aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/bectl/bectl.814
-rw-r--r--sbin/bectl/bectl.c16
-rwxr-xr-xsbin/bectl/tests/bectl_test.sh8
3 files changed, 35 insertions, 3 deletions
diff --git a/sbin/bectl/bectl.8 b/sbin/bectl/bectl.8
index 0e08b3383e9a..7614bea2ddad 100644
--- a/sbin/bectl/bectl.8
+++ b/sbin/bectl/bectl.8
@@ -3,7 +3,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.Dd June 13, 2025
+.Dd February 4, 2026
.Dt BECTL 8
.Os
.Sh NAME
@@ -33,6 +33,11 @@
.Ar beName@snapshot
.Nm
.Op Fl r Ar beroot
+.Cm create
+.Fl E
+.Ar newBeName
+.Nm
+.Op Fl r Ar beroot
.Cm destroy
.Op Fl \&Fo
.Ar beName Ns Op Cm @ Ns Ar snapshot
@@ -181,6 +186,13 @@ for a discussion on different layouts.
.Pp
No new boot environment is created with this subcommand.
.It Xo
+.Cm create
+.Fl E
+.Ar newBeName
+.Xc
+Create a new empty boot environment named
+.Ar newBeName .
+.It Xo
.Cm destroy
.Op Fl \&Fo
.Ar beName Ns Op Cm @ Ns Ar snapshot
diff --git a/sbin/bectl/bectl.c b/sbin/bectl/bectl.c
index 28483dae17b2..7f462984267f 100644
--- a/sbin/bectl/bectl.c
+++ b/sbin/bectl/bectl.c
@@ -53,6 +53,7 @@ usage(bool explicit)
"\tbectl [-r beroot] check\n"
"\tbectl [-r beroot] create [-r] [-e {nonActiveBe | beName@snapshot}] beName\n"
"\tbectl [-r beroot] create [-r] beName@snapshot\n"
+ "\tbectl [-r beroot] create -E beName\n"
"\tbectl [-r beroot] destroy [-Fo] {beName | beName@snapshot}\n"
"\tbectl [-r beroot] export sourceBe\n"
"\tbectl [-r beroot] import targetBe\n"
@@ -184,15 +185,19 @@ bectl_cmd_create(int argc, char *argv[])
char snapshot[BE_MAXPATHLEN];
char *atpos, *bootenv, *snapname;
int err, opt;
- bool recursive;
+ bool empty, recursive;
snapname = NULL;
+ empty = false;
recursive = false;
- while ((opt = getopt(argc, argv, "e:r")) != -1) {
+ while ((opt = getopt(argc, argv, "e:Er")) != -1) {
switch (opt) {
case 'e':
snapname = optarg;
break;
+ case 'E':
+ empty = true;
+ break;
case 'r':
recursive = true;
break;
@@ -221,6 +226,13 @@ bectl_cmd_create(int argc, char *argv[])
*/
*atpos++ = '\0';
err = be_snapshot(be, bootenv, atpos, recursive, NULL);
+ } else if (empty) {
+ if (snapname || recursive) {
+ fprintf(stderr,
+ "bectl create: -E cannot be combined with -e or -r\n");
+ return (usage(false));
+ }
+ err = be_create_empty(be, bootenv);
} else {
if (snapname == NULL)
/* Create from currently booted BE */
diff --git a/sbin/bectl/tests/bectl_test.sh b/sbin/bectl/tests/bectl_test.sh
index 8084b0a173f4..6aa94127aa36 100755
--- a/sbin/bectl/tests/bectl_test.sh
+++ b/sbin/bectl/tests/bectl_test.sh
@@ -126,6 +126,14 @@ bectl_create_body()
zfs list "${zpool}/ROOT/recursive/usr"
atf_check -o not-empty \
zfs list "${zpool}/ROOT/recursive-snap/usr"
+
+ # Test creation of an empty BE.
+ atf_check bectl -r ${zpool}/ROOT create -E empty
+ atf_check -o inline:"-\n" zfs get -H -o value origin ${zpool}/ROOT/empty
+ atf_check -e match:"cannot be combined" -s not-exit:0 \
+ bectl -r ${zpool}/ROOT create -E -e not-allowed empty-existing
+ atf_check -e match:"cannot be combined" -s not-exit:0 \
+ bectl -r ${zpool}/ROOT create -E -r empty-recursive
}
bectl_create_cleanup()
{