summaryrefslogtreecommitdiff
path: root/usr/src/lib/libbe/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libbe/common')
-rw-r--r--usr/src/lib/libbe/common/be_activate.c54
-rw-r--r--usr/src/lib/libbe/common/be_list.c22
-rw-r--r--usr/src/lib/libbe/common/libbe.h2
-rw-r--r--usr/src/lib/libbe/common/libbe_priv.h8
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 *);