comparison sbin/fzfs @ 539:f6dc405ddd58

fzfs: switch to farray.sh
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 09 Sep 2024 15:16:01 +0200
parents 9f8f3e9b3d84
children 566ecdd9e73b
comparison
equal deleted inserted replaced
538:9f8f3e9b3d84 539:f6dc405ddd58
43 ' 43 '
44 44
45 45
46 _p_datadir="$(dirname "$0")"/../share/local-bsdtools 46 _p_datadir="$(dirname "$0")"/../share/local-bsdtools
47 . "${_p_datadir}/common.subr" 47 . "${_p_datadir}/common.subr"
48 . "${_p_datadir}/array.sh" 48 . "${_p_datadir}/farray.sh"
49 49
50 50
51 # 51 #
52 #: Implementation of the "mount" command. 52 #: Implementation of the "mount" command.
53 #: 53 #:
57 local _dsname _mountpoint 57 local _dsname _mountpoint
58 local _opt_dry_run _opt_mount_outside _opt_mount_natural 58 local _opt_dry_run _opt_mount_outside _opt_mount_natural
59 local _opt_mount_children_only _opt_keep 59 local _opt_mount_children_only _opt_keep
60 60
61 local _name _mp _canmount _mounted _rootds_mountpoint _rootds_mountpoint_prefix _relative_mp _real_mp 61 local _name _mp _canmount _mounted _rootds_mountpoint _rootds_mountpoint_prefix _relative_mp _real_mp
62 local _mounted_datasets
62 63
63 _opt_dry_run="" 64 _opt_dry_run=""
64 _opt_keep="" 65 _opt_keep=""
65 _opt_mount_outside="" 66 _opt_mount_outside=""
66 _opt_mount_natural="" 67 _opt_mount_natural=""
134 # 135 #
135 # _mounted_datasets is an array of ZFS datasets that have been 136 # _mounted_datasets is an array of ZFS datasets that have been
136 # mounted by this routine and should be unmounted on errors 137 # mounted by this routine and should be unmounted on errors
137 # -- if possible. 138 # -- if possible.
138 # 139 #
139 array_create _mounted_datasets 140 farray_create _mounted_datasets
140 141
141 while IFS=$'\t' read -r _name _mp _canmount _mounted ; do 142 while IFS=$'\t' read -r _name _mp _canmount _mounted ; do
142 # Skip filesystems that are already mounted 143 # Skip filesystems that are already mounted
143 [ "${_mounted}" = "yes" ] && continue 144 [ "${_mounted}" = "yes" ] && continue
144 # Skip filesystems that must not be mounted 145 # Skip filesystems that must not be mounted
208 else 209 else
209 mkdir -p "${_real_mp}" 1> /dev/null 2> /dev/null || \ 210 mkdir -p "${_real_mp}" 1> /dev/null 2> /dev/null || \
210 { echo "ERROR: cannot create mountpoint ${_real_mp}" >&2; _umount_datasets _mounted_datasets || true; return 1; } 211 { echo "ERROR: cannot create mountpoint ${_real_mp}" >&2; _umount_datasets _mounted_datasets || true; return 1; }
211 echo "Mounting ${_name} on ${_real_mp}" 212 echo "Mounting ${_name} on ${_real_mp}"
212 if /sbin/mount -t zfs "${_name}" "${_real_mp}"; then 213 if /sbin/mount -t zfs "${_name}" "${_real_mp}"; then
213 array_append _mounted_datasets "${_name}" 214 farray_append _mounted_datasets "${_name}"
214 else 215 else
215 if ! checkyes _opt_keep; then 216 if ! checkyes _opt_keep; then
216 _umount_datasets _mounted_datasets || true 217 _umount_datasets _mounted_datasets || true
217 fi 218 fi
218 return 1 219 return 1
224 if [ "${_opt_dry_run}" = "yes" ]; then 225 if [ "${_opt_dry_run}" = "yes" ]; then
225 echo "Would mount ${_name} on configured ZFS dataset mountpoint ${_mp}" 226 echo "Would mount ${_name} on configured ZFS dataset mountpoint ${_mp}"
226 else 227 else
227 echo "Mounting ${_name} on configured ZFS dataset mountpoint ${_mp}" 228 echo "Mounting ${_name} on configured ZFS dataset mountpoint ${_mp}"
228 if zfs mount "${_name}"; then 229 if zfs mount "${_name}"; then
229 array_append _mounted_datasets "${_name}" 230 farray_append _mounted_datasets "${_name}"
230 else 231 else
231 if ! checkyes _opt_keep; then 232 if ! checkyes _opt_keep; then
232 _umount_datasets _mounted_datasets || true 233 _umount_datasets _mounted_datasets || true
233 fi 234 fi
234 return 1 235 return 1
238 echo "Skipping ${_name} because its configured ZFS mountpoint is not relative to given root dataset" 2>&1 239 echo "Skipping ${_name} because its configured ZFS mountpoint is not relative to given root dataset" 2>&1
239 fi 240 fi
240 ;; 241 ;;
241 esac 242 esac
242 done 243 done
243 array_destroy _mounted_datasets 244 farray_destroy _mounted_datasets
244 return 0 245 return 0
245 } 246 }
246 } 247 }
247 248
248 249
257 #: 1 otherwise 258 #: 1 otherwise
258 #: 259 #:
259 #: Unmounting is done in the reverse order. 260 #: Unmounting is done in the reverse order.
260 #: 261 #:
261 _umount_datasets() { 262 _umount_datasets() {
262 array_reversed_for_each "$1" _umount_datasets_umount 263 farray_reversed_for_each "$1" _umount_datasets_umount
263 } 264 }
264 265
265 266
266 #: 267 #:
267 #: Array callback to unmount a single ZFS filesystem 268 #: Array callback to unmount a single ZFS filesystem
487 488
488 local _ds snapshot_name _ds_source_base _ds_relname 489 local _ds snapshot_name _ds_source_base _ds_relname
489 local _ds_canmount _ds_mountpoint 490 local _ds_canmount _ds_mountpoint
490 local _clone_props _arg_canmount _arg_other_clone_props 491 local _clone_props _arg_canmount _arg_other_clone_props
491 local _opt _idx _idx_lp _prop _propval 492 local _opt _idx _idx_lp _prop _propval
493 local _ds_tree _cloned_datasets _local_props
492 494
493 _opt_dry_run="" 495 _opt_dry_run=""
494 _opt_keep="" 496 _opt_keep=""
495 497
496 while getopts "kn" _opt ; do 498 while getopts "kn" _opt ; do
530 if [ "${_ds_source_base}" = "${_snapshot_name}" ]; then 532 if [ "${_ds_source_base}" = "${_snapshot_name}" ]; then
531 err "no snapshot given" 533 err "no snapshot given"
532 return 1 534 return 1
533 fi 535 fi
534 536
535 array_create _ds_tree 537 farray_create _ds_tree
536 538
537 while IFS=$'\n' read -r _ds; do 539 while IFS=$'\n' read -r _ds; do
538 array_append _ds_tree "${_ds}" 540 farray_append _ds_tree "${_ds}"
539 done <<EOF_9ef07253679011efa78174d435fd3892 541 done <<EOF_9ef07253679011efa78174d435fd3892
540 $(zfs list -H -r -t filesystem -o name -s name "${_ds_source_base}") 542 $(zfs list -H -r -t filesystem -o name -s name "${_ds_source_base}")
541 EOF_9ef07253679011efa78174d435fd3892 543 EOF_9ef07253679011efa78174d435fd3892
542 544
543 # Check the existence of all intermediate datasets and their shapshots 545 # Check the existence of all intermediate datasets and their shapshots
544 _idx=1 546 _idx=1
545 while array_tryget _ds _ds_tree ${_idx}; do 547 while farray_tryget _ds _ds_tree ${_idx}; do
546 if ! zfs get -H name "${_ds}@${_snapshot_name}" >/dev/null 2>&1; then 548 if ! zfs get -H name "${_ds}@${_snapshot_name}" >/dev/null 2>&1; then
547 err "child dataset (snapshot) does not exist: ${_ds}@${_snapshot_name}" 1>&2 549 err "child dataset (snapshot) does not exist: ${_ds}@${_snapshot_name}" 1>&2
548 return 1 550 return 1
549 fi 551 fi
550 _idx=$((${_idx} + 1)) 552 _idx=$((${_idx} + 1))
551 done 553 done
552 554
553 array_create _cloned_datasets 555 farray_create _cloned_datasets
554 alist_create _local_props 556 falist_create _local_props
555 557
556 # 558 #
557 # 1. Clone with "safe" canmount settings 559 # 1. Clone with "safe" canmount settings
558 # 560 #
559 561
560 _idx=1 562 _idx=1
561 while array_tryget _ds _ds_tree ${_idx}; do 563 while farray_tryget _ds _ds_tree ${_idx}; do
562 # Determine the relative name of the dataset 564 # Determine the relative name of the dataset
563 _ds_relname="${_ds#${_ds_source_base}}" 565 _ds_relname="${_ds#${_ds_source_base}}"
564 566
565 # Need to determine in *every* case (local, default, received, ...) 567 # Need to determine in *every* case (local, default, received, ...)
566 _ds_canmount="$(zfs get -H -o value canmount "${_ds}")" 568 _ds_canmount="$(zfs get -H -o value canmount "${_ds}")"
567 569
568 alist_clear _local_props 570 falist_clear _local_props
569 while IFS=$'\t' read -r _prop _propval ; do 571 while IFS=$'\t' read -r _prop _propval ; do
570 alist_set _local_props "${_prop}" "${_propval}" 572 falist_set _local_props "${_prop}" "${_propval}"
571 done <<EOF_ce8c76187f33471f8e8c1607ed09c42e 573 done <<EOF_ce8c76187f33471f8e8c1607ed09c42e
572 $(zfs get -H -o property,value -s local,received all "${_ds}") 574 $(zfs get -H -o property,value -s local,received all "${_ds}")
573 EOF_ce8c76187f33471f8e8c1607ed09c42e 575 EOF_ce8c76187f33471f8e8c1607ed09c42e
574 576
575 # 577 #
585 fi 587 fi
586 588
587 # Copy all local props with the exception of canmount and mountpoint 589 # Copy all local props with the exception of canmount and mountpoint
588 _arg_other_clone_props="" 590 _arg_other_clone_props=""
589 _idx_lp=1 591 _idx_lp=1
590 while alist_tryget_key_at_index _prop _local_props ${_idx_lp}; do 592 while falist_tryget_key_at_index _prop _local_props ${_idx_lp}; do
591 if [ "${_prop}" = "mountpoint" ]; then 593 if [ "${_prop}" = "mountpoint" ]; then
592 _idx_lp=$((${_idx_lp} + 1)) 594 _idx_lp=$((${_idx_lp} + 1))
593 continue 595 continue
594 fi 596 fi
595 if [ "${_prop}" = "canmount" ]; then 597 if [ "${_prop}" = "canmount" ]; then
596 _idx_lp=$((${_idx_lp} + 1)) 598 _idx_lp=$((${_idx_lp} + 1))
597 continue 599 continue
598 fi 600 fi
599 alist_tryget_value_at_index _propvalue _local_props ${_idx_lp} 601 falist_tryget_value_at_index _propvalue _local_props ${_idx_lp}
600 _arg_other_clone_props="${_arg_other_clone_props} -o ${_prop}=${_propvalue}" 602 _arg_other_clone_props="${_arg_other_clone_props} -o ${_prop}=${_propvalue}"
601 _idx_lp=$((${_idx_lp} + 1)) 603 _idx_lp=$((${_idx_lp} + 1))
602 done 604 done
603 605
604 if ! checkyes _opt_dry_run; then 606 if ! checkyes _opt_dry_run; then
605 echo "Cloning ${_ds}@${_snapshot_name} into ${_ds_dest}${_ds_relname} with ${_arg_canmount} ${_arg_other_clone_props}" 607 echo "Cloning ${_ds}@${_snapshot_name} into ${_ds_dest}${_ds_relname} with ${_arg_canmount} ${_arg_other_clone_props}"
606 if zfs clone ${_arg_canmount} ${_arg_other_clone_props} "${_ds}@${_snapshot_name}" "${_ds_dest}${_ds_relname}"; then 608 if zfs clone ${_arg_canmount} ${_arg_other_clone_props} "${_ds}@${_snapshot_name}" "${_ds_dest}${_ds_relname}"; then
607 array_append _cloned_datasets "${_ds_dest}${_ds_relname}" 609 farray_append _cloned_datasets "${_ds_dest}${_ds_relname}"
608 else 610 else
609 if ! checkyes _opt_keep; then 611 if ! checkyes _opt_keep; then
610 _destroy_datasets _cloned_datasets || true 612 _destroy_datasets _cloned_datasets || true
611 fi 613 fi
612 return 1 614 return 1
620 # 622 #
621 # 2. Copy property mountpoint for root and inherit for all children; 623 # 2. Copy property mountpoint for root and inherit for all children;
622 # also handle canmount. 624 # also handle canmount.
623 # 625 #
624 _idx=1 626 _idx=1
625 while array_tryget _ds _ds_tree ${_idx}; do 627 while farray_tryget _ds _ds_tree ${_idx}; do
626 # Determine the relative name of the dataset 628 # Determine the relative name of the dataset
627 _ds_relname="${_ds#${_ds_source_base}}" 629 _ds_relname="${_ds#${_ds_source_base}}"
628 630
629 # Need to determine in *every* case (default, local, received, ...) 631 # Need to determine in *every* case (default, local, received, ...)
630 _ds_canmount="$(zfs get -H -o value canmount "${_ds}")" 632 _ds_canmount="$(zfs get -H -o value canmount "${_ds}")"
660 fi 662 fi
661 fi 663 fi
662 fi 664 fi
663 _idx=$((${_idx} + 1)) 665 _idx=$((${_idx} + 1))
664 done 666 done
665 array_destroy _cloned_datasets 667 farray_destroy _cloned_datasets
666 return 0 668 return 0
667 } 669 }
668 670
669 671
670 #: 672 #:
799 #: 1 otherwise 801 #: 1 otherwise
800 #: 802 #:
801 #: Destruction is done in the reverse order. 803 #: Destruction is done in the reverse order.
802 #: 804 #:
803 _destroy_datasets() { 805 _destroy_datasets() {
804 array_reversed_for_each "$1" _destroy_datasets_destroy 806 farray_reversed_for_each "$1" _destroy_datasets_destroy
805 } 807 }
806 808
807 809
808 #: 810 #:
809 #: Array callback to destroy a single ZFS filesystem 811 #: Array callback to destroy a single ZFS filesystem