changeset 529:703e9f357339

fzfs umount: umounting now also works for datasets and/or mountpoints that have spaces in their values. For this to work textproc/jq must be installed as /usr/local/bin/jq. "mount -p" is requested as JSON (via libxo) processed accordingly. This is because normally "mount -p" has a TAB as field separator -- with the exception of fields becoming to large; the a SPACE is used... "fzfs mount" works already in this cases.
author Franz Glasner <fzglas.hg@dom66.de>
date Wed, 04 Sep 2024 20:52:57 +0200
parents 93b98803219b
children c3db1ec91f02
files sbin/fzfs share/local-bsdtools/common.subr
diffstat 2 files changed, 26 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/sbin/fzfs	Wed Sep 04 18:48:10 2024 +0200
+++ b/sbin/fzfs	Wed Sep 04 20:52:57 2024 +0200
@@ -302,24 +302,37 @@
     OPTIND=1
 
     _dsname="${1-}"
-    [ -z "${_dsname}" ] && { echo "ERROR: no dataset given" 1>&2; return 2; }
+    [ -z "${_dsname}" ] && { err "no dataset given"; return 2; }
 
     # Just determine whether the given dataset name exists
-    _rootds_mountpoint="$(zfs list -H -o mountpoint -t filesystem "${_dsname}")" || { echo "ERROR: dataset not found" 1>&2; return 1; }
+    _rootds_mountpoint="$(zfs list -H -o mountpoint -t filesystem "${_dsname}" 1>/dev/null 2>/dev/null)" || { err "dataset not found"; return 1; }
 
-    /sbin/mount -t zfs -p \
-    | LC_ALL=C GREP_OPTIONS="" /usr/bin/egrep "^${_dsname}(/|\s)" \
-    | /usr/bin/sort -n -r \
-    | {
-        while IFS=' '$'\t' read -r _name _mp _rest ; do
+    if [ -x "${JQ}" ]; then
+        /sbin/mount -t zfs -p --libxo=json,no-locale \
+        | LC_ALL=C "${JQ}" -r $'.mount.fstab.[] | [.device, .mntpoint, .fstype, .opts, .dump, .pass] | @tsv ' \
+        | LC_ALL=C /usr/bin/awk -F $'\\t+' -v OFS=$'\t' -v ds1="${_dsname}" -v ds2="${_dsname}/" $'{ if (($1 == ds1) || (index($1, ds2) == 1)) { print $1, $2; } }' \
+        | LC_ALL=C /usr/bin/sort -t $'\t' -k 1 -r \
+        | while IFS=$'\t' read -r _name _mp ; do
             if checkyes _opt_dry_run ; then
                 echo "Would umount ${_name} from ${_mp}"
             else
                 echo "Umounting ${_name} on ${_mp}"
                 /sbin/umount "${_mp}" || return 1
             fi
-        done
-    }
+          done
+    else
+        /sbin/mount -t zfs -p \
+        | LC_ALL=C GREP_OPTIONS="" /usr/bin/egrep "^${_dsname}(/|\s)" \
+        | LC_ALL=C /usr/bin/sort -n -r \
+        | while IFS=' '$'\t' read -r _name _mp _rest ; do
+            if checkyes _opt_dry_run ; then
+                echo "Would umount ${_name} from ${_mp}"
+            else
+                echo "Umounting ${_name} on ${_mp}"
+                /sbin/umount "${_mp}" || return 1
+            fi
+          done
+    fi
     return 0
 }
 
--- a/share/local-bsdtools/common.subr	Wed Sep 04 18:48:10 2024 +0200
+++ b/share/local-bsdtools/common.subr	Wed Sep 04 20:52:57 2024 +0200
@@ -11,6 +11,10 @@
 #:
 
 
+#: The path to the external jq executable (JSON parser)
+JQ="/usr/local/bin/jq"
+
+
 #:
 #: Display an error message to stderr and exit with given exit code
 #: