An attempt at a no-encryption-props flag

Signed-off-by: Rich Ercolani <rincebrain@gmail.com>
This commit is contained in:
Rich Ercolani 2023-09-22 17:51:19 -04:00
parent 8af8d2abb1
commit dbdd2558dc
3 changed files with 48 additions and 14 deletions

View File

@ -4463,11 +4463,12 @@ zfs_do_send(int argc, char **argv)
{"holds", no_argument, NULL, 'h'}, {"holds", no_argument, NULL, 'h'},
{"saved", no_argument, NULL, 'S'}, {"saved", no_argument, NULL, 'S'},
{"exclude", required_argument, NULL, 'X'}, {"exclude", required_argument, NULL, 'X'},
{"props-dropenc", no_argument, NULL, 'C'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
/* check options */ /* check options */
while ((c = getopt_long(argc, argv, ":i:I:RsDpVvnPLeht:cwbd:SX:", while ((c = getopt_long(argc, argv, ":i:I:RsDpVvnPLeht:cwbd:SX:C",
long_options, NULL)) != -1) { long_options, NULL)) != -1) {
switch (c) { switch (c) {
case 'X': case 'X':
@ -4504,6 +4505,9 @@ zfs_do_send(int argc, char **argv)
case 'd': case 'd':
redactbook = optarg; redactbook = optarg;
break; break;
case 'C':
flags.dropenc = B_TRUE;
// fall through
case 'p': case 'p':
flags.props = B_TRUE; flags.props = B_TRUE;
break; break;
@ -4595,6 +4599,14 @@ zfs_do_send(int argc, char **argv)
} }
} }
if (flags.dropenc && flags.raw) {
free(excludes.list);
(void) fprintf(stderr,
gettext("Cannot specify both --raw and "
"--props-dropenc.\n"));
usage(B_FALSE);
}
if ((flags.parsable || flags.progressastitle) && flags.verbosity == 0) if ((flags.parsable || flags.progressastitle) && flags.verbosity == 0)
flags.verbosity = 1; flags.verbosity = 1;

View File

@ -781,6 +781,9 @@ typedef struct sendflags {
/* stream represents a partially received dataset */ /* stream represents a partially received dataset */
boolean_t saved; boolean_t saved;
/* Drop encryption flags for a property send. */
boolean_t dropenc;
} sendflags_t; } sendflags_t;
typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *); typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);

View File

