aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorUmer Saleem <[email protected]>2023-10-03 04:58:54 +0500
committerBrian Behlendorf <[email protected]>2023-10-03 15:41:46 -0700
commit8015e2ea66b4f6233877fef29a8a35594f33558d (patch)
tree2a9b7133207f5d9138ecac9dec19ccc89a02c409 /lib
parentc53bc3837cb67a36b53ee7b9ae02903dc7b86fdb (diff)
Add '-u' - nomount flag for zfs set
This commit adds '-u' flag for zfs set operation. With this flag, mountpoint, sharenfs and sharesmb properties can be updated without actually mounting or sharing the dataset. Previously, if dataset was unmounted, and mountpoint property was updated, dataset was not mounted after the update. This behavior is changed in #15240. We mount the dataset whenever mountpoint property is updated, regardless if it's mounted or not. To provide the user with option to keep the dataset unmounted and still update the mountpoint without mounting the dataset, '-u' flag can be used. If any of mountpoint, sharenfs or sharesmb properties are updated with '-u' flag, the property is set to desired value but the operation to (re/un)mount and/or (re/un)share the dataset is not performed and dataset remains as it was before. Reviewed-by: Alexander Motin <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Umer Saleem <[email protected]> Closes #15322
Diffstat (limited to 'lib')
-rw-r--r--lib/libzfs/libzfs.abi7
-rw-r--r--lib/libzfs/libzfs_changelist.c27
-rw-r--r--lib/libzfs/libzfs_dataset.c18
3 files changed, 42 insertions, 10 deletions
diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi
index 6e53bcb41..8658d39e2 100644
--- a/lib/libzfs/libzfs.abi
+++ b/lib/libzfs/libzfs.abi
@@ -396,6 +396,7 @@
<elf-symbol name='zfs_prop_readonly' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_prop_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_prop_set_list' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='zfs_prop_set_list_flags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_prop_setonce' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_prop_string_to_index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_prop_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -4424,6 +4425,12 @@
<parameter type-id='5ce45b60' name='props'/>
<return type-id='95e97e5e'/>
</function-decl>
+ <function-decl name='zfs_prop_set_list_flags' mangled-name='zfs_prop_set_list_flags' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_set_list_flags'>
+ <parameter type-id='9200a744' name='zhp'/>
+ <parameter type-id='5ce45b60' name='props'/>
+ <parameter type-id='95e97e5e' name='flags'/>
+ <return type-id='95e97e5e'/>
+ </function-decl>
<function-decl name='zfs_prop_inherit' mangled-name='zfs_prop_inherit' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_inherit'>
<parameter type-id='9200a744' name='zhp'/>
<parameter type-id='80f4b756' name='propname'/>
diff --git a/lib/libzfs/libzfs_changelist.c b/lib/libzfs/libzfs_changelist.c
index efe1c0c06..4db1cbce9 100644
--- a/lib/libzfs/libzfs_changelist.c
+++ b/lib/libzfs/libzfs_changelist.c
@@ -105,6 +105,15 @@ changelist_prefix(prop_changelist_t *clp)
clp->cl_prop != ZFS_PROP_SHARESMB)
return (0);
+ /*
+ * If CL_GATHER_DONT_UNMOUNT is set, don't want to unmount/unshare and
+ * later (re)mount/(re)share the filesystem in postfix phase, so we
+ * return from here. If filesystem is mounted or unmounted, leave it
+ * as it is.
+ */
+ if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
+ return (0);
+
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
return (-1);
@@ -129,8 +138,6 @@ changelist_prefix(prop_changelist_t *clp)
*/
switch (clp->cl_prop) {
case ZFS_PROP_MOUNTPOINT:
- if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
- break;
if (zfs_unmount(cn->cn_handle, NULL,
clp->cl_mflags) != 0) {
ret = -1;
@@ -164,9 +171,8 @@ changelist_prefix(prop_changelist_t *clp)
* reshare the filesystems as necessary. In changelist_gather() we recorded
* whether the filesystem was previously shared or mounted. The action we take
* depends on the previous state, and whether the value was previously 'legacy'.
- * For non-legacy properties, we only remount/reshare the filesystem if it was
- * previously mounted/shared. Otherwise, we always remount/reshare the
- * filesystem.
+ * For non-legacy properties, we always remount/reshare the filesystem,
+ * if CL_GATHER_DONT_UNMOUNT is not set.
*/
int
changelist_postfix(prop_changelist_t *clp)
@@ -178,6 +184,14 @@ changelist_postfix(prop_changelist_t *clp)
boolean_t commit_nfs_shares = B_FALSE;
/*
+ * If CL_GATHER_DONT_UNMOUNT is set, it means we don't want to (un)mount
+ * or (re/un)share the filesystem, so we return from here. If filesystem
+ * is mounted or unmounted, leave it as it is.
+ */
+ if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
+ return (0);
+
+ /*
* If we're changing the mountpoint, attempt to destroy the underlying
* mountpoint. All other datasets will have inherited from this dataset
* (in which case their mountpoints exist in the filesystem in the new
@@ -239,8 +253,7 @@ changelist_postfix(prop_changelist_t *clp)
needs_key = (zfs_prop_get_int(cn->cn_handle,
ZFS_PROP_KEYSTATUS) == ZFS_KEYSTATUS_UNAVAILABLE);
- mounted = (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT) ||
- zfs_is_mounted(cn->cn_handle, NULL);
+ mounted = zfs_is_mounted(cn->cn_handle, NULL);
if (!mounted && !needs_key && (cn->cn_mounted ||
(((clp->cl_prop == ZFS_PROP_MOUNTPOINT &&
diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c
index 11d3eb6a3..727efc5a9 100644
--- a/lib/libzfs/libzfs_dataset.c
+++ b/lib/libzfs/libzfs_dataset.c
@@ -1771,8 +1771,6 @@ error:
return (ret);
}
-
-
/*
* Given an nvlist of property names and values, set the properties for the
* given dataset.
@@ -1780,6 +1778,18 @@ error:
int
zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
{
+ return (zfs_prop_set_list_flags(zhp, props, 0));
+}
+
+/*
+ * Given an nvlist of property names, values and flags, set the properties
+ * for the given dataset. If ZFS_SET_NOMOUNT is set, it allows to update
+ * mountpoint, sharenfs and sharesmb properties without (un/re)mounting
+ * and (un/re)sharing the dataset.
+ */
+int
+zfs_prop_set_list_flags(zfs_handle_t *zhp, nvlist_t *props, int flags)
+{
zfs_cmd_t zc = {"\0"};
int ret = -1;
prop_changelist_t **cls = NULL;
@@ -1848,7 +1858,9 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
if (prop != ZFS_PROP_CANMOUNT ||
(fnvpair_value_uint64(elem) == ZFS_CANMOUNT_OFF &&
zfs_is_mounted(zhp, NULL))) {
- cls[cl_idx] = changelist_gather(zhp, prop, 0, 0);
+ cls[cl_idx] = changelist_gather(zhp, prop,
+ ((flags & ZFS_SET_NOMOUNT) ?
+ CL_GATHER_DONT_UNMOUNT : 0), 0);
if (cls[cl_idx] == NULL)
goto error;
}