diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c index d4073e7da71..73f3507fb8f 100644 --- a/sys/boot/i386/loader/main.c +++ b/sys/boot/i386/loader/main.c @@ -321,7 +321,8 @@ init_zfs_bootenv(char *currdev) currdev++; /* Remove the last element (current bootenv) */ beroot = strrchr(currdev, '/'); - beroot[0] = '\0'; + if (beroot != NULL) + beroot[0] = '\0'; beroot = currdev; diff --git a/sys/boot/userboot/userboot/main.c b/sys/boot/userboot/userboot/main.c index d4cefff4225..335c8fd05c1 100644 --- a/sys/boot/userboot/userboot/main.c +++ b/sys/boot/userboot/userboot/main.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); static void userboot_zfs_probe(void); static int userboot_zfs_found; +static void init_zfs_bootenv(char *currdev); #endif #define USERBOOT_VERSION USERBOOT_VERSION_3 @@ -190,6 +191,10 @@ extract_currdev(void) dev.d_unit = 0; } +#if defined(USERBOOT_ZFS_SUPPORT) + init_zfs_bootenv(zfs_fmtdev(&dev)); +#endif + env_setenv("currdev", EV_VOLATILE, userboot_fmtdev(&dev), userboot_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, userboot_fmtdev(&dev), @@ -197,6 +202,29 @@ extract_currdev(void) } #if defined(USERBOOT_ZFS_SUPPORT) +static void +init_zfs_bootenv(char *currdev) +{ + char *beroot; + + /* Remove the trailing : */ + currdev[strlen(currdev) - 1] = '\0'; + setenv("zfs_be_active", currdev, 1); + /* Do not overwrite if already set */ + setenv("vfs.root.mountfrom", currdev, 0); + /* Forward past zfs: */ + currdev = strchr(currdev, ':'); + currdev++; + /* Remove the last element (current bootenv) */ + beroot = strrchr(currdev, '/'); + if (beroot != NULL) + beroot[0] = '\0'; + + beroot = currdev; + + setenv("zfs_be_root", beroot, 1); +} + static void userboot_zfs_probe(void) { @@ -237,6 +265,33 @@ command_lszfs(int argc, char *argv[]) } return (CMD_OK); } + +COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments", + command_reloadbe); + +static int +command_reloadbe(int argc, char *argv[]) +{ + int err; + + if (argc > 2) { + command_errmsg = "wrong number of arguments"; + return (CMD_ERROR); + } + + if (argc == 2) { + err = zfs_bootenv(argv[1]); + } else { + err = zfs_bootenv(getenv("zfs_be_root")); + } + + if (err != 0) { + command_errmsg = strerror(err); + return (CMD_ERROR); + } + + return (CMD_OK); +} #endif /* USERBOOT_ZFS_SUPPORT */ COMMAND_SET(quit, "quit", "exit the loader", command_quit);