aboutsummaryrefslogtreecommitdiff
path: root/lib/libbe
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libbe')
-rw-r--r--lib/libbe/Makefile4
-rw-r--r--lib/libbe/be.c69
-rw-r--r--lib/libbe/be.h1
-rw-r--r--lib/libbe/be_impl.h1
-rw-r--r--lib/libbe/be_info.c11
-rw-r--r--lib/libbe/libbe.326
6 files changed, 53 insertions, 59 deletions
diff --git a/lib/libbe/Makefile b/lib/libbe/Makefile
index 2ef809d97ea2..d3d5beee293e 100644
--- a/lib/libbe/Makefile
+++ b/lib/libbe/Makefile
@@ -13,7 +13,9 @@ INCS= be.h
MAN= libbe.3
LIBADD+= zfs
-LIBADD+= nvpair spl
+LIBADD+= nvpair
+LIBADD+= spl
+LIBADD+= zfsbootenv
CFLAGS+= -DIN_BASE -DHAVE_RPC_TYPES
CFLAGS+= -I${SRCTOP}/sys/contrib/openzfs/include
diff --git a/lib/libbe/be.c b/lib/libbe/be.c
index 72f937453b08..644cf90a6fd7 100644
--- a/lib/libbe/be.c
+++ b/lib/libbe/be.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
+#include <libzfsbootenv.h>
#include "be.h"
#include "be_impl.h"
@@ -1221,43 +1222,20 @@ be_add_child(libbe_handle_t *lbh, const char *child_path, bool cp_if_exists)
}
#endif /* SOON */
-static int
-be_set_nextboot(libbe_handle_t *lbh, nvlist_t *config, uint64_t pool_guid,
- const char *zfsdev)
-{
- nvlist_t **child;
- uint64_t vdev_guid;
- int c, children;
-
- if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN, &child,
- &children) == 0) {
- for (c = 0; c < children; ++c)
- if (be_set_nextboot(lbh, child[c], pool_guid, zfsdev) != 0)
- return (1);
- return (0);
- }
-
- if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID,
- &vdev_guid) != 0) {
- return (1);
- }
-
- if (zpool_nextboot(lbh->lzh, pool_guid, vdev_guid, zfsdev) != 0) {
- perror("ZFS_IOC_NEXTBOOT failed");
- return (1);
- }
-
- return (0);
-}
-
/*
- * Deactivate old BE dataset; currently just sets canmount=noauto
+ * Deactivate old BE dataset; currently just sets canmount=noauto or
+ * resets boot once configuration.
*/
-static int
-be_deactivate(libbe_handle_t *lbh, const char *ds)
+int
+be_deactivate(libbe_handle_t *lbh, const char *ds, bool temporary)
{
zfs_handle_t *zfs;
+ if (temporary) {
+ return (lzbe_set_boot_device(
+ zpool_get_name(lbh->active_phandle), lzbe_add, NULL));
+ }
+
if ((zfs = zfs_open(lbh->lzh, ds, ZFS_TYPE_DATASET)) == NULL)
return (1);
if (zfs_prop_set(zfs, "canmount", "noauto") != 0)
@@ -1270,10 +1248,8 @@ int
be_activate(libbe_handle_t *lbh, const char *bootenv, bool temporary)
{
char be_path[BE_MAXPATHLEN];
- char buf[BE_MAXPATHLEN];
- nvlist_t *config, *dsprops, *vdevs;
+ nvlist_t *dsprops;
char *origin;
- uint64_t pool_guid;
zfs_handle_t *zhp;
int err;
@@ -1284,27 +1260,10 @@ be_activate(libbe_handle_t *lbh, const char *bootenv, bool temporary)
return (set_error(lbh, err));
if (temporary) {
- config = zpool_get_config(lbh->active_phandle, NULL);
- if (config == NULL)
- /* config should be fetchable... */
- return (set_error(lbh, BE_ERR_UNKNOWN));
-
- if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
- &pool_guid) != 0)
- /* Similarly, it shouldn't be possible */
- return (set_error(lbh, BE_ERR_UNKNOWN));
-
- /* Expected format according to zfsbootcfg(8) man */
- snprintf(buf, sizeof(buf), "zfs:%s:", be_path);
-
- /* We have no config tree */
- if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
- &vdevs) != 0)
- return (set_error(lbh, BE_ERR_NOPOOL));
-
- return (be_set_nextboot(lbh, vdevs, pool_guid, buf));
+ return (lzbe_set_boot_device(
+ zpool_get_name(lbh->active_phandle), lzbe_add, be_path));
} else {
- if (be_deactivate(lbh, lbh->bootfs) != 0)
+ if (be_deactivate(lbh, lbh->bootfs, false) != 0)
return (-1);
/* Obtain bootenv zpool */
diff --git a/lib/libbe/be.h b/lib/libbe/be.h
index 3a99c177e4bd..960b1adf2457 100644
--- a/lib/libbe/be.h
+++ b/lib/libbe/be.h
@@ -81,6 +81,7 @@ int be_prop_list_alloc(nvlist_t **be_list);
void be_prop_list_free(nvlist_t *be_list);
int be_activate(libbe_handle_t *, const char *, bool);
+int be_deactivate(libbe_handle_t *, const char *, bool);
bool be_is_auto_snapshot_name(libbe_handle_t *, const char *);
diff --git a/lib/libbe/be_impl.h b/lib/libbe/be_impl.h
index 98fd3b29f932..0b0f0db3cb5c 100644
--- a/lib/libbe/be_impl.h
+++ b/lib/libbe/be_impl.h
@@ -63,6 +63,7 @@ typedef struct prop_data {
nvlist_t *list;
libbe_handle_t *lbh;
bool single_object; /* list will contain props directly */
+ char *bootonce;
} prop_data_t;
int prop_list_builder_cb(zfs_handle_t *, void *);
diff --git a/lib/libbe/be_info.c b/lib/libbe/be_info.c
index 7f1b58a071ca..745f4f9be23b 100644
--- a/lib/libbe/be_info.c
+++ b/lib/libbe/be_info.c
@@ -30,6 +30,7 @@
__FBSDID("$FreeBSD$");
#include <sys/zfs_context.h>
+#include <libzfsbootenv.h>
#include "be.h"
#include "be_impl.h"
@@ -108,6 +109,7 @@ be_get_bootenv_props(libbe_handle_t *lbh, nvlist_t *dsnvl)
data.lbh = lbh;
data.list = dsnvl;
data.single_object = false;
+ data.bootonce = NULL;
return (be_proplist_update(&data));
}
@@ -121,6 +123,7 @@ be_get_dataset_props(libbe_handle_t *lbh, const char *name, nvlist_t *props)
data.lbh = lbh;
data.list = props;
data.single_object = true;
+ data.bootonce = NULL;
if ((snap_hdl = zfs_open(lbh->lzh, name,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT)) == NULL)
return (BE_ERR_ZFSOPEN);
@@ -140,6 +143,7 @@ be_get_dataset_snapshots(libbe_handle_t *lbh, const char *name, nvlist_t *props)
data.lbh = lbh;
data.list = props;
data.single_object = false;
+ data.bootonce = NULL;
if ((ds_hdl = zfs_open(lbh->lzh, name,
ZFS_TYPE_FILESYSTEM)) == NULL)
return (BE_ERR_ZFSOPEN);
@@ -179,6 +183,10 @@ prop_list_builder_cb(zfs_handle_t *zfs_hdl, void *data_p)
dataset = zfs_get_name(zfs_hdl);
nvlist_add_string(props, "dataset", dataset);
+ if (data->bootonce != NULL &&
+ strcmp(dataset, data->bootonce) == 0)
+ nvlist_add_boolean_value(props, "bootonce", true);
+
name = strrchr(dataset, '/') + 1;
nvlist_add_string(props, "name", name);
@@ -246,6 +254,9 @@ be_proplist_update(prop_data_t *data)
ZFS_TYPE_FILESYSTEM)) == NULL)
return (BE_ERR_ZFSOPEN);
+ (void) lzbe_get_boot_device(zpool_get_name(data->lbh->active_phandle),
+ &data->bootonce);
+
/* XXX TODO: some error checking here */
zfs_iter_filesystems(root_hdl, prop_list_builder_cb, data);
diff --git a/lib/libbe/libbe.3 b/lib/libbe/libbe.3
index 0a93b30dbcbc..b8bbc29cf1d3 100644
--- a/lib/libbe/libbe.3
+++ b/lib/libbe/libbe.3
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 16, 2019
+.Dd July 22, 2020
.Dt LIBBE 3
.Os
.Sh NAME
@@ -78,6 +78,10 @@
.Pp
.Ft int
.Fn be_activate "libbe_handle_t *hdl" "const char *be_name" "bool temporary"
+.Pp
+.Ft int
+.Fn be_deactivate "libbe_handle_t *hdl" "const char *be_name" "bool temporary"
+.Pp
.Ft int
.Fn be_destroy "libbe_handle_t *hdl" "const char *be_name" "int options"
.Pp
@@ -270,8 +274,24 @@ If the
.Fa temporary
flag is set, then it will be active for the next boot only, as done by
.Xr zfsbootcfg 8 .
-Next boot functionality is currently only available when booting in x86 BIOS
-mode.
+.Pp
+The
+.Fn be_deactivate
+function deactivates a boot environment.
+If the
+.Fa temporary
+flag is set, then it will cause removal of boot once configuration, set by
+.Fn be_activate
+function or by
+.Xr zfsbootcfg 8 .
+If the
+.Fa temporary
+flag is not set,
+.Fn be_deactivate
+function will set zfs
+.Dv canmount
+property to
+.Dv noauto .
.Pp
The
.Fn be_destroy