diff options
author | allanjude <allanjude@FreeBSD.org> | 2016-01-13 01:50:02 +0000 |
---|---|---|
committer | allanjude <allanjude@FreeBSD.org> | 2016-01-13 01:50:02 +0000 |
commit | e72f532e157a4f8c7f6ce72a3f59d2a2d865662b (patch) | |
tree | feae895cdd35fc83efbdb3a5e6ead7ec7dbf874f /sys/boot/i386 | |
parent | 46a82c43e860b1c5e14e6808ca205ee9b5199616 (diff) | |
download | FreeBSD-src-e72f532e157a4f8c7f6ce72a3f59d2a2d865662b.zip FreeBSD-src-e72f532e157a4f8c7f6ce72a3f59d2a2d865662b.tar.gz |
MFC: r293001
Introduce the ZFS Boot Environments menu to the loader menu
MFC: r293414
Add ZFS Boot Environments menu to userboot
MFC: r293454
Only call init_zfs_bootenv when the system is booted with ZFS
MFC: r293612
Fix calling init_zfs_bootenv to early, resulting in empty ZFS BE menu
Relnotes: yes
Sponsored by: ScaleEngine Inc.
Diffstat (limited to 'sys/boot/i386')
-rw-r--r-- | sys/boot/i386/loader/main.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c index c1a3ca4..be08271 100644 --- a/sys/boot/i386/loader/main.c +++ b/sys/boot/i386/loader/main.c @@ -69,6 +69,7 @@ static int isa_inb(int port); static void isa_outb(int port, int value); void exit(int code); #ifdef LOADER_ZFS_SUPPORT +static void init_zfs_bootenv(char *currdev); static void i386_zfs_probe(void); #endif @@ -291,12 +292,45 @@ extract_currdev(void) new_currdev.d_unit = 0; } +#ifdef LOADER_ZFS_SUPPORT + if (new_currdev.d_type == DEVT_ZFS) + init_zfs_bootenv(zfs_fmtdev(&new_currdev)); +#endif + env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev), i386_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset, env_nounset); } +#ifdef LOADER_ZFS_SUPPORT +static void +init_zfs_bootenv(char *currdev) +{ + char *beroot; + + if (strlen(currdev) == 0) + return; + if(strncmp(currdev, "zfs:", 4) != 0) + return; + /* Remove the trailing : */ + currdev[strlen(currdev) - 1] = '\0'; + setenv("zfs_be_active", currdev, 1); + setenv("zfs_be_currpage", "1", 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); +} +#endif + COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); static int @@ -350,6 +384,40 @@ command_lszfs(int argc, char *argv[]) command_errmsg = strerror(err); return (CMD_ERROR); } + + 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; + char *root; + + if (argc > 2) { + command_errmsg = "wrong number of arguments"; + return (CMD_ERROR); + } + + if (argc == 2) { + err = zfs_bootenv(argv[1]); + } else { + root = getenv("zfs_be_root"); + if (root == NULL) { + /* There does not appear to be a ZFS pool here, exit without error */ + return (CMD_OK); + } + err = zfs_bootenv(getenv("zfs_be_root")); + } + + if (err != 0) { + command_errmsg = strerror(err); + return (CMD_ERROR); + } + return (CMD_OK); } #endif |