svn commit: r353644 - head/lib/libbe

Kyle Evans kevans at FreeBSD.org
Wed Oct 16 14:43:06 UTC 2019


Author: kevans
Date: Wed Oct 16 14:43:05 2019
New Revision: 353644
URL: https://svnweb.freebsd.org/changeset/base/353644

Log:
  libbe(3): add needed bits for be_destroy to auto-destroy some origins
  
  New BEs can be created from either an existing snapshot or an existing BE.
  If an existing BE is chosen (either implicitly via 'bectl create' or
  explicitly via 'bectl create -e foo bar', for instance), then bectl will
  create a snapshot of the current BE or "foo" with be_snapshot, with a name
  formatted like: strftime("%F-%T") and a serial added to it.
  
  This commit adds the needed bits for libbe or consumers to determine if a
  snapshot names matches one of these auto-created snapshots (with some light
  validation of the date/time/serial), and also a be_destroy flag to specify
  that the origin should be automatically destroyed if possible.
  
  A future commit to bectl will specify BE_DESTROY_AUTOORIGIN by default so we
  clean up the origin in the most common case, non-user-managed snapshots.

Modified:
  head/lib/libbe/be.c
  head/lib/libbe/be.h
  head/lib/libbe/libbe.3

Modified: head/lib/libbe/be.c
==============================================================================
--- head/lib/libbe/be.c	Wed Oct 16 14:42:49 2019	(r353643)
+++ head/lib/libbe/be.c	Wed Oct 16 14:43:05 2019	(r353644)
@@ -229,6 +229,7 @@ be_destroy_cb(zfs_handle_t *zfs_hdl, void *data)
 	return (0);
 }
 
+#define	BE_DESTROY_NEEDORIGIN	(BE_DESTROY_ORIGIN | BE_DESTROY_AUTOORIGIN)
 /*
  * Destroy the boot environment or snapshot specified by the name
  * parameter. Options are or'd together with the possible values:
@@ -264,11 +265,24 @@ be_destroy(libbe_handle_t *lbh, const char *name, int 
 		if (fs == NULL)
 			return (set_error(lbh, BE_ERR_ZFSOPEN));
 
-		if ((options & BE_DESTROY_ORIGIN) != 0 &&
+		if ((options & BE_DESTROY_NEEDORIGIN) != 0 &&
 		    zfs_prop_get(fs, ZFS_PROP_ORIGIN, origin, sizeof(origin),
 		    NULL, NULL, 0, 1) != 0)
 			return (set_error(lbh, BE_ERR_NOORIGIN));
 
+		/*
+		 * If the caller wants auto-origin destruction and the origin
+		 * name matches one of our automatically created snapshot names
+		 * (i.e. strftime("%F-%T") with a serial at the end), then
+		 * we'll set the DESTROY_ORIGIN flag and nuke it
+		 * be_is_auto_snapshot_name is exported from libbe(3) so that
+		 * the caller can determine if it needs to warn about the origin
+		 * not being destroyed or not.
+		 */
+		if ((options & BE_DESTROY_AUTOORIGIN) != 0 &&
+		    be_is_auto_snapshot_name(lbh, origin))
+			options |= BE_DESTROY_ORIGIN;
+
 		/* Don't destroy a mounted dataset unless force is specified */
 		if ((mounted = zfs_is_mounted(fs, NULL)) != 0) {
 			if (force) {
@@ -341,6 +355,25 @@ be_setup_snapshot_name(libbe_handle_t *lbh, char *buf,
 		if (!zfs_dataset_exists(lbh->lzh, buf, ZFS_TYPE_SNAPSHOT))
 			return;
 	}
+}
+
+bool
+be_is_auto_snapshot_name(libbe_handle_t *lbh, const char *name)
+{
+	const char *snap;
+	int day, hour, minute, month, second, serial, year;
+
+	if ((snap = strchr(name, '@')) == NULL)
+		return (false);
+	++snap;
+	/* We'll grab the individual components and do some light validation. */
+	if (sscanf(snap, "%d-%d-%d-%d:%d:%d-%d", &year, &month, &day, &hour,
+	    &minute, &second, &serial) != 7)
+		return (false);
+	return (year >= 1970) && (month >= 1 && month <= 12) &&
+	    (day >= 1 && day <= 31) && (hour >= 0 && hour <= 23) &&
+	    (minute >= 0 && minute <= 59) && (second >= 0 && second <= 60) &&
+	    serial >= 0;
 }
 
 int

Modified: head/lib/libbe/be.h
==============================================================================
--- head/lib/libbe/be.h	Wed Oct 16 14:42:49 2019	(r353643)
+++ head/lib/libbe/be.h	Wed Oct 16 14:43:05 2019	(r353644)
@@ -82,6 +82,8 @@ void be_prop_list_free(nvlist_t *be_list);
 
 int be_activate(libbe_handle_t *, const char *, bool);
 
+bool be_is_auto_snapshot_name(libbe_handle_t *, const char *);
+
 /* Bootenv creation functions */
 int be_create(libbe_handle_t *, const char *);
 int be_create_depth(libbe_handle_t *, const char *, const char *, int);
@@ -97,6 +99,7 @@ int be_rename(libbe_handle_t *, const char *, const ch
 typedef enum {
 	BE_DESTROY_FORCE	= 1 << 0,
 	BE_DESTROY_ORIGIN	= 1 << 1,
+	BE_DESTROY_AUTOORIGIN	= 1 << 2,
 } be_destroy_opt_t;
 
 int be_destroy(libbe_handle_t *, const char *, int);

Modified: head/lib/libbe/libbe.3
==============================================================================
--- head/lib/libbe/libbe.3	Wed Oct 16 14:42:49 2019	(r353643)
+++ head/lib/libbe/libbe.3	Wed Oct 16 14:43:05 2019	(r353644)
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 22, 2019
+.Dd October 16, 2019
 .Dt LIBBE 3
 .Os
 .Sh NAME
@@ -59,6 +59,9 @@
 .Ft const char * Ns
 .Fn be_root_path "libbe_handle_t *hdl"
 .Pp
+.Ft bool Ns
+.Fn be_is_auto_snapshot_name "libbe_handle_t *hdl" "const char *snap"
+.Pp
 .Ft int
 .Fn be_create "libbe_handle_t *hdl" "const char *be_name"
 .Pp
@@ -212,6 +215,18 @@ active on reboot.
 The
 .Fn be_root_path
 function returns the boot environment root path.
+.Pp
+The
+.Fn be_is_auto_snapshot_name
+function is used to determine if the given snapshot name matches the format that
+the
+.Fn be_snapshot
+function will use by default if it is not given a snapshot name to use.
+It returns
+.Dv true
+if the name matches the format, and
+.Dv false
+if it does not.
 .Pp
 The
 .Fn be_create


More information about the svn-src-head mailing list