diff options
Diffstat (limited to 'usr/src/lib/libbe/common')
-rw-r--r-- | usr/src/lib/libbe/common/be_activate.c | 54 | ||||
-rw-r--r-- | usr/src/lib/libbe/common/be_list.c | 22 | ||||
-rw-r--r-- | usr/src/lib/libbe/common/libbe.h | 2 | ||||
-rw-r--r-- | usr/src/lib/libbe/common/libbe_priv.h | 8 |
4 files changed, 70 insertions, 16 deletions
diff --git a/usr/src/lib/libbe/common/be_activate.c b/usr/src/lib/libbe/common/be_activate.c index 1c2454991d..6133f2ca59 100644 --- a/usr/src/lib/libbe/common/be_activate.c +++ b/usr/src/lib/libbe/common/be_activate.c @@ -47,6 +47,7 @@ #include <libbe.h> #include <libbe_priv.h> +#include <libzfsbootenv.h> char *mnttab = MNTTAB; @@ -92,6 +93,8 @@ be_activate(nvlist_t *be_attrs) { int ret = BE_SUCCESS; char *be_name = NULL; + be_nextboot_state_t nextboot; + boolean_t next_boot; /* Initialize libzfs handle */ if (!be_zfs_init()) @@ -114,7 +117,17 @@ be_activate(nvlist_t *be_attrs) return (BE_ERR_INVAL); } - ret = _be_activate(be_name); + if (nvlist_lookup_boolean_value(be_attrs, BE_ATTR_ACTIVE_NEXTBOOT, + &next_boot) == 0) { + if (next_boot) + nextboot = BE_NEXTBOOT_SET; + else + nextboot = BE_NEXTBOOT_UNSET; + } else { + nextboot = BE_NEXTBOOT_IGNORE; + } + + ret = _be_activate(be_name, nextboot); be_zfs_fini(); @@ -206,6 +219,7 @@ be_installboot(nvlist_t *be_attrs) * Description: This does the actual work described in be_activate. * Parameters: * be_name - pointer to the name of BE to activate. + * nextboot - flag to ignore, set or unset nextboot * * Return: * BE_SUCCESS - Success @@ -214,7 +228,7 @@ be_installboot(nvlist_t *be_attrs) * Public */ int -_be_activate(char *be_name) +_be_activate(char *be_name, be_nextboot_state_t nextboot) { be_transaction_data_t cb = { 0 }; zfs_handle_t *zhp = NULL; @@ -233,6 +247,9 @@ _be_activate(char *be_name) if (be_name == NULL) return (BE_ERR_INVAL); + if (nextboot == BE_NEXTBOOT_SET && getzoneid() != GLOBAL_ZONEID) + return (BE_ERR_INVAL); + /* Set obe_name to be_name in the cb structure */ cb.obe_name = be_name; @@ -288,11 +305,31 @@ _be_activate(char *be_name) } if (getzoneid() == GLOBAL_ZONEID) { - if ((ret = set_bootfs(be_nodes->be_rpool, - root_ds)) != BE_SUCCESS) { - be_print_err(gettext("be_activate: failed to set " - "bootfs pool property for %s\n"), root_ds); - goto done; + switch (nextboot) { + case BE_NEXTBOOT_SET: + if ((ret = lzbe_set_boot_device(be_nodes->be_rpool, + lzbe_add, root_ds)) != 0) { + be_print_err(gettext("be_activate: failed to " + "set nextboot for %s\n"), root_ds); + goto done; + } + break; + case BE_NEXTBOOT_UNSET: + if ((ret = lzbe_set_boot_device(be_nodes->be_rpool, + lzbe_add, "")) != 0) { + be_print_err(gettext("be_activate: failed to " + "clear nextboot for %s\n"), root_ds); + goto done; + } + break; + default: + if ((ret = set_bootfs(be_nodes->be_rpool, + root_ds)) != BE_SUCCESS) { + be_print_err(gettext("be_activate: failed to " + "set bootfs pool property for %s\n"), + root_ds); + goto done; + } } } @@ -415,7 +452,8 @@ be_activate_current_be(void) return (ret); } - if ((ret = _be_activate(bt.obe_name)) != BE_SUCCESS) { + ret = _be_activate(bt.obe_name, BE_NEXTBOOT_IGNORE); + if (ret != BE_SUCCESS) { be_print_err(gettext("be_activate_current_be: failed to " "activate %s\n"), bt.obe_name); return (ret); diff --git a/usr/src/lib/libbe/common/be_list.c b/usr/src/lib/libbe/common/be_list.c index 926b7260da..3e0833ea83 100644 --- a/usr/src/lib/libbe/common/be_list.c +++ b/usr/src/lib/libbe/common/be_list.c @@ -47,6 +47,7 @@ #include <libbe.h> #include <libbe_priv.h> +#include <libzfsbootenv.h> /* * Callback data used for zfs_iter calls. @@ -986,13 +987,8 @@ be_qsort_compare_datasets(const void *x, const void *y) * Private */ static int -be_get_node_data( - zfs_handle_t *zhp, - be_node_list_t *be_node, - char *be_name, - const char *rpool, - char *current_be, - char *be_ds) +be_get_node_data(zfs_handle_t *zhp, be_node_list_t *be_node, char *be_name, + const char *rpool, char *current_be, char *be_ds) { char prop_buf[MAXPATHLEN]; nvlist_t *userprops = NULL; @@ -1041,6 +1037,8 @@ be_get_node_data( be_node->be_space_used = zfs_prop_get_int(zhp, ZFS_PROP_USED); if (getzoneid() == GLOBAL_ZONEID) { + char *nextboot; + if ((zphp = zpool_open(g_zfs, rpool)) == NULL) { be_print_err(gettext("be_get_node_data: failed to open " "pool (%s): %s\n"), rpool, @@ -1048,6 +1046,16 @@ be_get_node_data( return (zfs_err_to_be_err(g_zfs)); } + /* Set nextboot info */ + be_node->be_active_next = B_FALSE; + if (lzbe_get_boot_device(rpool, &nextboot) == 0) { + if (nextboot != NULL) { + if (strcmp(nextboot, be_ds) == 0) + be_node->be_active_next = B_TRUE; + free(nextboot); + } + } + (void) zpool_get_prop(zphp, ZPOOL_PROP_BOOTFS, prop_buf, ZFS_MAXPROPLEN, NULL, B_FALSE); if (be_has_grub() && (be_default_grub_bootfs(rpool, diff --git a/usr/src/lib/libbe/common/libbe.h b/usr/src/lib/libbe/common/libbe.h index b670d86ce5..774fe1ef9f 100644 --- a/usr/src/lib/libbe/common/libbe.h +++ b/usr/src/lib/libbe/common/libbe.h @@ -67,6 +67,7 @@ extern "C" { #define BE_ATTR_ACTIVE "active" #define BE_ATTR_ACTIVE_ON_BOOT "active_boot" +#define BE_ATTR_ACTIVE_NEXTBOOT "active_nextboot" #define BE_ATTR_GLOBAL_ACTIVE "global_active" #define BE_ATTR_SPACE "space_used" #define BE_ATTR_DATASET "dataset" @@ -174,6 +175,7 @@ typedef struct be_snapshot_list { typedef struct be_node_list { boolean_t be_mounted; /* is BE currently mounted */ + boolean_t be_active_next; /* is this BE active on next boot */ boolean_t be_active_on_boot; /* is this BE active on boot */ boolean_t be_active; /* is this BE active currently */ boolean_t be_global_active; /* is zone's BE associated with */ diff --git a/usr/src/lib/libbe/common/libbe_priv.h b/usr/src/lib/libbe/common/libbe_priv.h index f2960c4f17..ace201577f 100644 --- a/usr/src/lib/libbe/common/libbe_priv.h +++ b/usr/src/lib/libbe/common/libbe_priv.h @@ -142,6 +142,12 @@ struct be_defaults { char be_deflt_bename_starts_with[ZFS_MAX_DATASET_NAME_LEN]; }; +typedef enum be_nextboot_state { + BE_NEXTBOOT_IGNORE = -1, + BE_NEXTBOOT_SET, + BE_NEXTBOOT_UNSET +} be_nextboot_state_t; + /* Library globals */ extern libzfs_handle_t *g_zfs; extern boolean_t do_print; @@ -201,7 +207,7 @@ int zfs_err_to_be_err(libzfs_handle_t *); int errno_to_be_err(int); /* be_activate.c */ -int _be_activate(char *); +int _be_activate(char *, be_nextboot_state_t); int be_activate_current_be(void); boolean_t be_is_active_on_boot(char *); |