changeset 424:a200c18603c9

Further work on "fzfs copy-tree"
author Franz Glasner <fzglas.hg@dom66.de>
date Wed, 20 Sep 2023 09:31:26 +0200
parents 1d6ee78f06ef
children 3ebaa936b2b2
files docs/man/man8/fzfs-copy-tree.rst sbin/fzfs
diffstat 2 files changed, 60 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/docs/man/man8/fzfs-copy-tree.rst	Tue Sep 19 20:23:54 2023 +0200
+++ b/docs/man/man8/fzfs-copy-tree.rst	Wed Sep 20 09:31:26 2023 +0200
@@ -20,6 +20,9 @@
 
 The structure and content of the filesystems is copied.
 
+If `source-dataset` is a snapshot then all child datasets also must
+have a snapshot with the same snapshot name.
+
 `dest-dataset` must not exist already.
 
 By default `canmount` is also copied. But this can be modified with
--- a/sbin/fzfs	Tue Sep 19 20:23:54 2023 +0200
+++ b/sbin/fzfs	Wed Sep 20 09:31:26 2023 +0200
@@ -258,7 +258,13 @@
     local _ds_source _ds_target
     local _opt_mountpoint _opt_mount_noauto _opt_nomount _opt_dry_run
 
-    local _ds_source_base _ds_source_snapshot
+    local _ds_source_base _ds_source_snapshot _snapshot_suffix
+    local _ds_tree _ds _ds_relname
+
+    _opt_mountpoint=""
+    _opt_mount_noauto=""
+    _opt_nomount=""
+    _opt_dry_run=""
 
     while getopts "AM:nu" _opt ; do
         case ${_opt} in
@@ -288,13 +294,63 @@
     [ -z "${_ds_source}" ] && { echo "ERROR: no source given" 1>&2; return 2; }
     [ -z "${_ds_target}" ] && { echo "ERROR: no target name given" 1>&2; return 2; }
 
+    if ! zfs get -H name "${_ds_source}" >/dev/null 2>&1; then
+        echo "ERROR: source dataset does not exist: ${_ds_source}" 1>&2;
+        return 1;
+    fi
+
     _ds_source_base="${_ds_source%@*}"
     _ds_source_snapshot="${_ds_source##*@}"
+    _snapshot_suffix="@${_ds_source_snapshot}"
 
     if [ "${_ds_source_snapshot}" = "${_ds_source_base}" ]; then
         # No snapshot given
+        [ "${_ds_source_base}" = "${_ds_source}" ] || { echo "ERROR:" 1>&2; return 1; }
         _ds_source_snapshot=""
+        _snapshot_suffix=""
     fi
+
+    echo $_ds_source_base
+    echo $_ds_source_snapshot $_snapshot_suffix
+
+    _ds_tree=""
+
+    while IFS=$'\n' read -r _ds; do
+        if [ -z "${_ds_tree}" ]; then
+            _ds_tree="${_ds}"
+        else
+            _ds_tree="${_ds_tree}"$'\n'"${_ds}"
+        fi
+        echo "X: $_ds"
+    done <<EOF20ee7ea0781414fab8c305d3875d15e
+$(zfs list -H -r -t filesystem -o name -s name "${_ds_source_base}")
+EOF20ee7ea0781414fab8c305d3875d15e
+    # Check the existence of all intermediate datasets and their shapshots
+    IFS=$'\n'
+    for _ds in ${_ds_tree}; do
+        if  ! zfs get -H name "${_ds}${_snapshot_suffix}" >/dev/null 2>&1; then
+            echo "ERROR: child dataset does not exist: ${_ds}${_snapshot_suffix}" 1>&2
+            return 1
+        fi
+    done
+    for _ds in ${_ds_tree}; do
+        # Determine the relative name of the dataset
+        _ds_relname="${_ds#${_ds_source_base}}"
+        echo "REL: $_ds  --- $_ds_relname"
+
+        if [ -z "${_ds_relname}" ]; then
+            #
+            # Source root to target root
+            #
+            if [ -z "${_opt_mountpoint}" ]; then
+            else
+            fi
+        else
+            if [ -z "${_opt_mountpoint}" ]; then
+            else
+            fi
+        fi
+    done
 }