aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2019-02-10 21:19:09 +0000
committerKyle Evans <kevans@FreeBSD.org>2019-02-10 21:19:09 +0000
commit13c62c50e345a24aa0a4a14c7eb167ec668266bd (patch)
treef0088893267919bf9ca43fceffe324eb74aa3157
parentdcbd7de5b66ac485ea29f73c9c24c89ae4cd3992 (diff)
downloadsrc-13c62c50e345a24aa0a4a14c7eb167ec668266bd.tar.gz
src-13c62c50e345a24aa0a4a14c7eb167ec668266bd.zip
libbe(3): Add a destroy option for removing the origin
Currently origin snapshots are left behind when a BE is destroyed, whether it was an auto-created snapshot or explicitly specified via, for example, `bectl create -e be@mysnap ...`. Removing it automatically could be argued as a POLA violation in some circumstances, so provide a flag to be_destroy for it. An accompanying option will be added to bectl(8) to utilize this. Some minor style/consistency nits in the affected areas also addressed. Reported by: Shawn Webb MFC after: 1 week
Notes
Notes: svn path=/head/; revision=343977
-rw-r--r--lib/libbe/be.c26
-rw-r--r--lib/libbe/be.h5
2 files changed, 24 insertions, 7 deletions
diff --git a/lib/libbe/be.c b/lib/libbe/be.c
index b07e791805b6..cf13e9fec9bd 100644
--- a/lib/libbe/be.c
+++ b/lib/libbe/be.c
@@ -203,13 +203,14 @@ be_destroy_cb(zfs_handle_t *zfs_hdl, void *data)
int
be_destroy(libbe_handle_t *lbh, const char *name, int options)
{
+ char origin[BE_MAXPATHLEN], path[BE_MAXPATHLEN];
zfs_handle_t *fs;
- char path[BE_MAXPATHLEN];
char *p;
int err, force, mounted;
p = path;
force = options & BE_DESTROY_FORCE;
+ *origin = '\0';
be_root_concat(lbh, name, path);
@@ -222,17 +223,21 @@ be_destroy(libbe_handle_t *lbh, const char *name, int options)
return (set_error(lbh, BE_ERR_DESTROYACT));
fs = zfs_open(lbh->lzh, p, ZFS_TYPE_FILESYSTEM);
+ if (fs == NULL)
+ return (set_error(lbh, BE_ERR_ZFSOPEN));
+ if ((options & BE_DESTROY_ORIGIN) != 0 &&
+ zfs_prop_get(fs, ZFS_PROP_ORIGIN, origin, sizeof(origin),
+ NULL, NULL, 0, 1) != 0)
+ return (set_error(lbh, BE_ERR_NOORIGIN));
} else {
-
if (!zfs_dataset_exists(lbh->lzh, path, ZFS_TYPE_SNAPSHOT))
return (set_error(lbh, BE_ERR_NOENT));
fs = zfs_open(lbh->lzh, p, ZFS_TYPE_SNAPSHOT);
+ if (fs == NULL)
+ return (set_error(lbh, BE_ERR_ZFSOPEN));
}
- if (fs == NULL)
- return (set_error(lbh, BE_ERR_ZFSOPEN));
-
/* Check if mounted, unmount if force is specified */
if ((mounted = zfs_is_mounted(fs, NULL)) != 0) {
if (force)
@@ -248,6 +253,17 @@ be_destroy(libbe_handle_t *lbh, const char *name, int options)
return (set_error(lbh, BE_ERR_UNKNOWN));
}
+ if (*origin != '\0') {
+ fs = zfs_open(lbh->lzh, origin, ZFS_TYPE_SNAPSHOT);
+ if (fs == NULL)
+ return (set_error(lbh, BE_ERR_ZFSOPEN));
+ err = zfs_destroy(fs, false);
+ if (err == EBUSY)
+ return (set_error(lbh, BE_ERR_DESTROYMNT));
+ else if (err != 0)
+ return (set_error(lbh, BE_ERR_UNKNOWN));
+ }
+
return (0);
}
diff --git a/lib/libbe/be.h b/lib/libbe/be.h
index 265ce263cf55..dcf336d7423c 100644
--- a/lib/libbe/be.h
+++ b/lib/libbe/be.h
@@ -93,7 +93,8 @@ int be_rename(libbe_handle_t *, const char *, const char *);
/* Bootenv removal functions */
typedef enum {
- BE_DESTROY_FORCE = 1 << 0,
+ BE_DESTROY_FORCE = 1 << 0,
+ BE_DESTROY_ORIGIN = 1 << 1,
} be_destroy_opt_t;
int be_destroy(libbe_handle_t *, const char *, int);
@@ -102,7 +103,7 @@ int be_destroy(libbe_handle_t *, const char *, int);
typedef enum {
BE_MNT_FORCE = 1 << 0,
- BE_MNT_DEEP = 1 << 1,
+ BE_MNT_DEEP = 1 << 1,
} be_mount_opt_t;
int be_mount(libbe_handle_t *, char *, char *, int, char *);