Introduce recursive '-r' option for zfs-promote(8)
This patch introduces a new recurse parameter to zfs_promote. The new signature is zfs_promote(zfs_handle_t *, boolean_t). When activating boot environments, it is necessary to recursively promote datasets. External tooling like bectl(8) implement this property locally by wrapping zfs_promote. However, it is also useful to have this option '-r' in upstream zfs-promote(8). Here we push this functionality into libzfs where it can be shared by zfs-promote(8). Signed-off-by: R. Christian McDonald <rcm@rcm.sh> Sponsored by: Rubicon Communications, LLC ("Netgate")
This commit is contained in:
parent
a1771d243a
commit
47972f08f3
|
@ -311,7 +311,7 @@ get_usage(zfs_help_t idx)
|
|||
return (gettext("\tmount\n"
|
||||
"\tmount [-flvO] [-o opts] <-a | filesystem>\n"));
|
||||
case HELP_PROMOTE:
|
||||
return (gettext("\tpromote <clone-filesystem>\n"));
|
||||
return (gettext("\tpromote [-r] <clone-filesystem>\n"));
|
||||
case HELP_RECEIVE:
|
||||
return (gettext("\treceive [-vMnsFhu] "
|
||||
"[-o <property>=<value>] ... [-x <property>] ...\n"
|
||||
|
@ -3869,32 +3869,36 @@ static int
|
|||
zfs_do_promote(int argc, char **argv)
|
||||
{
|
||||
zfs_handle_t *zhp;
|
||||
int ret = 0;
|
||||
int c, ret = 0;
|
||||
boolean_t recursive = B_FALSE;
|
||||
|
||||
/* check options */
|
||||
if (argc > 1 && argv[1][0] == '-') {
|
||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||
argv[1][1]);
|
||||
usage(B_FALSE);
|
||||
while ((c = getopt(argc, argv, "r")) != -1) {
|
||||
switch (c) {
|
||||
case 'r':
|
||||
recursive = B_TRUE;
|
||||
break;
|
||||
default:
|
||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||
optopt);
|
||||
usage(B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* check number of arguments */
|
||||
if (argc < 2) {
|
||||
if (argc < 1) {
|
||||
(void) fprintf(stderr, gettext("missing clone filesystem"
|
||||
" argument\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
if (argc > 2) {
|
||||
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
zhp = zfs_open(g_zfs, argv[1], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
|
||||
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
|
||||
if (zhp == NULL)
|
||||
return (1);
|
||||
|
||||
ret = (zfs_promote(zhp) != 0);
|
||||
|
||||
ret = (zfs_promote(zhp, recursive) != 0);
|
||||
|
||||
zfs_close(zhp);
|
||||
return (ret);
|
||||
|
|
|
@ -817,7 +817,7 @@ _LIBZFS_H int zfs_send_saved(zfs_handle_t *, sendflags_t *, int, const char *);
|
|||
_LIBZFS_H nvlist_t *zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl,
|
||||
const char *token);
|
||||
|
||||
_LIBZFS_H int zfs_promote(zfs_handle_t *);
|
||||
_LIBZFS_H int zfs_promote(zfs_handle_t *, boolean_t);
|
||||
_LIBZFS_H int zfs_hold(zfs_handle_t *, const char *, const char *,
|
||||
boolean_t, int);
|
||||
_LIBZFS_H int zfs_hold_nvl(zfs_handle_t *, int, nvlist_t *);
|
||||
|
|
|
@ -4106,11 +4106,8 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
|
|||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Promotes the given clone fs to be the clone parent.
|
||||
*/
|
||||
int
|
||||
zfs_promote(zfs_handle_t *zhp)
|
||||
static int
|
||||
zfs_promote_impl(zfs_handle_t *zhp)
|
||||
{
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
char snapname[ZFS_MAX_DATASET_NAME_LEN];
|
||||
|
@ -4163,6 +4160,42 @@ zfs_promote(zfs_handle_t *zhp)
|
|||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_promote_recursive_cb(zfs_handle_t *zhp, void *arg)
|
||||
{
|
||||
int err, *ret = (void *)arg;
|
||||
|
||||
/* Bubble up last non-zero error to caller, best we can do */
|
||||
if ((err = zfs_promote_impl(zhp)) != 0)
|
||||
*ret = err;
|
||||
|
||||
return (zfs_iter_filesystems(zhp, zfs_promote_recursive_cb, arg));
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_promote_recursive_impl(zfs_handle_t *zhp)
|
||||
{
|
||||
int err, ret = 0;
|
||||
|
||||
/* Bubble up last non-zero error to caller, best we can do */
|
||||
if ((err = zfs_promote_recursive_cb(zhp, &ret)) != 0)
|
||||
ret = err;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Promotes the given clone fs to be the clone parent.
|
||||
*/
|
||||
int
|
||||
zfs_promote(zfs_handle_t *zhp, boolean_t recurse)
|
||||
{
|
||||
if (recurse)
|
||||
return (zfs_promote_recursive_impl(zhp));
|
||||
|
||||
return (zfs_promote_impl(zhp));
|
||||
}
|
||||
|
||||
typedef struct snapdata {
|
||||
nvlist_t *sd_nvl;
|
||||
const char *sd_snapname;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
.Sh SYNOPSIS
|
||||
.Nm zfs
|
||||
.Cm promote
|
||||
.Op Fl r
|
||||
.Ar clone
|
||||
.
|
||||
.Sh DESCRIPTION
|
||||
|
@ -55,10 +56,15 @@ The space they use moves from the origin dataset to the promoted clone, so
|
|||
enough space must be available to accommodate these snapshots.
|
||||
No new space is consumed by this operation, but the space accounting is
|
||||
adjusted.
|
||||
.Pp
|
||||
The promoted clone must not have any conflicting snapshot names of its own.
|
||||
The
|
||||
.Nm zfs Cm rename
|
||||
subcommand can be used to rename any conflicting snapshots.
|
||||
.Bl -tag -width "-H"
|
||||
.It Fl r
|
||||
Recursively promote all descendent datasets.
|
||||
.El
|
||||
.
|
||||
.Sh EXAMPLES
|
||||
.\" These are, respectively, examples 10 from zfs.8
|
||||
|
|
Loading…
Reference in New Issue