svn commit: r345848 - head/lib/libbe
Kyle Evans
kevans at FreeBSD.org
Tue Sep 3 14:06:31 UTC 2019
Author: kevans
Date: Wed Apr 3 17:04:38 2019
New Revision: 345848
URL: https://svnweb.freebsd.org/changeset/base/345848
Log:
libbe(3): Add a serial to the generated snapshot names
To use bectl in an example, when one creates a new boot environment with
either `bectl create <be>` or `bectl create -e <otherbe> <be>`, libbe will
take a snapshot of the original boot environment to clone. Previously, this
used %F-%T date format as the snapshot name, but this has some limitations-
attempting to create multiple boot environments in quick succession may
collide if done within the same second.
Tack a serial onto it to reduce the chances of a collision... we could still
collide if multiple processes/threads are creating boot environments at the
same time, but this is likely not a big concern as this has only been
reported as occurring in freebsd-ci setup.
MFC after: 3 days
Modified:
head/lib/libbe/be.c
Modified: head/lib/libbe/be.c
==============================================================================
--- head/lib/libbe/be.c Wed Apr 3 17:02:18 2019 (r345847)
+++ head/lib/libbe/be.c Wed Apr 3 17:04:38 2019 (r345848)
@@ -56,6 +56,9 @@ static int be_create_child_noent(libbe_handle_t *lbh,
static int be_create_child_cloned(libbe_handle_t *lbh, const char *active);
#endif
+/* Arbitrary... should tune */
+#define BE_SNAP_SERIAL_MAX 1024
+
/*
* Iterator function for locating the rootfs amongst the children of the
* zfs_be_root set by loader(8). data is expected to be a libbe_handle_t *.
@@ -320,13 +323,32 @@ be_destroy(libbe_handle_t *lbh, const char *name, int
options & ~BE_DESTROY_ORIGIN));
}
+static void
+be_setup_snapshot_name(libbe_handle_t *lbh, char *buf, size_t buflen)
+{
+ time_t rawtime;
+ int len, serial;
+
+ time(&rawtime);
+ len = strlen(buf);
+ len += strftime(buf + len, buflen - len, "@%F-%T", localtime(&rawtime));
+ /* No room for serial... caller will do its best */
+ if (buflen - len < 2)
+ return;
+
+ for (serial = 0; serial < BE_SNAP_SERIAL_MAX; ++serial) {
+ snprintf(buf + len, buflen - len, "-%d", serial);
+ if (!zfs_dataset_exists(lbh->lzh, buf, ZFS_TYPE_SNAPSHOT))
+ return;
+ }
+}
+
int
be_snapshot(libbe_handle_t *lbh, const char *source, const char *snap_name,
bool recursive, char *result)
{
char buf[BE_MAXPATHLEN];
- time_t rawtime;
- int len, err;
+ int err;
be_root_concat(lbh, source, buf);
@@ -344,10 +366,8 @@ be_snapshot(libbe_handle_t *lbh, const char *source, c
snprintf(result, BE_MAXPATHLEN, "%s@%s", source,
snap_name);
} else {
- time(&rawtime);
- len = strlen(buf);
- strftime(buf + len, sizeof(buf) - len,
- "@%F-%T", localtime(&rawtime));
+ be_setup_snapshot_name(lbh, buf, sizeof(buf));
+
if (result != NULL && strlcpy(result, strrchr(buf, '/') + 1,
sizeof(buf)) >= sizeof(buf))
return (set_error(lbh, BE_ERR_INVALIDNAME));
More information about the svn-src-all
mailing list