Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108332704
D30848.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
36 KB
Referenced Files
None
Subscribers
None
D30848.diff
View Options
diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h
--- a/stand/common/bootstrap.h
+++ b/stand/common/bootstrap.h
@@ -29,6 +29,7 @@
#ifndef _BOOTSTRAP_H_
#define _BOOTSTRAP_H_
+#include <stand.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/linker_set.h>
@@ -400,6 +401,9 @@
const char *);
int nvstore_unset_var(void *, const char *);
+/* common code to set currdev variable. */
+extern int mount_currdev(struct env_var *, int, const void *);
+
#ifndef CTASSERT
#define CTASSERT(x) _Static_assert(x, "compile-time assertion failed")
#endif
diff --git a/stand/common/misc.c b/stand/common/misc.c
--- a/stand/common/misc.c
+++ b/stand/common/misc.c
@@ -179,3 +179,25 @@
if (devsw[i]->dv_cleanup != NULL)
(devsw[i]->dv_cleanup)();
}
+
+/*
+ * mount new rootfs and unmount old, set "currdev" environment variable.
+ */
+int mount_currdev(struct env_var *ev, int flags, const void *value)
+{
+ int rv;
+
+ /* mount new rootfs */
+ rv = mount(value, "/", 0, NULL);
+ if (rv == 0) {
+ /*
+ * Note we unmount any previously mounted fs only after
+ * successfully mounting the new because we do not want to
+ * end up with unmounted rootfs.
+ */
+ if (ev->ev_value != NULL)
+ unmount(ev->ev_value, 0);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ }
+ return (rv);
+}
diff --git a/stand/efi/boot1/zfs_module.c b/stand/efi/boot1/zfs_module.c
--- a/stand/efi/boot1/zfs_module.c
+++ b/stand/efi/boot1/zfs_module.c
@@ -160,7 +160,7 @@
return (EFI_NOT_FOUND);
}
- if ((err = zfs_mount(spa, 0, &zmount)) != 0) {
+ if ((err = zfs_mount_impl(spa, 0, &zmount)) != 0) {
DPRINTF("Failed to mount pool '%s' (%d)\n", spa->spa_name, err);
return (EFI_NOT_FOUND);
}
diff --git a/stand/efi/libefi/devicename.c b/stand/efi/libefi/devicename.c
--- a/stand/efi/libefi/devicename.c
+++ b/stand/efi/libefi/devicename.c
@@ -209,8 +209,7 @@
rv = efi_parsedev(&ncurr, value, NULL);
if (rv != 0)
return (rv);
-
free(ncurr);
- env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
- return (0);
+
+ return (mount_currdev(ev, flags, value));
}
diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c
--- a/stand/efi/loader/main.c
+++ b/stand/efi/loader/main.c
@@ -187,15 +187,12 @@
set_currdev(const char *devname)
{
+ env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev,
+ env_nounset);
/*
- * Don't execute hooks here; we may need to try setting these more than
- * once here if we're probing for the ZFS pool we're supposed to boot.
- * The currdev hook is intended to just validate user input anyways,
- * while the loaddev hook makes it immutable once we've determined what
- * the proper currdev is.
+ * Don't execute hook here; the loaddev hook makes it immutable
+ * once we've determined what the proper currdev is.
*/
- env_setenv("currdev", EV_VOLATILE | EV_NOHOOK, devname, efi_setcurrdev,
- env_nounset);
env_setenv("loaddev", EV_VOLATILE | EV_NOHOOK, devname, env_noset,
env_nounset);
}
@@ -958,6 +955,9 @@
#endif
cons_probe();
+ /* Set up currdev variable to have hooks in place. */
+ env_setenv("currdev", EV_VOLATILE, "", efi_setcurrdev, env_nounset);
+
/* Init the time source */
efi_time_init();
diff --git a/stand/i386/gptzfsboot/Makefile b/stand/i386/gptzfsboot/Makefile
--- a/stand/i386/gptzfsboot/Makefile
+++ b/stand/i386/gptzfsboot/Makefile
@@ -66,7 +66,7 @@
gptldr.out: gptldr.o
${LD} ${LD_FLAGS} -e start --defsym ORG=${ORG1} -T ${LDSCRIPT} -o ${.TARGET} gptldr.o
-OBJS= zfsboot.o sio.o cons.o bcache.o devopen.o disk.o part.o zfs_cmd.o
+OBJS= zfsboot.o sio.o cons.o bcache.o devopen.o disk.o part.o zfs_cmd.o misc.o
CLEANFILES+= gptzfsboot.bin gptzfsboot.out ${OBJS} ${OPENCRYPTO_XTS}
# i386 standalone support library
diff --git a/stand/i386/libi386/devicename.c b/stand/i386/libi386/devicename.c
--- a/stand/i386/libi386/devicename.c
+++ b/stand/i386/libi386/devicename.c
@@ -204,12 +204,12 @@
int
i386_setcurrdev(struct env_var *ev, int flags, const void *value)
{
- struct i386_devdesc *ncurr;
- int rv;
+ struct i386_devdesc *ncurr;
+ int rv;
- if ((rv = i386_parsedev(&ncurr, value, NULL)) != 0)
- return(rv);
- free(ncurr);
- env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
- return(0);
+ if ((rv = i386_parsedev(&ncurr, value, NULL)) != 0)
+ return (rv);
+ free(ncurr);
+
+ return (mount_currdev(ev, flags, value));
}
diff --git a/stand/i386/loader/main.c b/stand/i386/loader/main.c
--- a/stand/i386/loader/main.c
+++ b/stand/i386/loader/main.c
@@ -164,6 +164,10 @@
}
cons_probe();
+ /* Set up currdev variable to have hooks in place. */
+ env_setenv("currdev", EV_VOLATILE | EV_NOHOOK, "",
+ i386_setcurrdev, env_nounset);
+
/*
* Initialise the block cache. Set the upper limit.
*/
diff --git a/stand/i386/zfsboot/Makefile b/stand/i386/zfsboot/Makefile
--- a/stand/i386/zfsboot/Makefile
+++ b/stand/i386/zfsboot/Makefile
@@ -59,7 +59,7 @@
zfsldr.out: zfsldr.o
${LD} ${LD_FLAGS} -e start --defsym ORG=${ORG1} -T ${LDSCRIPT} -o ${.TARGET} zfsldr.o
-OBJS= zfsboot.o sio.o cons.o bcache.o devopen.o disk.o part.o zfs_cmd.o
+OBJS= zfsboot.o sio.o cons.o bcache.o devopen.o disk.o part.o zfs_cmd.o misc.o
CLEANFILES+= zfsboot2 zfsboot.ld zfsboot.ldr zfsboot.bin zfsboot.out \
${OBJS}
diff --git a/stand/i386/zfsboot/zfsboot.c b/stand/i386/zfsboot/zfsboot.c
--- a/stand/i386/zfsboot/zfsboot.c
+++ b/stand/i386/zfsboot/zfsboot.c
@@ -207,6 +207,10 @@
snprintf(boot_devname, sizeof (boot_devname), "disk%d:",
bd_bios2unit(bootinfo.bi_bios_dev));
+ /* Set up currdev variable to have hooks in place. */
+ env_setenv("currdev", EV_VOLATILE, "", i386_setcurrdev,
+ env_nounset);
+
for (i = 0; devsw[i] != NULL; i++)
if (devsw[i]->dv_init != NULL)
(devsw[i]->dv_init)();
diff --git a/stand/libofw/devicename.c b/stand/libofw/devicename.c
--- a/stand/libofw/devicename.c
+++ b/stand/libofw/devicename.c
@@ -134,13 +134,13 @@
int
ofw_setcurrdev(struct env_var *ev, int flags, const void *value)
{
- struct ofw_devdesc *ncurr;
- int rv;
+ struct ofw_devdesc *ncurr;
+ int rv;
- if ((rv = ofw_parsedev(&ncurr, value, NULL)) != 0)
- return rv;
+ if ((rv = ofw_parsedev(&ncurr, value, NULL)) != 0)
+ return (rv);
- free(ncurr);
- env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
- return 0;
+ free(ncurr);
+
+ return (mount_currdev(ev, flags, value));
}
diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile
--- a/stand/libsa/Makefile
+++ b/stand/libsa/Makefile
@@ -131,7 +131,7 @@
CLEANFILES+= ${SAFE_INCS} ${STAND_H_INC} ${OTHER_INC}
# io routines
-SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \
+SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c mount.c \
fstat.c close.c lseek.c open.c read.c write.c readdir.c
# SMBios routines
diff --git a/stand/libsa/cd9660.c b/stand/libsa/cd9660.c
--- a/stand/libsa/cd9660.c
+++ b/stand/libsa/cd9660.c
@@ -70,6 +70,8 @@
static off_t cd9660_seek(struct open_file *f, off_t offset, int where);
static int cd9660_stat(struct open_file *f, struct stat *sb);
static int cd9660_readdir(struct open_file *f, struct dirent *d);
+static int cd9660_mount(const char *, const char *, void **);
+static int cd9660_unmount(const char *, void *);
static int dirmatch(struct open_file *f, const char *path,
struct iso_directory_record *dp, int use_rrip, int lenskip);
static int rrip_check(struct open_file *f, struct iso_directory_record *dp,
@@ -81,16 +83,28 @@
int lenskip);
struct fs_ops cd9660_fsops = {
- "cd9660",
- cd9660_open,
- cd9660_close,
- cd9660_read,
- null_write,
- cd9660_seek,
- cd9660_stat,
- cd9660_readdir
+ .fs_name = "cd9660",
+ .fo_open = cd9660_open,
+ .fo_close = cd9660_close,
+ .fo_read = cd9660_read,
+ .fo_write = null_write,
+ .fo_seek = cd9660_seek,
+ .fo_stat = cd9660_stat,
+ .fo_readdir = cd9660_readdir,
+ .fo_mount = cd9660_mount,
+ .fo_unmount = cd9660_unmount
};
+typedef struct cd9660_mnt {
+ struct devdesc *cd_dev;
+ int cd_fd;
+ struct iso_directory_record cd_rec;
+ STAILQ_ENTRY(cd9660_mnt) cd_link;
+} cd9660_mnt_t;
+
+typedef STAILQ_HEAD(cd9660_mnt_list, cd9660_mnt) cd9660_mnt_list_t;
+static cd9660_mnt_list_t mnt_list = STAILQ_HEAD_INITIALIZER(mnt_list);
+
#define F_ISDIR 0x0001 /* Directory */
#define F_ROOTDIR 0x0002 /* Root directory */
#define F_RR 0x0004 /* Rock Ridge on this volume */
@@ -281,26 +295,23 @@
}
static int
-cd9660_open(const char *path, struct open_file *f)
+cd9660_read_dr(struct open_file *f, struct iso_directory_record *rec)
{
- struct file *fp = NULL;
- void *buf;
struct iso_primary_descriptor *vd;
- size_t read, dsize, off;
- daddr_t bno, boff;
- struct iso_directory_record rec;
- struct iso_directory_record *dp = NULL;
- int rc, first, use_rrip, lenskip;
- bool isdir = false;
+ size_t read;
+ daddr_t bno;
+ int rc;
- /* First find the volume descriptor */
- buf = malloc(MAX(ISO_DEFAULT_BLOCK_SIZE,
+ errno = 0;
+ vd = malloc(MAX(ISO_DEFAULT_BLOCK_SIZE,
sizeof(struct iso_primary_descriptor)));
- vd = buf;
+ if (vd == NULL)
+ return (errno);
+
for (bno = 16;; bno++) {
twiddle(1);
rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno),
- ISO_DEFAULT_BLOCK_SIZE, buf, &read);
+ ISO_DEFAULT_BLOCK_SIZE, (char *)vd, &read);
if (rc)
goto out;
if (read != ISO_DEFAULT_BLOCK_SIZE) {
@@ -308,18 +319,61 @@
goto out;
}
rc = EINVAL;
- if (bcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id) != 0)
+ if (bcmp(vd->id, ISO_STANDARD_ID, sizeof(vd->id)) != 0)
goto out;
if (isonum_711(vd->type) == ISO_VD_END)
goto out;
if (isonum_711(vd->type) == ISO_VD_PRIMARY)
break;
}
- if (isonum_723(vd->logical_block_size) != ISO_DEFAULT_BLOCK_SIZE)
+ if (isonum_723(vd->logical_block_size) == ISO_DEFAULT_BLOCK_SIZE) {
+ bcopy(vd->root_directory_record, rec, sizeof(*rec));
+ rc = 0;
+ }
+out:
+ free(vd);
+ return (rc);
+}
+
+static int
+cd9660_open(const char *path, struct open_file *f)
+{
+ struct file *fp = NULL;
+ void *buf;
+ size_t read, dsize, off;
+ daddr_t bno, boff;
+ struct iso_directory_record rec;
+ struct iso_directory_record *dp = NULL;
+ int rc, first, use_rrip, lenskip;
+ bool isdir = false;
+ struct devdesc *dev;
+ cd9660_mnt_t *mnt;
+
+ /* First find the volume descriptor */
+ errno = 0;
+ buf = malloc(MAX(ISO_DEFAULT_BLOCK_SIZE,
+ sizeof(struct iso_primary_descriptor)));
+ if (buf == NULL)
+ return (errno);
+
+ dev = f->f_devdata;
+ STAILQ_FOREACH(mnt, &mnt_list, cd_link) {
+ if (dev->d_dev->dv_type == mnt->cd_dev->d_dev->dv_type &&
+ dev->d_unit == mnt->cd_dev->d_unit)
+ break;
+ }
+
+ rc = 0;
+ if (mnt == NULL)
+ rc = cd9660_read_dr(f, &rec);
+ else
+ rec = mnt->cd_rec;
+
+ if (rc != 0)
goto out;
- bcopy(vd->root_directory_record, &rec, sizeof(rec));
- if (*path == '/') path++; /* eat leading '/' */
+ if (*path == '/')
+ path++; /* eat leading '/' */
first = 1;
use_rrip = 0;
@@ -621,3 +675,57 @@
sb->st_size = fp->f_size;
return 0;
}
+
+static int
+cd9660_mount(const char *dev, const char *path, void **data)
+{
+ cd9660_mnt_t *mnt;
+ struct open_file *f;
+ char *fs;
+
+ errno = 0;
+ mnt = calloc(1, sizeof(*mnt));
+ if (mnt == NULL)
+ return (errno);
+ mnt->cd_fd = -1;
+
+ if (asprintf(&fs, "%s%s", dev, path) < 0)
+ goto done;
+
+ mnt->cd_fd = open(fs, O_RDONLY);
+ free(fs);
+ if (mnt->cd_fd == -1)
+ goto done;
+
+ f = fd2open_file(mnt->cd_fd);
+ /* Is it cd9660 file system? */
+ if (strcmp(f->f_ops->fs_name, "cd9660") == 0) {
+ mnt->cd_dev = f->f_devdata;
+ errno = cd9660_read_dr(f, &mnt->cd_rec);
+ STAILQ_INSERT_TAIL(&mnt_list, mnt, cd_link);
+ } else {
+ errno = ENXIO;
+ }
+
+done:
+ if (errno != 0) {
+ free(mnt->cd_dev);
+ if (mnt->cd_fd >= 0)
+ close(mnt->cd_fd);
+ free(mnt);
+ } else {
+ *data = mnt;
+ }
+ return (errno);
+}
+
+static int
+cd9660_unmount(const char *dev __unused, void *data)
+{
+ cd9660_mnt_t *mnt = data;
+
+ STAILQ_REMOVE(&mnt_list, mnt, cd9660_mnt, cd_link);
+ close(mnt->cd_fd);
+ free(mnt);
+ return (0);
+}
diff --git a/stand/libsa/dosfs.c b/stand/libsa/dosfs.c
--- a/stand/libsa/dosfs.c
+++ b/stand/libsa/dosfs.c
@@ -38,9 +38,19 @@
#include <stddef.h>
#include "stand.h"
+#include "disk.h"
#include "dosfs.h"
+typedef struct dos_mnt {
+ char *dos_dev;
+ DOS_FS *dos_fs;
+ int dos_fd;
+ STAILQ_ENTRY(dos_mnt) dos_link;
+} dos_mnt_t;
+
+typedef STAILQ_HEAD(dos_mnt_list, dos_mnt) dos_mnt_list_t;
+static dos_mnt_list_t mnt_list = STAILQ_HEAD_INITIALIZER(mnt_list);
static int dos_open(const char *path, struct open_file *fd);
static int dos_close(struct open_file *fd);
@@ -48,16 +58,20 @@
static off_t dos_seek(struct open_file *fd, off_t offset, int whence);
static int dos_stat(struct open_file *fd, struct stat *sb);
static int dos_readdir(struct open_file *fd, struct dirent *d);
+static int dos_mount(const char *dev, const char *path, void **data);
+static int dos_unmount(const char *dev, void *data);
struct fs_ops dosfs_fsops = {
- "dosfs",
- dos_open,
- dos_close,
- dos_read,
- null_write,
- dos_seek,
- dos_stat,
- dos_readdir
+ .fs_name = "dosfs",
+ .fo_open = dos_open,
+ .fo_close = dos_close,
+ .fo_read = dos_read,
+ .fo_write = null_write,
+ .fo_seek = dos_seek,
+ .fo_stat = dos_stat,
+ .fo_readdir = dos_readdir,
+ .fo_mount = dos_mount,
+ .fo_unmount = dos_unmount
};
#define SECSIZ 512 /* sector size */
@@ -179,12 +193,11 @@
* Mount DOS filesystem
*/
static int
-dos_mount(DOS_FS *fs, struct open_file *fd)
+dos_mount_impl(DOS_FS *fs, struct open_file *fd)
{
int err;
u_char *buf;
- bzero(fs, sizeof(DOS_FS));
fs->fd = fd;
if ((buf = malloc(secbyt(1))) == NULL)
@@ -215,11 +228,70 @@
return (0);
}
+static int
+dos_mount(const char *dev, const char *path, void **data)
+{
+ char *fs;
+ dos_mnt_t *mnt;
+ struct open_file *f;
+ DOS_FILE *df;
+
+ errno = 0;
+ mnt = calloc(1, sizeof(*mnt));
+ if (mnt == NULL)
+ return (errno);
+ mnt->dos_fd = -1;
+ mnt->dos_dev = strdup(dev);
+ if (mnt->dos_dev == NULL)
+ goto done;
+
+ if (asprintf(&fs, "%s%s", dev, path) < 0)
+ goto done;
+
+ mnt->dos_fd = open(fs, O_RDONLY);
+ free(fs);
+ if (mnt->dos_fd == -1)
+ goto done;
+
+ f = fd2open_file(mnt->dos_fd);
+ if (strcmp(f->f_ops->fs_name, "dosfs") == 0) {
+ df = f->f_fsdata;
+ mnt->dos_fs = df->fs;
+ STAILQ_INSERT_TAIL(&mnt_list, mnt, dos_link);
+ } else {
+ errno = ENXIO;
+ }
+
+done:
+ if (errno != 0) {
+ free(mnt->dos_dev);
+ if (mnt->dos_fd >= 0)
+ close(mnt->dos_fd);
+ free(mnt);
+ } else {
+ *data = mnt;
+ }
+
+ return (errno);
+}
+
+static int
+dos_unmount(const char *dev __unused, void *data)
+{
+ dos_mnt_t *mnt = data;
+
+ STAILQ_REMOVE(&mnt_list, mnt, dos_mnt, dos_link);
+ free(mnt->dos_dev);
+ close(mnt->dos_fd);
+ free(mnt);
+ return (0);
+}
+
/*
* Unmount mounted filesystem
*/
static int
-dos_unmount(DOS_FS *fs)
+dos_unmount_impl(DOS_FS *fs)
{
if (fs->links)
return (EBUSY);
@@ -237,19 +309,32 @@
DOS_DE *de;
DOS_FILE *f;
DOS_FS *fs;
+ dos_mnt_t *mnt;
+ const char *dev;
u_int size, clus;
int err;
- /* Allocate mount structure, associate with open */
- if ((fs = malloc(sizeof(DOS_FS))) == NULL)
- return (errno);
- if ((err = dos_mount(fs, fd))) {
- free(fs);
- return (err);
+ dev = disk_fmtdev(fd->f_devdata);
+ STAILQ_FOREACH(mnt, &mnt_list, dos_link) {
+ if (strcmp(dev, mnt->dos_dev) == 0)
+ break;
+ }
+
+ if (mnt == NULL) {
+ /* Allocate mount structure, associate with open */
+ if ((fs = malloc(sizeof(DOS_FS))) == NULL)
+ return (errno);
+ if ((err = dos_mount_impl(fs, fd))) {
+ free(fs);
+ return (err);
+ }
+ } else {
+ fs = mnt->dos_fs;
}
if ((err = namede(fs, path, &de))) {
- dos_unmount(fs);
+ if (mnt == NULL)
+ dos_unmount_impl(fs);
return (err);
}
@@ -259,19 +344,20 @@
if ((!(de->attr & FA_DIR) && (!clus != !size)) ||
((de->attr & FA_DIR) && size) ||
(clus && !okclus(fs, clus))) {
- dos_unmount(fs);
+ if (mnt == NULL)
+ dos_unmount_impl(fs);
return (EINVAL);
}
- if ((f = malloc(sizeof(DOS_FILE))) == NULL) {
+ if ((f = calloc(1, sizeof(DOS_FILE))) == NULL) {
err = errno;
- dos_unmount(fs);
+ if (mnt == NULL)
+ dos_unmount_impl(fs);
return (err);
}
- bzero(f, sizeof(DOS_FILE));
f->fs = fs;
fs->links++;
f->de = *de;
- fd->f_fsdata = (void *)f;
+ fd->f_fsdata = f;
return (0);
}
@@ -381,7 +467,7 @@
f->fs->links--;
free(f);
- dos_unmount(fs);
+ dos_unmount_impl(fs);
return (0);
}
diff --git a/stand/libsa/mount.c b/stand/libsa/mount.c
new file mode 100644
--- /dev/null
+++ b/stand/libsa/mount.c
@@ -0,0 +1,163 @@
+/*-
+ * Copyright 2021 Toomas Soome <tsoome@me.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/queue.h>
+
+/*
+ * While setting "currdev" environment variable, alse "mount" the
+ * new root file system. This is done to hold disk device open
+ * in between file accesses, and thus preserve block cache for
+ * this device. Additionally, this allows us to optimize filesystem
+ * access by sharing filesystem metadata (like superblock).
+ */
+
+typedef STAILQ_HEAD(mnt_info_list, mnt_info) mnt_info_list_t;
+
+typedef struct mnt_info {
+ STAILQ_ENTRY(mnt_info) mnt_link; /* link in mount list */
+ const struct fs_ops *mnt_fs;
+ char *mnt_dev;
+ char *mnt_path;
+ unsigned mnt_refcount;
+ void *mnt_data; /* Private state */
+} mnt_info_t;
+
+/* list of mounted filesystems. */
+static mnt_info_list_t mnt_list = STAILQ_HEAD_INITIALIZER(mnt_list);
+
+static void
+free_mnt(mnt_info_t *mnt)
+{
+ free(mnt->mnt_dev);
+ free(mnt->mnt_path);
+ free(mnt);
+}
+
+static int
+add_mnt_info(struct fs_ops *fs, const char *dev, const char *path, void *data)
+{
+ mnt_info_t *mnt;
+
+ mnt = malloc(sizeof(*mnt));
+ if (mnt == NULL)
+ return (ENOMEM);
+
+ mnt->mnt_fs = fs;
+ mnt->mnt_dev = strdup(dev);
+ mnt->mnt_path = strdup(path);
+ mnt->mnt_data = data;
+ mnt->mnt_refcount = 1;
+
+ if (mnt->mnt_dev == NULL || mnt->mnt_path == NULL) {
+ free_mnt(mnt);
+ return (ENOMEM);
+ }
+ STAILQ_INSERT_TAIL(&mnt_list, mnt, mnt_link);
+ return (0);
+}
+
+static void
+delete_mnt_info(mnt_info_t *mnt)
+{
+ STAILQ_REMOVE(&mnt_list, mnt, mnt_info, mnt_link);
+ free_mnt(mnt);
+}
+
+int
+mount(const char *dev, const char *path, int flags __unused, void *data)
+{
+ mnt_info_t *mnt;
+ int rc = -1;
+
+ /* Is it already mounted? */
+ STAILQ_FOREACH(mnt, &mnt_list, mnt_link) {
+ if (strcmp(dev, mnt->mnt_dev) == 0 &&
+ strcmp(path, mnt->mnt_path) == 0) {
+ mnt->mnt_refcount++;
+ return (0);
+ }
+ }
+
+ for (int i = 0; file_system[i] != NULL; i++) {
+ struct fs_ops *fs;
+
+ fs = file_system[i];
+ if (fs->fo_mount == NULL)
+ continue;
+
+ if (fs->fo_mount(dev, path, &data) != 0)
+ continue;
+
+ rc = add_mnt_info(fs, dev, path, data);
+ if (rc != 0 && mnt->mnt_fs->fo_unmount != NULL) {
+ printf("failed to mount %s: %s\n", dev,
+ strerror(rc));
+ (void)mnt->mnt_fs->fo_unmount(dev, data);
+ }
+ break;
+ }
+
+
+ /*
+ * if rc is -1, it means we have no file system with fo_mount()
+ * callback, or all fo_mount() calls failed. As long as we
+ * have missing fo_mount() callbacks, we allow mount() to return 0.
+ */
+ if (rc == -1)
+ rc = 0;
+
+ return (rc);
+}
+
+int
+unmount(const char *dev, int flags __unused)
+{
+ mnt_info_t *mnt;
+ int rv;
+
+ rv = 0;
+ STAILQ_FOREACH(mnt, &mnt_list, mnt_link) {
+ if (strcmp(dev, mnt->mnt_dev) == 0) {
+ if (mnt->mnt_refcount > 1) {
+ mnt->mnt_refcount--;
+ break;
+ }
+
+ if (mnt->mnt_fs->fo_unmount != NULL)
+ rv = mnt->mnt_fs->fo_unmount(dev,
+ mnt->mnt_data);
+ delete_mnt_info(mnt);
+ break;
+ }
+ }
+
+ if (rv != 0)
+ printf("failed to unmount %s: %d\n", dev, rv);
+ return (0);
+}
diff --git a/stand/libsa/netif.c b/stand/libsa/netif.c
--- a/stand/libsa/netif.c
+++ b/stand/libsa/netif.c
@@ -37,7 +37,6 @@
#include <sys/param.h>
#include <sys/types.h>
#include <sys/cdefs.h>
-#include <sys/mount.h>
#include <string.h>
#include <netinet/in.h>
diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h
--- a/stand/libsa/stand.h
+++ b/stand/libsa/stand.h
@@ -111,6 +111,8 @@
off_t (*fo_seek)(struct open_file *f, off_t offset, int where);
int (*fo_stat)(struct open_file *f, struct stat *sb);
int (*fo_readdir)(struct open_file *f, struct dirent *d);
+ int (*fo_mount)(const char *, const char *, void **);
+ int (*fo_unmount)(const char *, void *);
};
/*
@@ -283,6 +285,8 @@
#define gets(x) ngets((x), 0)
extern int fgetstr(char *buf, int size, int fd);
+extern int mount(const char *dev, const char *path, int flags, void *data);
+extern int unmount(const char *dev, int flags);
extern int open(const char *, int);
#define O_RDONLY 0x0
#define O_WRONLY 0x1
diff --git a/stand/libsa/ufs.c b/stand/libsa/ufs.c
--- a/stand/libsa/ufs.c
+++ b/stand/libsa/ufs.c
@@ -81,6 +81,7 @@
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
#include "stand.h"
+#include "disk.h"
#include "string.h"
static int ufs_open(const char *path, struct open_file *f);
@@ -91,16 +92,20 @@
static off_t ufs_seek(struct open_file *f, off_t offset, int where);
static int ufs_stat(struct open_file *f, struct stat *sb);
static int ufs_readdir(struct open_file *f, struct dirent *d);
+static int ufs_mount(const char *dev, const char *path, void **data);
+static int ufs_unmount(const char *dev, void *data);
struct fs_ops ufs_fsops = {
- "ufs",
- ufs_open,
- ufs_close,
- ufs_read,
- ufs_write,
- ufs_seek,
- ufs_stat,
- ufs_readdir
+ .fs_name = "ufs",
+ .fo_open = ufs_open,
+ .fo_close = ufs_close,
+ .fo_read = ufs_read,
+ .fo_write = ufs_write,
+ .fo_seek = ufs_seek,
+ .fo_stat = ufs_stat,
+ .fo_readdir = ufs_readdir,
+ .fo_mount = ufs_mount,
+ .fo_unmount = ufs_unmount
};
/*
@@ -130,6 +135,15 @@
((fp)->f_fs->fs_magic == FS_UFS1_MAGIC ? \
(fp)->f_di.di1.field : (fp)->f_di.di2.field)
+typedef struct ufs_mnt {
+ char *um_dev;
+ int um_fd;
+ STAILQ_ENTRY(ufs_mnt) um_link;
+} ufs_mnt_t;
+
+typedef STAILQ_HEAD(ufs_mnt_list, ufs_mnt) ufs_mnt_list_t;
+static ufs_mnt_list_t mnt_list = STAILQ_HEAD_INITIALIZER(mnt_list);
+
static int read_inode(ino_t, struct open_file *);
static int block_map(struct open_file *, ufs2_daddr_t, ufs2_daddr_t *);
static int buf_read_file(struct open_file *, char **, size_t *);
@@ -150,9 +164,7 @@
* Read a new inode into a file structure.
*/
static int
-read_inode(inumber, f)
- ino_t inumber;
- struct open_file *f;
+read_inode(ino_t inumber, struct open_file *f)
{
struct file *fp = (struct file *)f->f_fsdata;
struct fs *fs = fp->f_fs;
@@ -207,10 +219,8 @@
* contains that block.
*/
static int
-block_map(f, file_block, disk_block_p)
- struct open_file *f;
- ufs2_daddr_t file_block;
- ufs2_daddr_t *disk_block_p; /* out */
+block_map(struct open_file *f, ufs2_daddr_t file_block,
+ ufs2_daddr_t *disk_block_p)
{
struct file *fp = (struct file *)f->f_fsdata;
struct fs *fs = fp->f_fs;
@@ -312,10 +322,7 @@
* Write a portion of a file from an internal buffer.
*/
static int
-buf_write_file(f, buf_p, size_p)
- struct open_file *f;
- const char *buf_p;
- size_t *size_p; /* out */
+buf_write_file(struct open_file *f, const char *buf_p, size_t *size_p)
{
struct file *fp = (struct file *)f->f_fsdata;
struct fs *fs = fp->f_fs;
@@ -390,10 +397,7 @@
* the location in the buffer and the amount in the buffer.
*/
static int
-buf_read_file(f, buf_p, size_p)
- struct open_file *f;
- char **buf_p; /* out */
- size_t *size_p; /* out */
+buf_read_file(struct open_file *f, char **buf_p, size_t *size_p)
{
struct file *fp = (struct file *)f->f_fsdata;
struct fs *fs = fp->f_fs;
@@ -452,10 +456,7 @@
* i_number.
*/
static int
-search_directory(name, f, inumber_p)
- char *name;
- struct open_file *f;
- ino_t *inumber_p; /* out */
+search_directory(char *name, struct open_file *f, ino_t *inumber_p)
{
struct file *fp = (struct file *)f->f_fsdata;
struct direct *dp;
@@ -502,9 +503,7 @@
* Open a file.
*/
static int
-ufs_open(upath, f)
- const char *upath;
- struct open_file *f;
+ufs_open(const char *upath, struct open_file *f)
{
char *cp, *ncp;
int c;
@@ -516,18 +515,41 @@
char namebuf[MAXPATHLEN+1];
char *buf = NULL;
char *path = NULL;
+ const char *dev;
+ ufs_mnt_t *mnt;
/* allocate file system specific data structure */
- fp = malloc(sizeof(struct file));
- bzero(fp, sizeof(struct file));
+ errno = 0;
+ fp = calloc(1, sizeof(struct file));
+ if (fp == NULL)
+ return (errno);
f->f_fsdata = (void *)fp;
- /* read super block */
- twiddle(1);
- if ((rc = ffs_sbget(f, &fs, STDSB_NOHASHFAIL, "stand",
- ufs_use_sa_read)) != 0)
- goto out;
+ dev = disk_fmtdev(f->f_devdata);
+ /* Is this device mounted? */
+ STAILQ_FOREACH(mnt, &mnt_list, um_link) {
+ if (strcmp(dev, mnt->um_dev) == 0)
+ break;
+ }
+
+ if (mnt == NULL) {
+ /* read super block */
+ twiddle(1);
+ if ((rc = ffs_sbget(f, &fs, STDSB_NOHASHFAIL, "stand",
+ ufs_use_sa_read)) != 0) {
+ goto out;
+ }
+ } else {
+ struct open_file *sbf;
+ struct file *sfp;
+
+ /* get superblock from mounted file system */
+ sbf = fd2open_file(mnt->um_fd);
+ sfp = sbf->f_fsdata;
+ fs = sfp->f_fs;
+ }
fp->f_fs = fs;
+
/*
* Calculate indirect block levels.
*/
@@ -671,14 +693,12 @@
rc = 0;
fp->f_seekp = 0;
out:
- if (buf)
- free(buf);
- if (path)
- free(path);
+ free(buf);
+ free(path);
if (rc) {
- if (fp->f_buf)
- free(fp->f_buf);
- if (fp->f_fs != NULL) {
+ free(fp->f_buf);
+
+ if (mnt == NULL && fp->f_fs != NULL) {
free(fp->f_fs->fs_csp);
free(fp->f_fs->fs_si);
free(fp->f_fs);
@@ -711,27 +731,34 @@
}
static int
-ufs_close(f)
- struct open_file *f;
+ufs_close(struct open_file *f)
{
+ ufs_mnt_t *mnt;
struct file *fp = (struct file *)f->f_fsdata;
int level;
+ char *dev;
- f->f_fsdata = (void *)0;
- if (fp == (struct file *)0)
+ f->f_fsdata = NULL;
+ if (fp == NULL)
return (0);
for (level = 0; level < UFS_NIADDR; level++) {
- if (fp->f_blk[level])
- free(fp->f_blk[level]);
+ free(fp->f_blk[level]);
}
- if (fp->f_buf)
- free(fp->f_buf);
- if (fp->f_fs != NULL) {
+ free(fp->f_buf);
+
+ dev = disk_fmtdev(f->f_devdata);
+ STAILQ_FOREACH(mnt, &mnt_list, um_link) {
+ if (strcmp(dev, mnt->um_dev) == 0)
+ break;
+ }
+
+ if (mnt == NULL && fp->f_fs != NULL) {
free(fp->f_fs->fs_csp);
free(fp->f_fs->fs_si);
free(fp->f_fs);
}
+
free(fp);
return (0);
}
@@ -741,11 +768,7 @@
* Cross block boundaries when necessary.
*/
static int
-ufs_read(f, start, size, resid)
- struct open_file *f;
- void *start;
- size_t size;
- size_t *resid; /* out */
+ufs_read(struct open_file *f, void *start, size_t size, size_t *resid)
{
struct file *fp = (struct file *)f->f_fsdata;
size_t csize;
@@ -783,11 +806,7 @@
* extend the file.
*/
static int
-ufs_write(f, start, size, resid)
- struct open_file *f;
- const void *start;
- size_t size;
- size_t *resid; /* out */
+ufs_write(struct open_file *f, const void *start, size_t size, size_t *resid)
{
struct file *fp = (struct file *)f->f_fsdata;
size_t csize;
@@ -815,10 +834,7 @@
}
static off_t
-ufs_seek(f, offset, where)
- struct open_file *f;
- off_t offset;
- int where;
+ufs_seek(struct open_file *f, off_t offset, int where)
{
struct file *fp = (struct file *)f->f_fsdata;
@@ -840,9 +856,7 @@
}
static int
-ufs_stat(f, sb)
- struct open_file *f;
- struct stat *sb;
+ufs_stat(struct open_file *f, struct stat *sb)
{
struct file *fp = (struct file *)f->f_fsdata;
@@ -894,3 +908,59 @@
strcpy(d->d_name, dp->d_name);
return (0);
}
+
+static int
+ufs_mount(const char *dev, const char *path, void **data)
+{
+ char *fs;
+ ufs_mnt_t *mnt;
+ struct open_file *f;
+
+ errno = 0;
+ mnt = calloc(1, sizeof(*mnt));
+ if (mnt == NULL)
+ return (errno);
+ mnt->um_fd = -1;
+ mnt->um_dev = strdup(dev);
+ if (mnt->um_dev == NULL)
+ goto done;
+
+ if (asprintf(&fs, "%s%s", dev, path) < 0)
+ goto done;
+
+ mnt->um_fd = open(fs, O_RDONLY);
+ free(fs);
+ if (mnt->um_fd == -1)
+ goto done;
+
+ /* Is it ufs file system? */
+ f = fd2open_file(mnt->um_fd);
+ if (strcmp(f->f_ops->fs_name, "ufs") == 0)
+ STAILQ_INSERT_TAIL(&mnt_list, mnt, um_link);
+ else
+ errno = ENXIO;
+
+done:
+ if (errno != 0) {
+ free(mnt->um_dev);
+ if (mnt->um_fd >= 0)
+ close(mnt->um_fd);
+ free(mnt);
+ } else {
+ *data = mnt;
+ }
+
+ return (errno);
+}
+
+static int
+ufs_unmount(const char *dev __unused, void *data)
+{
+ ufs_mnt_t *mnt = data;
+
+ STAILQ_REMOVE(&mnt_list, mnt, ufs_mnt, um_link);
+ free(mnt->um_dev);
+ close(mnt->um_fd);
+ free(mnt);
+ return (0);
+}
diff --git a/stand/libsa/zfs/zfs.c b/stand/libsa/zfs/zfs.c
--- a/stand/libsa/zfs/zfs.c
+++ b/stand/libsa/zfs/zfs.c
@@ -58,6 +58,8 @@
static off_t zfs_seek(struct open_file *f, off_t offset, int where);
static int zfs_stat(struct open_file *f, struct stat *sb);
static int zfs_readdir(struct open_file *f, struct dirent *d);
+static int zfs_mount(const char *dev, const char *path, void **data);
+static int zfs_unmount(const char *dev, void *data);
static void zfs_bootenv_initial(const char *envname, spa_t *spa,
const char *name, const char *dsname, int checkpoint);
@@ -67,14 +69,16 @@
struct devsw zfs_dev;
struct fs_ops zfs_fsops = {
- "zfs",
- zfs_open,
- zfs_close,
- zfs_read,
- null_write,
- zfs_seek,
- zfs_stat,
- zfs_readdir
+ .fs_name = "zfs",
+ .fo_open = zfs_open,
+ .fo_close = zfs_close,
+ .fo_read = zfs_read,
+ .fo_write = null_write,
+ .fo_seek = zfs_seek,
+ .fo_stat = zfs_stat,
+ .fo_readdir = zfs_readdir,
+ .fo_mount = zfs_mount,
+ .fo_unmount = zfs_unmount
};
/*
@@ -362,6 +366,74 @@
}
}
+/*
+ * if path is NULL, create mount structure, but do not add it to list.
+ */
+static int
+zfs_mount(const char *dev, const char *path, void **data)
+{
+ struct zfs_devdesc *zfsdev;
+ spa_t *spa;
+ struct zfsmount *mnt;
+ int rv;
+
+ errno = 0;
+ zfsdev = malloc(sizeof(*zfsdev));
+ if (zfsdev == NULL)
+ return (errno);
+
+ rv = zfs_parsedev(zfsdev, dev + 3, NULL);
+ if (rv != 0) {
+ free(zfsdev);
+ return (rv);
+ }
+
+ spa = spa_find_by_dev(zfsdev);
+ if (spa == NULL)
+ return (ENXIO);
+
+ mnt = calloc(1, sizeof(*mnt));
+ if (mnt != NULL && path != NULL)
+ mnt->path = strdup(path);
+ rv = errno;
+
+ if (mnt != NULL)
+ rv = zfs_mount_impl(spa, zfsdev->root_guid, mnt);
+ free(zfsdev);
+
+ if (rv == 0 && mnt != NULL && mnt->objset.os_type != DMU_OST_ZFS) {
+ printf("Unexpected object set type %ju\n",
+ (uintmax_t)mnt->objset.os_type);
+ rv = EIO;
+ }
+
+ if (rv != 0) {
+ if (mnt != NULL)
+ free(mnt->path);
+ free(mnt);
+ return (rv);
+ }
+
+ if (mnt != NULL) {
+ *data = mnt;
+ if (path != NULL)
+ STAILQ_INSERT_TAIL(&zfsmount, mnt, next);
+ }
+
+ return (rv);
+}
+
+static int
+zfs_unmount(const char *dev, void *data)
+{
+ struct zfsmount *mnt = data;
+
+ STAILQ_REMOVE(&zfsmount, mnt, zfsmount, next);
+ free(mnt->path);
+ free(mnt);
+ return (0);
+}
+
static int
vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t bytes)
{
@@ -1503,32 +1575,45 @@
if ((spa = spa_find_by_dev(dev)) == NULL)
return (ENXIO);
- mount = malloc(sizeof(*mount));
- if (mount == NULL)
- rv = ENOMEM;
- else
- rv = zfs_mount(spa, dev->root_guid, mount);
- if (rv != 0) {
- free(mount);
- return (rv);
+ STAILQ_FOREACH(mount, &zfsmount, next) {
+ if (spa->spa_guid == mount->spa->spa_guid)
+ break;
}
- if (mount->objset.os_type != DMU_OST_ZFS) {
- printf("Unexpected object set type %ju\n",
- (uintmax_t)mount->objset.os_type);
- free(mount);
- return (EIO);
+
+ rv = 0;
+ /* This device is not set as currdev, mount us private copy. */
+ if (mount == NULL)
+ rv = zfs_mount(zfs_fmtdev(dev), NULL, (void **)&mount);
+
+ if (rv == 0) {
+ f->f_devdata = mount;
+ free(dev);
}
- f->f_devdata = mount;
- free(dev);
- return (0);
+ return (rv);
}
static int
zfs_dev_close(struct open_file *f)
{
+ struct zfsmount *mnt, *mount;
+
+ mnt = f->f_devdata;
+
+ STAILQ_FOREACH(mount, &zfsmount, next) {
+ if (mnt->spa->spa_guid == mount->spa->spa_guid)
+ break;
+ }
+
+ /*
+ * devclose() will free f->f_devdata, but since we do have
+ * pointer to zfsmount structure in f->f_devdata, and
+ * zfs_unmount() will also free the zfsmount structure,
+ * we will get double free. To prevent double free,
+ * we must set f_devdata to NULL there.
+ */
+ if (mount != NULL)
+ f->f_devdata = NULL;
- free(f->f_devdata);
- f->f_devdata = NULL;
return (0);
}
diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c
--- a/stand/libsa/zfs/zfsimpl.c
+++ b/stand/libsa/zfs/zfsimpl.c
@@ -47,11 +47,15 @@
#endif
struct zfsmount {
- const spa_t *spa;
- objset_phys_t objset;
- uint64_t rootobj;
+ char *path;
+ const spa_t *spa;
+ objset_phys_t objset;
+ uint64_t rootobj;
+ STAILQ_ENTRY(zfsmount) next;
};
-static struct zfsmount zfsmount __unused;
+
+typedef STAILQ_HEAD(zfs_mnt_list, zfsmount) zfs_mnt_list_t;
+static zfs_mnt_list_t zfsmount = STAILQ_HEAD_INITIALIZER(zfsmount);
/*
* The indirect_child_t represents the vdev that we will read from, when we
@@ -3321,7 +3325,7 @@
}
static int
-zfs_mount(const spa_t *spa, uint64_t rootobj, struct zfsmount *mount)
+zfs_mount_impl(const spa_t *spa, uint64_t rootobj, struct zfsmount *mount)
{
mount->spa = spa;
diff --git a/stand/mips/beri/loader/devicename.c b/stand/mips/beri/loader/devicename.c
--- a/stand/mips/beri/loader/devicename.c
+++ b/stand/mips/beri/loader/devicename.c
@@ -195,12 +195,12 @@
int
beri_arch_setcurrdev(struct env_var *ev, int flags, const void *value)
{
- struct disk_devdesc *ncurr;
- int rv;
+ struct disk_devdesc *ncurr;
+ int rv;
- if ((rv = beri_arch_parsedev(&ncurr, value, NULL)) != 0)
- return(rv);
- free(ncurr);
- env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
- return(0);
+ if ((rv = beri_arch_parsedev(&ncurr, value, NULL)) != 0)
+ return (rv);
+ free(ncurr);
+
+ return (mount_currdev(ev, flags, value));
}
diff --git a/stand/powerpc/kboot/main.c b/stand/powerpc/kboot/main.c
--- a/stand/powerpc/kboot/main.c
+++ b/stand/powerpc/kboot/main.c
@@ -45,7 +45,6 @@
ssize_t kboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len);
int kboot_autoload(void);
uint64_t kboot_loadaddr(u_int type, void *data, uint64_t addr);
-int kboot_setcurrdev(struct env_var *ev, int flags, const void *value);
static void kboot_kseg_get(int *nseg, void **ptr);
extern int command_fdt_internal(int argc, char *argv[]);
diff --git a/stand/powerpc/ofw/main.c b/stand/powerpc/ofw/main.c
--- a/stand/powerpc/ofw/main.c
+++ b/stand/powerpc/ofw/main.c
@@ -137,6 +137,9 @@
*/
cons_probe();
+ /* Set up currdev variable to have hooks in place. */
+ env_setenv("currdev", EV_VOLATILE, "", ofw_setcurrdev, env_nounset);
+
/*
* March through the device switch probing for things.
*/
diff --git a/stand/uboot/common/main.c b/stand/uboot/common/main.c
--- a/stand/uboot/common/main.c
+++ b/stand/uboot/common/main.c
@@ -475,6 +475,9 @@
meminfo();
+ /* Set up currdev variable to have hooks in place. */
+ env_setenv("currdev", EV_VOLATILE, "", uboot_setcurrdev, env_nounset);
+
/*
* Enumerate U-Boot devices
*/
diff --git a/stand/uboot/lib/devicename.c b/stand/uboot/lib/devicename.c
--- a/stand/uboot/lib/devicename.c
+++ b/stand/uboot/lib/devicename.c
@@ -195,6 +195,6 @@
if ((rv = uboot_parsedev(&ncurr, value, NULL)) != 0)
return (rv);
free(ncurr);
- env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
- return (0);
+
+ return (mount_currdev(ev, flags, value));
}
diff --git a/stand/userboot/userboot/devicename.c b/stand/userboot/userboot/devicename.c
--- a/stand/userboot/userboot/devicename.c
+++ b/stand/userboot/userboot/devicename.c
@@ -222,6 +222,6 @@
if ((rv = userboot_parsedev(&ncurr, value, NULL)) != 0)
return (rv);
free(ncurr);
- env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
- return (0);
+
+ return (mount_currdev(ev, flags, value));
}
diff --git a/stand/userboot/userboot/main.c b/stand/userboot/userboot/main.c
--- a/stand/userboot/userboot/main.c
+++ b/stand/userboot/userboot/main.c
@@ -159,6 +159,10 @@
*/
cons_probe();
+ /* Set up currdev variable to have hooks in place. */
+ env_setenv("currdev", EV_VOLATILE, "",
+ userboot_setcurrdev, env_nounset);
+
printf("\n%s", bootprog_info);
#if 0
printf("Memory: %ld k\n", memsize() / 1024);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 24, 10:53 PM (45 m, 15 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16108007
Default Alt Text
D30848.diff (36 KB)
Attached To
Mode
D30848: loader: implement mount/unmount rootfs
Attached
Detach File
Event Timeline
Log In to Comment