summaryrefslogtreecommitdiff
path: root/usr/src/lib/libbe/common
diff options
context:
space:
mode:
authorJason King <jason.king@joyent.com>2020-11-16 16:37:31 +0000
committerJason King <jason.king@joyent.com>2020-11-16 16:37:31 +0000
commit5ffcb7f72a2f7a214b40ea8d0ef402f68aeada38 (patch)
tree86b767ee8b3625c219d1f5438eb25530c9703534 /usr/src/lib/libbe/common
parent45f7bf1d4508f8d85c7add1bdeb9f7ea099f0ab2 (diff)
parentde0f04687a2a3fe3692d9ad1254738343bf9c4eb (diff)
downloadillumos-joyent-5ffcb7f72a2f7a214b40ea8d0ef402f68aeada38.tar.gz
[illumos-gate merge]
commit de0f04687a2a3fe3692d9ad1254738343bf9c4eb 13310 Remove auto_ef.3ext as we don't have the software commit 25befe07d3c1488cbbdecdb765cd0558e12cc364 13302 pthread_attr_get_np.3c erroneously refers to pthread_getattr_np commit 509a605d87b8005c687f8d8264f1be379620e886 13304 bhyve ioport handling bungled on reinit commit 83cd75bb2949d26e6eb38ddefc60fdeed1909643 13309 bhyve movs emulation leaks mem refcnt commit b713c91e508f40be7797bedd4ae1146ef0652625 7537 want nextboot (one time boot) support commit 09fcda9fe16a733cc35aa3156a47ef4b909251a6 13172 Port OpenZFS: zfs label bootenv should store data as nvlist commit c4ecba8aa5f13f00c2439c06af2aa1198771ee66 13025 Port OpenZFS: Add support for boot environment data to be stored in the label commit 1a2acdcd3ce765904dbf2bfc511e92d68022d100 13308 testrunner/run needs updates for python 3.9 commit 04573c73a7ab1505c46b2c4db26bfde5176dd6a5 13286 bhyve ins/outs emulation misuses %rax commit 3dfdac06b0c70e672dbe56a2f38ec05fc0254d07 13278 CTF assertion failed cmp->cm_tmap[id].cmt_map == suid commit a676209deb2ce5d0c98f331659de25e2483f8c4c 13252 ctf_update()/ctf_dwarf_convert_function() leak memory commit effb27ee30c48fe502152c38487ced379d9f8693 13247 CTF conversion fails with large files 13251 CTF conversion fails if any CU is missing DWARF data Conflicts: usr/src/test/test-runner/cmd/run usr/src/lib/libctf/common/libctf.h usr/src/lib/libctf/common/ctf_convert.c
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 *);