diff options
author | Rich Ercolani <[email protected]> | 2021-10-29 18:38:10 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2021-10-29 15:38:10 -0700 |
commit | 4476ccd906a3ee32af4741b9b0b58241739e3c7d (patch) | |
tree | 71b7bb3012d9f16e1df95def3307e3de2588499d /lib/libzfs | |
parent | adeccfea177ee674913a87d95ddacbd699ed1c67 (diff) |
Normalize property names for zfs receive
It turns out, userland is much more happy with aliased property
names than the kernel is.
So let's normalize those to the expected names before we pass
them off.
Added a test case hacked up from the other recv -o/-x test that fails
on unpatched git and passes here.
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Rich Ercolani <[email protected]>
Closes #12607
Closes #12609
Diffstat (limited to 'lib/libzfs')
-rw-r--r-- | lib/libzfs/libzfs_sendrecv.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index e95f28088..a3e3ad21c 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -3958,6 +3958,19 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type, const char *name = nvpair_name(nvp); zfs_prop_t prop = zfs_name_to_prop(name); + /* + * It turns out, if we don't normalize "aliased" names + * e.g. compress= against the "real" names (e.g. compression) + * here, then setting/excluding them does not work as + * intended. + * + * But since user-defined properties wouldn't have a valid + * mapping here, we do this conditional dance. + */ + const char *newname = name; + if (prop >= ZFS_PROP_TYPE) + newname = zfs_prop_to_name(prop); + /* "origin" is processed separately, don't handle it here */ if (prop == ZFS_PROP_ORIGIN) continue; @@ -4004,11 +4017,12 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type, * locally-set, in which case its value will take * priority over the received anyway. */ - if (nvlist_exists(origprops, name)) { + if (nvlist_exists(origprops, newname)) { nvlist_t *attrs; char *source = NULL; - attrs = fnvlist_lookup_nvlist(origprops, name); + attrs = fnvlist_lookup_nvlist(origprops, + newname); if (nvlist_lookup_string(attrs, ZPROP_SOURCE, &source) == 0 && strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0) @@ -4021,10 +4035,10 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type, */ if (!zfs_prop_inheritable(prop) && !zfs_prop_user(name) && /* can be inherited too */ - nvlist_exists(recvprops, name)) - fnvlist_remove(recvprops, name); + nvlist_exists(recvprops, newname)) + fnvlist_remove(recvprops, newname); else - fnvlist_add_nvpair(*oxprops, nvp); + fnvlist_add_boolean(*oxprops, newname); break; case DATA_TYPE_STRING: /* -o property=value */ /* @@ -4045,7 +4059,8 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type, ret = zfs_error(hdl, EZFS_BADPROP, errbuf); goto error; } - fnvlist_add_nvpair(oprops, nvp); + fnvlist_add_string(oprops, newname, + fnvpair_value_string(nvp)); break; default: zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, |