Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
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 |
