Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
comparison sbin/fjail @ 276:3c24b07240f2
Move the implementation of "mount" and "umount" into the new tool fzfs.
It is not jail-specific but in reality a helper for some ZFS management
issues.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sat, 17 Sep 2022 16:47:32 +0200 |
| parents | 95a81116471a |
| children | 90fa5b68bb62 |
comparison
equal
deleted
inserted
replaced
| 275:5bb4c4044e48 | 276:3c24b07240f2 |
|---|---|
| 39 -s Also create a dataset for freebsd-update data files | 39 -s Also create a dataset for freebsd-update data files |
| 40 -t Create a more tiny set of datasets | 40 -t Create a more tiny set of datasets |
| 41 -T Create only an extra tiny set of datasets | 41 -T Create only an extra tiny set of datasets |
| 42 -u Do not automatically mount newly created datasets | 42 -u Do not automatically mount newly created datasets |
| 43 | 43 |
| 44 mount [-O] [-u] [-n] DATASET [MOUNTPOINT] | 44 mount |
| 45 | 45 |
| 46 Mount the ZFS dataset DATASET and all its children to mountpoint | 46 See sibling tool `fzfs'"'"' |
| 47 MOUNTPOINT | 47 |
| 48 | 48 umount |
| 49 -O Also mount datasets at mountpoints outside of their "natural" | 49 |
| 50 and inherited mountpoints | 50 See sibling tool `fzfs'"'"' |
| 51 -N Mount at their "natural" configured ZFS mountpoints (MOUNTPOINT is not required) | |
| 52 -P Do not mount the given prent DATASET but only its children | |
| 53 -n Do not really mount but show what would be mounted where | |
| 54 -u Alias of -n | |
| 55 | |
| 56 umount DATASET | |
| 57 | |
| 58 Unmount the mounted DATASET and all its children | |
| 59 | 51 |
| 60 privs MOUNTPOINT | 52 privs MOUNTPOINT |
| 61 | 53 |
| 62 Adjust some Unix privileges to mounted jail datasets | 54 Adjust some Unix privileges to mounted jail datasets |
| 63 | 55 |
| 488 zfs send -R ${_zfscopyopts} "${_source}" | zfs receive ${_zfsopts} "${_dest}" || { echo "ERROR: ZFS operation failed" >&2; return 1; } | 480 zfs send -R ${_zfscopyopts} "${_source}" | zfs receive ${_zfsopts} "${_dest}" || { echo "ERROR: ZFS operation failed" >&2; return 1; } |
| 489 } | 481 } |
| 490 | 482 |
| 491 | 483 |
| 492 # | 484 # |
| 493 # "mount" -- recursively mount a dataset including subordinate datasets | |
| 494 # | |
| 495 # command_mount dataset mountpoint | |
| 496 # | |
| 497 command_mount() { | |
| 498 local _dsname _mountpoint | |
| 499 local _name _mp _canmount _mounted | |
| 500 local _rootds_mountpoint _relative_mp _real_mp | |
| 501 local _dry_run _mount_outside _mount_natural _mount_children_only | |
| 502 | |
| 503 _dry_run="" | |
| 504 _mount_outside="" | |
| 505 _mount_natural="" | |
| 506 _mount_children_only="" | |
| 507 while getopts "ONPnu" _opt ; do | |
| 508 case ${_opt} in | |
| 509 O) | |
| 510 _mount_outside="yes" | |
| 511 ;; | |
| 512 N) | |
| 513 _mount_natural="yes" | |
| 514 ;; | |
| 515 P) | |
| 516 _mount_children_only="yes" | |
| 517 ;; | |
| 518 n|u) | |
| 519 _dry_run="yes" | |
| 520 ;; | |
| 521 \?|:) | |
| 522 return 2; | |
| 523 ;; | |
| 524 esac | |
| 525 done | |
| 526 shift $((OPTIND-1)) | |
| 527 OPTIND=1 | |
| 528 | |
| 529 _dsname="${1-}" | |
| 530 _mountpoint="${2-}" | |
| 531 | |
| 532 if [ -z "${_dsname}" ]; then | |
| 533 echo "ERROR: no dataset given" >&2 | |
| 534 return 2 | |
| 535 fi | |
| 536 | |
| 537 _rootds_mountpoint="$(zfs list -H -o mountpoint -t filesystem "${_dsname}")" || \ | |
| 538 { echo "ERROR: root dataset does not exist" >&2; return 1; } | |
| 539 | |
| 540 if [ -z "${_mountpoint}" ]; then | |
| 541 if [ "${_mount_natural}" = "yes" ]; then | |
| 542 _mountpoint="${_rootds_mountpoint}" | |
| 543 else | |
| 544 echo "ERROR: no mountpoint given" >&2 | |
| 545 return 2 | |
| 546 fi | |
| 547 else | |
| 548 if [ "${_mount_natural}" = "yes" ]; then | |
| 549 echo "ERROR: Cannot have a custom mountpoint when \"-O\" is given" >&2 | |
| 550 return 2 | |
| 551 fi | |
| 552 fi | |
| 553 | |
| 554 # Eventually remove a trailing slash | |
| 555 _mountpoint="${_mountpoint%/}" | |
| 556 if [ -z "${_mountpoint}" ]; then | |
| 557 echo "ERROR: would mount over the root filesystem" >&2 | |
| 558 return 1 | |
| 559 fi | |
| 560 | |
| 561 zfs list -H -o name,mountpoint,canmount,mounted -s mountpoint -t filesystem -r "${_dsname}" \ | |
| 562 | { | |
| 563 while IFS=$'\t' read -r _name _mp _canmount _mounted ; do | |
| 564 # Skip filesystems that are already mounted | |
| 565 [ "${_mounted}" = "yes" ] && continue | |
| 566 # Skip filesystems that must not be mounted | |
| 567 [ "${_canmount}" = "off" ] && continue | |
| 568 # Mount only the children and skip the given dataset it required | |
| 569 [ \( "${_mount_children_only}" = "yes" \) -a \( "${_name}" = "${_dsname}" \) ] && continue | |
| 570 case "${_mp}" in | |
| 571 "none"|"legacy") | |
| 572 # Do nothing for filesystem with unset or legacy mountpoints | |
| 573 ;; | |
| 574 "${_rootds_mountpoint}"|"${_rootds_mountpoint}/"*) | |
| 575 # | |
| 576 # Handle only mountpoints that have a mountpoint below | |
| 577 # the parent datasets mountpoint | |
| 578 # | |
| 579 | |
| 580 # Determine the mountpoint relative to the parent mountpoint | |
| 581 _relative_mp="${_mp#${_rootds_mountpoint}}" | |
| 582 # Eventually remove a trailing slash | |
| 583 _relative_mp="${_relative_mp%/}" | |
| 584 # The real effective full mountpoint | |
| 585 _real_mp="${_mountpoint}${_relative_mp}" | |
| 586 | |
| 587 # | |
| 588 # Consistency and sanity check: computed real mountpoint must | |
| 589 # be equal to the configured mountpoint when no custom mountpoint | |
| 590 # is given. | |
| 591 # | |
| 592 if [ "${_mount_natural}" = "yes" ]; then | |
| 593 if [ "${_real_mp}" != "${_mp}" ]; then | |
| 594 echo "ERROR: mountpoint mismatch" >&2 | |
| 595 return 1 | |
| 596 fi | |
| 597 fi | |
| 598 | |
| 599 if [ "${_dry_run}" = "yes" ]; then | |
| 600 echo "Would mount ${_name} on ${_real_mp}" | |
| 601 else | |
| 602 mkdir -p "${_real_mp}" 1> /dev/null 2> /dev/null || \ | |
| 603 { echo "ERROR: cannot create mountpoint ${_real_mp}" >&2; return 1; } | |
| 604 echo "Mounting ${_name} on ${_real_mp}" | |
| 605 mount -t zfs "${_name}" "${_real_mp}" || return 1 | |
| 606 fi | |
| 607 ;; | |
| 608 *) | |
| 609 if [ "${_mount_outside}" = "yes" ]; then | |
| 610 if [ "${_dry_run}" = "yes" ]; then | |
| 611 echo "Would mount ${_name} on configured ZFS dataset mountpoint ${_mp}" | |
| 612 else | |
| 613 echo "Mounting ${_name} on configured ZFS dataset mountpoint ${_mp}" | |
| 614 zfs mount "${_name}" || return 1 | |
| 615 fi | |
| 616 else | |
| 617 echo "Skipping ${_name} because its configured ZFS mountpoint is not relative to given root dataset" 2>&1 | |
| 618 fi | |
| 619 ;; | |
| 620 esac | |
| 621 done | |
| 622 | |
| 623 return 0 | |
| 624 } | |
| 625 } | |
| 626 | |
| 627 | |
| 628 # | |
| 629 # "umount" -- Recursively unmount ZFS datasets | |
| 630 # | |
| 631 # command_umount dataset | |
| 632 # | |
| 633 command_umount() { | |
| 634 local _dsname | |
| 635 local _name _mp _rest | |
| 636 local _rootds_mountpoint | |
| 637 | |
| 638 _dsname="${1-}" | |
| 639 [ -z "${_dsname}" ] && \ | |
| 640 { echo "ERROR: no dataset given" >&2; return 2; } | |
| 641 | |
| 642 # Just determine whether the given dataset name exists | |
| 643 _rootds_mountpoint="$(zfs list -H -o mountpoint -t filesystem "${_dsname}")" || { echo "ERROR: dataset not found" >&2; return 1; } | |
| 644 | |
| 645 mount -t zfs -p \ | |
| 646 | grep -E "^${_dsname}(/|\s)" \ | |
| 647 | sort -n -r \ | |
| 648 | { | |
| 649 while IFS=' '$'\t' read -r _name _mp _rest ; do | |
| 650 echo "Umounting ${_name} on ${_mp}" | |
| 651 umount "${_mp}" || return 1 | |
| 652 done | |
| 653 return 0 | |
| 654 } | |
| 655 } | |
| 656 | |
| 657 | |
| 658 # | |
| 659 # "privs" -- adjust privileges | 485 # "privs" -- adjust privileges |
| 660 # | 486 # |
| 661 # To be used when all ZFS datasets are mounted. | 487 # To be used when all ZFS datasets are mounted. |
| 662 # | 488 # |
| 663 command_privs() { | 489 command_privs() { |
| 739 case "${command}" in | 565 case "${command}" in |
| 740 datasets) | 566 datasets) |
| 741 command_datasets "$@" | 567 command_datasets "$@" |
| 742 ;; | 568 ;; |
| 743 mount) | 569 mount) |
| 744 command_mount "$@" | 570 exec "$(dirname $0)/fzfs" mount "$@" |
| 745 ;; | 571 ;; |
| 746 umount|unmount) | 572 umount|unmount) |
| 747 command_umount "$@" | 573 exec "$(dirname $0)/fzfs" umount "$@" |
| 748 ;; | 574 ;; |
| 749 privs) | 575 privs) |
| 750 command_privs "$@" | 576 command_privs "$@" |
| 751 ;; | 577 ;; |
| 752 populate) | 578 populate) |