@ -256,6 +256,7 @@ typedef struct send_data {
boolean_t seento; boolean_t seento;
boolean_t holds; /* were holds requested with send -h */ boolean_t holds; /* were holds requested with send -h */
boolean_t props; boolean_t props;
boolean_t dropenc;
/* /*
* The header nvlist is of the following format: * The header nvlist is of the following format:
@ -284,7 +285,8 @@ typedef struct send_data {
} send_data_t; } send_data_t;
static void static void
send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, nvlist_t *nv); send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, boolean_t dropenc,
nvlist_t *nv);
/* /*
* Collect guid, valid props, optionally holds, etc. of a snapshot. * Collect guid, valid props, optionally holds, etc. of a snapshot.
@ -353,7 +355,7 @@ send_iterate_snap(zfs_handle_t *zhp, void *arg)
} }
nvlist_t *nv = fnvlist_alloc(); nvlist_t *nv = fnvlist_alloc();
send_iterate_prop(zhp, sd->backup, nv); send_iterate_prop(zhp, sd->backup, sd->dropenc, nv);
fnvlist_add_nvlist(sd->snapprops, snapname, nv); fnvlist_add_nvlist(sd->snapprops, snapname, nv);
fnvlist_free(nv); fnvlist_free(nv);
@ -373,7 +375,8 @@ send_iterate_snap(zfs_handle_t *zhp, void *arg)
* Collect all valid props from the handle snap into an nvlist. * Collect all valid props from the handle snap into an nvlist.
*/ */
static void static void
send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, nvlist_t *nv) send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, boolean_t dropenc,
nvlist_t *nv)
{ {
nvlist_t *props; nvlist_t *props;
@ -412,6 +415,19 @@ send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, nvlist_t *nv)
if (isspacelimit && zhp->zfs_type == ZFS_TYPE_SNAPSHOT) if (isspacelimit && zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
continue; continue;
boolean_t isencprop = (prop == ZFS_PROP_IVSET_GUID ||
prop == ZFS_PROP_ENCRYPTION ||
prop == ZFS_PROP_KEYLOCATION ||
prop == ZFS_PROP_KEYFORMAT ||
prop == ZFS_PROP_PBKDF2_SALT ||
prop == ZFS_PROP_PBKDF2_ITERS ||
prop == ZFS_PROP_ENCRYPTION_ROOT ||
prop == ZFS_PROP_KEY_GUID ||
prop == ZFS_PROP_KEYSTATUS);
if (isencprop && dropenc)
continue;
const char *source; const char *source;
if (nvlist_lookup_string(propnv, ZPROP_SOURCE, &source) == 0) { if (nvlist_lookup_string(propnv, ZPROP_SOURCE, &source) == 0) {
if (strcmp(source, zhp->zfs_name) != 0 && if (strcmp(source, zhp->zfs_name) != 0 &&
@ -569,10 +585,11 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
/* Iterate over props. */ /* Iterate over props. */
if (sd->props || sd->backup || sd->recursive) { if (sd->props || sd->backup || sd->recursive) {
nv = fnvlist_alloc(); nv = fnvlist_alloc();
send_iterate_prop(zhp, sd->backup, nv); send_iterate_prop(zhp, sd->backup, sd->dropenc, nv);
fnvlist_add_nvlist(nvfs, "props", nv); fnvlist_add_nvlist(nvfs, "props", nv);
} }
if (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF) { if ((zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF) &&
sd->dropenc == B_FALSE) {
boolean_t encroot; boolean_t encroot;
/* Determine if this dataset is an encryption root. */ /* Determine if this dataset is an encryption root. */
@ -681,8 +698,8 @@ static int
gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap, gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
const char *tosnap, boolean_t recursive, boolean_t raw, boolean_t doall, const char *tosnap, boolean_t recursive, boolean_t raw, boolean_t doall,
boolean_t replicate, boolean_t skipmissing, boolean_t verbose, boolean_t replicate, boolean_t skipmissing, boolean_t verbose,
boolean_t backup, boolean_t holds, boolean_t props, nvlist_t **nvlp, boolean_t backup, boolean_t holds, boolean_t props, boolean_t dropenc,
avl_tree_t **avlp) nvlist_t **nvlp, avl_tree_t **avlp)
{ {
zfs_handle_t *zhp; zfs_handle_t *zhp;
send_data_t sd = { 0 }; send_data_t sd = { 0 };
@ -705,6 +722,7 @@ gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
sd.backup = backup; sd.backup = backup;
sd.holds = holds; sd.holds = holds;
sd.props = props; sd.props = props;
sd.dropenc = dropenc;
if ((error = send_iterate_fs(zhp, &sd)) != 0) { if ((error = send_iterate_fs(zhp, &sd)) != 0) {
fnvlist_free(sd.fss); fnvlist_free(sd.fss);
@ -2194,7 +2212,7 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
boolean_t gather_props, boolean_t recursive, boolean_t verbose, boolean_t gather_props, boolean_t recursive, boolean_t verbose,
boolean_t dryrun, boolean_t raw, boolean_t replicate, boolean_t skipmissing, boolean_t dryrun, boolean_t raw, boolean_t replicate, boolean_t skipmissing,
boolean_t backup, boolean_t holds, boolean_t props, boolean_t doall, boolean_t backup, boolean_t holds, boolean_t props, boolean_t doall,
nvlist_t **fssp, avl_tree_t **fsavlp) boolean_t dropenc, nvlist_t **fssp, avl_tree_t **fsavlp)
{ {
int err = 0; int err = 0;
char *packbuf = NULL; char *packbuf = NULL;
@ -2240,7 +2258,8 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
if (gather_nvlist(zhp->zfs_hdl, tofs, if (gather_nvlist(zhp->zfs_hdl, tofs,
from, tosnap, recursive, raw, doall, replicate, skipmissing, from, tosnap, recursive, raw, doall, replicate, skipmissing,
verbose, backup, holds, props, &fss, fsavlp) != 0) { verbose, backup, holds, props, dropenc,
&fss, fsavlp) != 0) {
return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP, return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
errbuf)); errbuf));
} }
@ -2386,7 +2405,7 @@ zfs_send_cb_impl(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
flags->replicate, flags->verbosity > 0, flags->dryrun, flags->replicate, flags->verbosity > 0, flags->dryrun,
flags->raw, flags->replicate, flags->skipmissing, flags->raw, flags->replicate, flags->skipmissing,
flags->backup, flags->holds, flags->props, flags->doall, flags->backup, flags->holds, flags->props, flags->doall,
&fss, &fsavl); flags->dropenc, &fss, &fsavl);
zfs_close(tosnap); zfs_close(tosnap);
if (err != 0) if (err != 0)
goto err_out; goto err_out;
@ -2729,7 +2748,7 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
err = send_prelim_records(zhp, NULL, fd, B_TRUE, B_FALSE, err = send_prelim_records(zhp, NULL, fd, B_TRUE, B_FALSE,
flags->verbosity > 0, flags->dryrun, flags->raw, flags->verbosity > 0, flags->dryrun, flags->raw,
flags->replicate, B_FALSE, flags->backup, flags->holds, flags->replicate, B_FALSE, flags->backup, flags->holds,
flags->props, flags->doall, NULL, NULL); flags->props, flags->doall, flags->dropenc, NULL, NULL);
if (err != 0) if (err != 0)
return (err); return (err);
} }
@ -3524,7 +3543,7 @@ again:
if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL, if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE, B_FALSE, recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE, B_FALSE,
B_FALSE, B_TRUE, &local_nv, &local_avl)) != 0) B_FALSE, B_TRUE, B_FALSE, &local_nv, &local_avl)) != 0)
return (error); return (error);
/* /*
@ -5115,7 +5134,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
*cp = '\0'; *cp = '\0';
if (gather_nvlist(hdl, destsnap, NULL, NULL, B_FALSE, B_TRUE, if (gather_nvlist(hdl, destsnap, NULL, NULL, B_FALSE, B_TRUE,
B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE,
B_TRUE, &local_nv, &local_avl) == 0) { B_TRUE, B_FALSE, &local_nv, &local_avl) == 0) {
*cp = '@'; *cp = '@';
fs = fsavl_find(local_avl, drrb->drr_toguid, NULL); fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
fsavl_destroy(local_avl); fsavl_destroy(local_avl);