diff options
author | allanjude <allanjude@FreeBSD.org> | 2016-01-08 05:09:55 +0000 |
---|---|---|
committer | allanjude <allanjude@FreeBSD.org> | 2016-01-08 05:09:55 +0000 |
commit | 3b77b5c8be948152c705ae667bce31c6cd5ed1bc (patch) | |
tree | d624cf17476d0b80ca21cd18c5aa48af104600ac /sys/boot | |
parent | a4cad9f2ef34eb4190fa8c79dcbedbeda889cab3 (diff) | |
download | FreeBSD-src-3b77b5c8be948152c705ae667bce31c6cd5ed1bc.zip FreeBSD-src-3b77b5c8be948152c705ae667bce31c6cd5ed1bc.tar.gz |
Add support for ZFS Boot Environments to userboot (for bhyve and others)
While here, also fix a possible null pointer
Reported by: lattera
MFC after: 3 days
Sponsored by: ScaleEngine Inc.
Diffstat (limited to 'sys/boot')
-rw-r--r-- | sys/boot/i386/loader/main.c | 3 | ||||
-rw-r--r-- | sys/boot/userboot/userboot/main.c | 55 |
2 files changed, 57 insertions, 1 deletions
diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c index d4073e7..73f3507 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 d4cefff..335c8fd 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), @@ -198,6 +203,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) { char devname[32]; @@ -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); |