# HG changeset patch # User Franz Glasner # Date 1695195086 -7200 # Node ID a200c18603c93b3d8eea497f04d0e7b4c26f30a8 # Parent 1d6ee78f06efed1363d8c36625243c008c37a0c3 Further work on "fzfs copy-tree" diff -r 1d6ee78f06ef -r a200c18603c9 docs/man/man8/fzfs-copy-tree.rst --- 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 diff -r 1d6ee78f06ef -r a200c18603c9 sbin/fzfs --- 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 </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 }