aboutsummaryrefslogtreecommitdiff
path: root/lib/libbe
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2019-04-03 17:04:38 +0000
committerKyle Evans <kevans@FreeBSD.org>2019-04-03 17:04:38 +0000
commit90cf61e8a57b5f5444d99dfd58101fcdc4740d89 (patch)
tree0dece93394cbdf33ee61648333363236e4605652 /lib/libbe
parentc973ee9e06274fec2bd595a83482ab3425537ebe (diff)
downloadsrc-90cf61e8a57b5f5444d99dfd58101fcdc4740d89.tar.gz
src-90cf61e8a57b5f5444d99dfd58101fcdc4740d89.zip
Notes
Diffstat (limited to 'lib/libbe')
-rw-r--r--lib/libbe/be.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/lib/libbe/be.c b/lib/libbe/be.c
index 103ce2aa7ce7..f6319064ad39 100644
--- a/lib/libbe/be.c
+++ b/lib/libbe/be.c
@@ -56,6 +56,9 @@ static int be_create_child_noent(libbe_handle_t *lbh, const char *active,
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)
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, const char *snap_name,
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));