Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
comparison sbin/fzfs @ 428:824e88618376
The first version of "fzfs copy-tree" completed
| author | Franz Glasner <hg@dom66.de> |
|---|---|
| date | Thu, 21 Sep 2023 18:42:41 +0200 |
| parents | 7056e5b7712d |
| children | bbdb1ab0ea00 |
comparison
equal
deleted
inserted
replaced
| 427:7056e5b7712d | 428:824e88618376 |
|---|---|
| 258 local _ds_source _ds_target | 258 local _ds_source _ds_target |
| 259 local _opt_mountpoint _opt_mount_noauto _opt_nomount _opt_dry_run | 259 local _opt_mountpoint _opt_mount_noauto _opt_nomount _opt_dry_run |
| 260 | 260 |
| 261 local _ds_source_base _ds_source_snapshot _snapshot_suffix | 261 local _ds_source_base _ds_source_snapshot _snapshot_suffix |
| 262 local _ds_tree _ds _ds_relname _ds_canmount | 262 local _ds_tree _ds _ds_relname _ds_canmount |
| 263 local _rflags | 263 local _arg_canmount _arg_mp1 _arg_mp2 |
| 264 | 264 |
| 265 _opt_mountpoint="" | 265 _opt_mountpoint="" |
| 266 _opt_mount_noauto="" | 266 _opt_mount_noauto="" |
| 267 _opt_nomount="" | 267 _opt_nomount="" |
| 268 _opt_dry_run="" | 268 _opt_dry_run="" |
| 295 [ -z "${_ds_source}" ] && { echo "ERROR: no source given" 1>&2; return 2; } | 295 [ -z "${_ds_source}" ] && { echo "ERROR: no source given" 1>&2; return 2; } |
| 296 [ -z "${_ds_target}" ] && { echo "ERROR: no target name given" 1>&2; return 2; } | 296 [ -z "${_ds_target}" ] && { echo "ERROR: no target name given" 1>&2; return 2; } |
| 297 | 297 |
| 298 if ! zfs get -H name "${_ds_source}" >/dev/null 2>&1; then | 298 if ! zfs get -H name "${_ds_source}" >/dev/null 2>&1; then |
| 299 echo "ERROR: source dataset does not exist: ${_ds_source}" 1>&2; | 299 echo "ERROR: source dataset does not exist: ${_ds_source}" 1>&2; |
| 300 return 1; | |
| 301 fi | |
| 302 if zfs get -H name "${_ds_target}" >/dev/null 2>&1; then | |
| 303 echo "ERROR: target dataset already exists: ${_ds_target}" 1>&2; | |
| 300 return 1; | 304 return 1; |
| 301 fi | 305 fi |
| 302 | 306 |
| 303 _ds_source_base="${_ds_source%@*}" | 307 _ds_source_base="${_ds_source%@*}" |
| 304 _ds_source_snapshot="${_ds_source##*@}" | 308 _ds_source_snapshot="${_ds_source##*@}" |
| 309 [ "${_ds_source_base}" = "${_ds_source}" ] || { echo "ERROR:" 1>&2; return 1; } | 313 [ "${_ds_source_base}" = "${_ds_source}" ] || { echo "ERROR:" 1>&2; return 1; } |
| 310 _ds_source_snapshot="" | 314 _ds_source_snapshot="" |
| 311 _snapshot_suffix="" | 315 _snapshot_suffix="" |
| 312 fi | 316 fi |
| 313 | 317 |
| 314 echo $_ds_source_base | |
| 315 echo $_ds_source_snapshot $_snapshot_suffix | |
| 316 | |
| 317 _ds_tree="" | 318 _ds_tree="" |
| 318 | 319 |
| 319 while IFS=$'\n' read -r _ds; do | 320 while IFS=$'\n' read -r _ds; do |
| 320 if [ -z "${_ds_tree}" ]; then | 321 if [ -z "${_ds_tree}" ]; then |
| 321 _ds_tree="${_ds}" | 322 _ds_tree="${_ds}" |
| 322 else | 323 else |
| 323 _ds_tree="${_ds_tree}"$'\n'"${_ds}" | 324 _ds_tree="${_ds_tree}"$'\n'"${_ds}" |
| 324 fi | 325 fi |
| 325 echo "X: $_ds" | |
| 326 done <<EOF20ee7ea0781414fab8c305d3875d15e | 326 done <<EOF20ee7ea0781414fab8c305d3875d15e |
| 327 $(zfs list -H -r -t filesystem -o name -s name "${_ds_source_base}") | 327 $(zfs list -H -r -t filesystem -o name -s name "${_ds_source_base}") |
| 328 EOF20ee7ea0781414fab8c305d3875d15e | 328 EOF20ee7ea0781414fab8c305d3875d15e |
| 329 # Check the existence of all intermediate datasets and their shapshots | 329 # Check the existence of all intermediate datasets and their shapshots |
| 330 IFS=$'\n' | 330 IFS=$'\n' |
| 332 if ! zfs get -H name "${_ds}${_snapshot_suffix}" >/dev/null 2>&1; then | 332 if ! zfs get -H name "${_ds}${_snapshot_suffix}" >/dev/null 2>&1; then |
| 333 echo "ERROR: child dataset does not exist: ${_ds}${_snapshot_suffix}" 1>&2 | 333 echo "ERROR: child dataset does not exist: ${_ds}${_snapshot_suffix}" 1>&2 |
| 334 return 1 | 334 return 1 |
| 335 fi | 335 fi |
| 336 done | 336 done |
| 337 IFS=$'\n' | |
| 337 for _ds in ${_ds_tree}; do | 338 for _ds in ${_ds_tree}; do |
| 339 # Reset IFS | |
| 340 IFS=$' \t\n' | |
| 341 | |
| 338 # Determine the relative name of the dataset | 342 # Determine the relative name of the dataset |
| 339 _ds_relname="${_ds#${_ds_source_base}}" | 343 _ds_relname="${_ds#${_ds_source_base}}" |
| 340 | 344 |
| 341 _ds_canmount=$(zfs get -H -o value canmount "${_ds}") | 345 _ds_canmount=$(zfs get -H -o value canmount "${_ds}") |
| 342 echo "REL: $_ds --- $_ds_relname --- $_ds_canmount" | |
| 343 | |
| 344 _rflags="" | |
| 345 | 346 |
| 346 if [ "${_ds_canmount}" = "off" ]; then | 347 if [ "${_ds_canmount}" = "off" ]; then |
| 347 _rflags="-o canmount=off" | 348 _arg_canmount="-o canmount=off" |
| 348 else | 349 else |
| 349 _rflags="${_opt_mount_noauto}" | 350 _arg_canmount="${_opt_mount_noauto}" |
| 350 fi | 351 fi |
| 351 | 352 |
| 352 if [ -z "${_ds_relname}" ]; then | 353 if [ -z "${_ds_relname}" ]; then |
| 353 # | 354 # |
| 354 # Source root to target root | 355 # Source root to target root |
| 355 # | 356 # |
| 356 if [ -z "${_opt_mountpoint}" ]; then | 357 if [ -z "${_opt_mountpoint}" ]; then |
| 357 _rflags="${_rflags} -x mountpoint" | 358 _arg_mp1=-x |
| 359 _arg_mp2=mountpoint | |
| 358 else | 360 else |
| 359 _rflags="${_rflags} -o mountpoint='${_opt_mountpoint}'" | 361 _arg_mp1=-o |
| 362 _arg_mp2="mountpoint=${_opt_mountpoint}" | |
| 360 fi | 363 fi |
| 361 else | 364 else |
| 362 _rflags="${_rflags} -x mountpoint" | 365 _arg_mp1=-x |
| 363 fi | 366 _arg_mp2=mountpoint |
| 364 echo "zfs send -Lec -p -v '${_ds}${_ds_source_snapshot}' | zfs receive -v ${_opt_nomount} ${_rflags} '${_ds_target}${_ds_relname}'" | 367 fi |
| 368 if [ -z "${_opt_dry_run}" ]; then | |
| 369 zfs send -Lec -p -v "${_ds}${_snapshot_suffix}" | zfs receive -v ${_opt_nomount} ${_arg_canmount} ${_arg_mp1} "${_arg_mp2}" "${_ds_target}${_ds_relname}" | |
| 370 else | |
| 371 echo "Would execute: zfs send -Lec -p -v '${_ds}${_snapshot_suffix}' | zfs receive -v ${_opt_nomount} ${_arg_canmount} ${_arg_mp1} '${_arg_mp2}' '${_ds_target}${_ds_relname}'" | |
| 372 fi | |
| 373 # for the loop | |
| 374 IFS=$'\n' | |
| 365 done | 375 done |
| 376 # Reset to default | |
| 377 IFS=$' \t\n' | |
| 378 # Remove received snapshots | |
| 379 if [ -n "${_ds_source_snapshot}" ]; then | |
| 380 if [ -z "${_opt_dry_run}" ]; then | |
| 381 zfs destroy -rv "${_ds_target}${_snapshot_suffix}" | |
| 382 else | |
| 383 echo "Would execute: zfs destroy -rv '${_ds_target}${_snapshot_suffix}'" | |
| 384 fi | |
| 385 fi | |
| 366 } | 386 } |
| 367 | 387 |
| 368 | 388 |
| 369 #: | 389 #: |
| 370 #: Implement the "create-tree" command | 390 #: Implement the "create-tree" command |
