mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
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
This commit is contained in:
parent
c973ee9e06
commit
90cf61e8a5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=345848
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user