bectl(8): create non-recursive boot environments

bectl advertises that it has the ability to create recursive and
non-recursive boot environments. This patch implements that functionality
using the be_create_depth API provided by libbe. With this patch, bectl now
works as bectl(8) describes in regards to creating recursive/non-recursive
boot environments.

Submitted by:	Rob Fairbanks <rob.fx907 gmail com> (with minor changes)
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D20240
This commit is contained in:
Kyle Evans 2019-06-27 14:03:32 +00:00
parent 338412e5a6
commit d05fa0d949
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=349455
2 changed files with 43 additions and 18 deletions

View File

@ -184,7 +184,8 @@ bectl_cmd_activate(int argc, char *argv[])
static int static int
bectl_cmd_create(int argc, char *argv[]) bectl_cmd_create(int argc, char *argv[])
{ {
char *atpos, *bootenv, *snapname, *source; char snapshot[BE_MAXPATHLEN];
char *atpos, *bootenv, *snapname;
int err, opt; int err, opt;
bool recursive; bool recursive;
@ -214,6 +215,8 @@ bectl_cmd_create(int argc, char *argv[])
} }
bootenv = *argv; bootenv = *argv;
err = BE_ERR_SUCCESS;
if ((atpos = strchr(bootenv, '@')) != NULL) { if ((atpos = strchr(bootenv, '@')) != NULL) {
/* /*
* This is the "create a snapshot variant". No new boot * This is the "create a snapshot variant". No new boot
@ -221,24 +224,22 @@ bectl_cmd_create(int argc, char *argv[])
*/ */
*atpos++ = '\0'; *atpos++ = '\0';
err = be_snapshot(be, bootenv, atpos, recursive, NULL); err = be_snapshot(be, bootenv, atpos, recursive, NULL);
} else if (snapname != NULL) {
if (strchr(snapname, '@') != NULL)
err = be_create_from_existing_snap(be, bootenv,
snapname);
else
err = be_create_from_existing(be, bootenv, snapname);
} else { } else {
if ((snapname = strchr(bootenv, '@')) != NULL) { if (snapname == NULL)
*(snapname++) = '\0'; /* Create from currently booted BE */
if ((err = be_snapshot(be, be_active_path(be), err = be_snapshot(be, be_active_path(be), NULL,
snapname, true, NULL)) != BE_ERR_SUCCESS) recursive, snapshot);
fprintf(stderr, "failed to create snapshot\n"); else if (strchr(snapname, '@') != NULL)
asprintf(&source, "%s@%s", be_active_path(be), snapname); /* Create from given snapshot */
err = be_create_from_existing_snap(be, bootenv, strlcpy(snapshot, snapname, sizeof(snapshot));
source); else
return (err); /* Create from given BE */
} else err = be_snapshot(be, snapname, NULL, recursive,
err = be_create(be, bootenv); snapshot);
if (err == BE_ERR_SUCCESS)
err = be_create_depth(be, bootenv, snapshot,
recursive == true ? -1 : 0);
} }
switch (err) { switch (err) {

View File

@ -99,11 +99,35 @@ bectl_create_body()
mount=${cwd}/mnt mount=${cwd}/mnt
bectl_create_setup ${zpool} ${disk} ${mount} bectl_create_setup ${zpool} ${disk} ${mount}
# Create a child dataset that will be used to test creation
# of recursive and non-recursive boot environments.
atf_check zfs create -o mountpoint=/usr -o canmount=noauto \
${zpool}/ROOT/default/usr
# Test standard creation, creation of a snapshot, and creation from a # Test standard creation, creation of a snapshot, and creation from a
# snapshot. # snapshot.
atf_check bectl -r ${zpool}/ROOT create -e default default2 atf_check bectl -r ${zpool}/ROOT create -e default default2
atf_check bectl -r ${zpool}/ROOT create default2@test_snap atf_check bectl -r ${zpool}/ROOT create default2@test_snap
atf_check bectl -r ${zpool}/ROOT create -e default2@test_snap default3 atf_check bectl -r ${zpool}/ROOT create -e default2@test_snap default3
# Test standard creation, creation of a snapshot, and creation from a
# snapshot for recursive boot environments.
atf_check bectl -r ${zpool}/ROOT create -r -e default recursive
atf_check bectl -r ${zpool}/ROOT create -r recursive@test_snap
atf_check bectl -r ${zpool}/ROOT create -r -e recursive@test_snap recursive-snap
# Test that non-recursive boot environments have no child datasets.
atf_check -e not-empty -s not-exit:0 \
zfs list "${zpool}/ROOT/default2/usr"
atf_check -e not-empty -s not-exit:0 \
zfs list "${zpool}/ROOT/default3/usr"
# Test that recursive boot environments have child datasets.
atf_check -o not-empty \
zfs list "${zpool}/ROOT/recursive/usr"
atf_check -o not-empty \
zfs list "${zpool}/ROOT/recursive-snap/usr"
} }
bectl_create_cleanup() bectl_create_cleanup()
{ {