Index: lib/libbe/be.c =================================================================== --- lib/libbe/be.c +++ lib/libbe/be.c @@ -29,11 +29,12 @@ #include __FBSDID("$FreeBSD$"); +#include +#include #include -#include +#include #include -#include #include #include #include @@ -55,23 +56,16 @@ * zfs_be_root set by loader(8). data is expected to be a libbe_handle_t *. */ static int -be_locate_rootfs(zfs_handle_t *chkds, void *data) +be_locate_rootfs(libbe_handle_t *lbh) { - libbe_handle_t *lbh; - char *mntpoint; - - lbh = (libbe_handle_t *)data; - if (lbh == NULL) - return (1); + zfs_handle_t *zfs; - mntpoint = NULL; - if (zfs_is_mounted(chkds, &mntpoint) && strcmp(mntpoint, "/") == 0) { - strlcpy(lbh->rootfs, zfs_get_name(chkds), sizeof(lbh->rootfs)); - free(mntpoint); + zfs = zfs_path_to_zhandle(lbh->lzh, "/", ZFS_TYPE_FILESYSTEM); + if (zfs == NULL) return (1); - } else if(mntpoint != NULL) - free(mntpoint); + strlcpy(lbh->rootfs, zfs_get_name(zfs), sizeof(lbh->rootfs)); + zfs_close(zfs); return (0); } @@ -82,33 +76,12 @@ libbe_handle_t * libbe_init(void) { - struct stat sb; - dev_t root_dev, boot_dev; libbe_handle_t *lbh; - zfs_handle_t *rootds; char *poolname, *pos; int pnamelen; lbh = NULL; poolname = pos = NULL; - rootds = NULL; - - /* Verify that /boot and / are mounted on the same filesystem */ - /* TODO: use errno here?? */ - if (stat("/", &sb) != 0) - goto err; - - root_dev = sb.st_dev; - - if (stat("/boot", &sb) != 0) - goto err; - - boot_dev = sb.st_dev; - - if (root_dev != boot_dev) { - fprintf(stderr, "/ and /boot not on same device, quitting\n"); - goto err; - } if ((lbh = calloc(1, sizeof(libbe_handle_t))) == NULL) goto err; @@ -116,15 +89,16 @@ if ((lbh->lzh = libzfs_init()) == NULL) goto err; - /* Obtain path to boot environment root */ - if ((kenv(KENV_GET, "zfs_be_root", lbh->root, - sizeof(lbh->root))) == -1) + /* Grab rootfs, we'll work backwards from there */ + if (be_locate_rootfs(lbh) != 0) goto err; - /* Remove leading 'zfs:' if present, otherwise use value as-is */ - if (strcmp(lbh->root, "zfs:") == 0) - strlcpy(lbh->root, strchr(lbh->root, ':') + sizeof(char), - sizeof(lbh->root)); + /* Strip off the final slash from the rootfs to get the be root */ + strlcpy(lbh->root, lbh->rootfs, sizeof(lbh->root)); + pos = strrchr(lbh->root, '/'); + if (pos == NULL) + goto err; + *pos = '\0'; if ((pos = strchr(lbh->root, '/')) == NULL) goto err; @@ -144,17 +118,6 @@ sizeof(lbh->bootfs), NULL, true) != 0) goto err; - /* Obtain path to boot environment rootfs (currently booted) */ - /* XXX Get dataset mounted at / by kenv/GUID from mountroot? */ - if ((rootds = zfs_open(lbh->lzh, lbh->root, ZFS_TYPE_DATASET)) == NULL) - goto err; - - zfs_iter_filesystems(rootds, be_locate_rootfs, lbh); - zfs_close(rootds); - rootds = NULL; - if (*lbh->rootfs == '\0') - goto err; - return (lbh); err: if (lbh != NULL) {