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"
|
return (gettext("\tmount\n"
|
||||||
"\tmount [-flvO] [-o opts] <-a | filesystem>\n"));
|
"\tmount [-flvO] [-o opts] <-a | filesystem>\n"));
|
||||||
case HELP_PROMOTE:
|
case HELP_PROMOTE:
|
||||||
return (gettext("\tpromote <clone-filesystem>\n"));
|
return (gettext("\tpromote [-r] <clone-filesystem>\n"));
|
||||||
case HELP_RECEIVE:
|
case HELP_RECEIVE:
|
||||||
return (gettext("\treceive [-vMnsFhu] "
|
return (gettext("\treceive [-vMnsFhu] "
|
||||||
"[-o <property>=<value>] ... [-x <property>] ...\n"
|
"[-o <property>=<value>] ... [-x <property>] ...\n"
|
||||||
|
@ -3869,32 +3869,36 @@ static int
|
||||||
zfs_do_promote(int argc, char **argv)
|
zfs_do_promote(int argc, char **argv)
|
||||||
{
|
{
|
||||||
zfs_handle_t *zhp;
|
zfs_handle_t *zhp;
|
||||||
int ret = 0;
|
int c, ret = 0;
|
||||||
|
boolean_t recursive = B_FALSE;
|
||||||
|
|
||||||
/* check options */
|
while ((c = getopt(argc, argv, "r")) != -1) {
|
||||||
if (argc > 1 && argv[1][0] == '-') {
|
switch (c) {
|
||||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
case 'r':
|
||||||
argv[1][1]);
|
recursive = B_TRUE;
|
||||||
usage(B_FALSE);
|
break;
|
||||||
|
default:
|
||||||
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
|
optopt);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
/* check number of arguments */
|
/* check number of arguments */
|
||||||
if (argc < 2) {
|
if (argc < 1) {
|
||||||
(void) fprintf(stderr, gettext("missing clone filesystem"
|
(void) fprintf(stderr, gettext("missing clone filesystem"
|
||||||
" argument\n"));
|
" argument\n"));
|
||||||
usage(B_FALSE);
|
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)
|
if (zhp == NULL)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
ret = (zfs_promote(zhp) != 0);
|
ret = (zfs_promote(zhp, recursive) != 0);
|
||||||
|
|
||||||
|
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
return (ret);
|
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,
|
_LIBZFS_H nvlist_t *zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl,
|
||||||
const char *token);
|
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 *,
|
_LIBZFS_H int zfs_hold(zfs_handle_t *, const char *, const char *,
|
||||||
boolean_t, int);
|
boolean_t, int);
|
||||||
_LIBZFS_H int zfs_hold_nvl(zfs_handle_t *, int, nvlist_t *);
|
_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);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int
|
||||||
* Promotes the given clone fs to be the clone parent.
|
zfs_promote_impl(zfs_handle_t *zhp)
|
||||||
*/
|
|
||||||
int
|
|
||||||
zfs_promote(zfs_handle_t *zhp)
|
|
||||||
{
|
{
|
||||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||||
char snapname[ZFS_MAX_DATASET_NAME_LEN];
|
char snapname[ZFS_MAX_DATASET_NAME_LEN];
|
||||||
|
@ -4163,6 +4160,42 @@ zfs_promote(zfs_handle_t *zhp)
|
||||||
return (ret);
|
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 {
|
typedef struct snapdata {
|
||||||
nvlist_t *sd_nvl;
|
nvlist_t *sd_nvl;
|
||||||
const char *sd_snapname;
|
const char *sd_snapname;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm promote
|
.Cm promote
|
||||||
|
.Op Fl r
|
||||||
.Ar clone
|
.Ar clone
|
||||||
.
|
.
|
||||||
.Sh DESCRIPTION
|
.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.
|
enough space must be available to accommodate these snapshots.
|
||||||
No new space is consumed by this operation, but the space accounting is
|
No new space is consumed by this operation, but the space accounting is
|
||||||
adjusted.
|
adjusted.
|
||||||
|
.Pp
|
||||||
The promoted clone must not have any conflicting snapshot names of its own.
|
The promoted clone must not have any conflicting snapshot names of its own.
|
||||||
The
|
The
|
||||||
.Nm zfs Cm rename
|
.Nm zfs Cm rename
|
||||||
subcommand can be used to rename any conflicting snapshots.
|
subcommand can be used to rename any conflicting snapshots.
|
||||||
|
.Bl -tag -width "-H"
|
||||||
|
.It Fl r
|
||||||
|
Recursively promote all descendent datasets.
|
||||||
|
.El
|
||||||
.
|
.
|
||||||
.Sh EXAMPLES
|
.Sh EXAMPLES
|
||||||
.\" These are, respectively, examples 10 from zfs.8
|
.\" These are, respectively, examples 10 from zfs.8
|
||||||
|
|
Loading…
Reference in New Issue