changeset 626:be8dce486af6

common.subr: Implement _get_zfs_mounts_for_dataset_tree() to search for current mounts of a given ZFS dataset and its children
author Franz Glasner <fzglas.hg@dom66.de>
date Tue, 24 Sep 2024 18:17:50 +0200
parents 69d557d67842
children b1e26b956041
files share/local-bsdtools/common.subr
diffstat 1 files changed, 62 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/share/local-bsdtools/common.subr	Tue Sep 24 14:38:46 2024 +0200
+++ b/share/local-bsdtools/common.subr	Tue Sep 24 18:17:50 2024 +0200
@@ -349,6 +349,68 @@
 
 
 #:
+#: Search for current mounts of a given ZFS dataset and its children.
+#:
+#: Only ZFS mounts are considered. Any returned datasets are just
+#: the given mounted dataset or its mounted children.
+#:
+#: The output is sorted by the mountpoint.
+#:
+#: Args:
+#:   $1 (str): The dataset the to check for.
+#:             The dataset and its children are searched for.
+#:
+#: Other Parameters:
+#:   -r (optional): If given the the output is sorted in reverse order.
+#:
+#: Output (stdout):
+#:   The sorted list (lines) of mounts in :manpage:`fstab(5)` format.
+#:   This list may be empty.
+#:   The fields are separated by a single TAB character always.
+#:
+#: Exit:
+#:   1: on fatal errors (usage et al.)
+#:
+_get_zfs_mounts_for_dataset_tree() {
+    local _dsname
+    local _opt_reversed
+
+    local _opt _fstab
+
+    _opt_reversed=""
+    while getopts "r" _opt ; do
+        case ${_opt} in
+            r)
+                _opt_reversed="--reverse"
+                ;;
+            \?)
+                fatal 2 "invalid option given"
+                ;;
+        esac
+    done
+    shift $((OPTIND-1))
+    OPTIND=1
+
+    _dsname="${1-}"
+    [ -z "${_dsname}" ] && fatal 2 "no dataset given"
+
+    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, $3, $4, $5, $6; } }' \
+        | LC_ALL=C /usr/bin/sort --field-separator=$'\t' --key=2 ${_opt_reversed}
+    else
+        # Check for unexpected spaces
+        if ! check_for_proper_fstab; then
+            fatal 1 "Unexpected spaces in fstab. Please install \`${JQ}'."
+        fi
+        _fstab="$(/sbin/mount -t zfs -p | LC_ALL=C awk -v OFS=$'\t' -v ds1="${_dsname}" -v ds2="${_dsname}/" $'{ if (($1 == ds1) || (index($1, ds2) == 1)) { print $1, $2, $3, $4, $5, $6; } }' | LC_ALL=C /usr/bin/sort --field-separator=$'\t' --key=2 ${_opt_reversed})"
+        printf '%s' "${_fstab}"
+    fi
+}
+
+
+#:
 #: Search for mounts and sub-mounts at a given directory.
 #:
 #: The output is sorted by the mountpoint.