changeset 578:721737ce1ea0

fzfs: make other "normal" properties an array and use eval with proper escaping. This is needed because -- generally -- a filename to a ZFS encryption key could have spaces in its path.
author Franz Glasner <fzglas.hg@dom66.de>
date Sun, 15 Sep 2024 21:58:33 +0200
parents 8655fadf4b77
children 4fd6be157c70
files sbin/fzfs
diffstat 1 files changed, 9 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/sbin/fzfs	Sun Sep 15 21:57:11 2024 +0200
+++ b/sbin/fzfs	Sun Sep 15 21:58:33 2024 +0200
@@ -493,7 +493,7 @@
 
     local _ds snapshot_name _ds_source_base _ds_relname
     local _ds_canmount _ds_mountpoint
-    local _clone_props _arg_canmount _arg_other_clone_props
+    local _clone_props _arg_canmount _args_other_clone_props
     local _opt _idx _idx_lp _prop _propvalue
     local _ds_tree _cloned_datasets _local_props
 
@@ -562,6 +562,8 @@
     farray_create _cloned_datasets
     _local_props=""
     falist_create _local_props
+    _args_other_clone_props=""
+    farray_create _args_other_clone_props
 
     #
     # 1. Clone with "safe" canmount settings
@@ -595,9 +597,8 @@
         fi
 
         # Copy all local props with the exception of canmount and mountpoint
-        _arg_other_clone_props=""
         _idx_lp=1
-        while falist_tryget_key_at_index _prop _local_props ${_idx_lp}; do
+        while falist_tryget_item_at_index _prop _propvalue _local_props ${_idx_lp}; do
             if [ "${_prop}" = "mountpoint" ]; then
                 _idx_lp=$((${_idx_lp} + 1))
                 continue
@@ -606,14 +607,13 @@
                 _idx_lp=$((${_idx_lp} + 1))
                 continue
             fi
-            falist_tryget_value_at_index _propvalue _local_props ${_idx_lp}
-            _arg_other_clone_props="${_arg_other_clone_props} -o ${_prop}=${_propvalue}"
+            farray_append _args_other_clone_props "-o" "${_prop}"="${_propvalue}"
             _idx_lp=$((${_idx_lp} + 1))
         done
 
         if ! checkyes _opt_dry_run; then
-            echo "Cloning ${_ds}@${_snapshot_name} into ${_ds_dest}${_ds_relname} with ${_arg_canmount} ${_arg_other_clone_props}"
-            if zfs clone ${_arg_canmount} ${_arg_other_clone_props} "${_ds}@${_snapshot_name}" "${_ds_dest}${_ds_relname}"; then
+            echo "Cloning ${_ds}@${_snapshot_name} into ${_ds_dest}${_ds_relname} with ${_arg_canmount} $(farray_print_join_for_eval _args_other_clone_props)"
+            if eval "zfs clone \${_arg_canmount} $(farray_print_join_for_eval _args_other_clone_props) \"\${_ds}@\${_snapshot_name}\" \"\${_ds_dest}\${_ds_relname}\""; then
                 farray_append _cloned_datasets "${_ds_dest}${_ds_relname}"
             else
                 if ! checkyes _opt_keep; then
@@ -622,7 +622,7 @@
                 return 1
             fi
         else
-            echo "Would execute: zfs clone ${_arg_canmount} ${_arg_other_clone_props} '${_ds}@${_snapshot_name}' '${_ds_dest}${_ds_relname}'"
+            echo "Would execute: zfs clone ${_arg_canmount} $(farray_print_join_for_eval _args_other_clone_props) '${_ds}@${_snapshot_name}' '${_ds_dest}${_ds_relname}'"
         fi
         _idx=$((${_idx} + 1))
     done
@@ -673,6 +673,7 @@
         _idx=$((${_idx} + 1))
     done
     farray_destroy _cloned_datasets
+    farray_destroy _args_other_clone_props
     return 0
 }