summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authorallanjude <allanjude@FreeBSD.org>2016-01-08 05:09:55 +0000
committerallanjude <allanjude@FreeBSD.org>2016-01-08 05:09:55 +0000
commit3b77b5c8be948152c705ae667bce31c6cd5ed1bc (patch)
treed624cf17476d0b80ca21cd18c5aa48af104600ac /sys/boot
parenta4cad9f2ef34eb4190fa8c79dcbedbeda889cab3 (diff)
downloadFreeBSD-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.c3
-rw-r--r--sys/boot/userboot/userboot/main.c55
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);
OpenPOWER on IntegriCloud