Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
comparison sbin/fjail @ 194:379d3178f3ce
mount and umount support for ZFS datasets: recursively mount and unmount
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sun, 21 Aug 2022 08:35:18 +0200 |
| parents | 62a24dfb238c |
| children | 4a0cb73945a8 |
comparison
equal
deleted
inserted
replaced
| 193:62a24dfb238c | 194:379d3178f3ce |
|---|---|
| 36 | 36 |
| 37 -s Also create a dataset for freebsd-update data files | 37 -s Also create a dataset for freebsd-update data files |
| 38 -t Create a more tiny set of datasets | 38 -t Create a more tiny set of datasets |
| 39 -T Create only an extra tiny set of datasets | 39 -T Create only an extra tiny set of datasets |
| 40 -u Do not automatically mount newly created datasets | 40 -u Do not automatically mount newly created datasets |
| 41 | |
| 42 mount [-u] [-n] DATASET MOUNTPOINT | |
| 43 | |
| 44 Mount the ZFS dataset DATASET and all its children to mountpoint | |
| 45 MOUNTPOINT | |
| 46 | |
| 47 -n Do not really mount but show what would be mounted where | |
| 48 -u Alias of -n | |
| 49 | |
| 50 umount DATASET | |
| 51 | |
| 52 Unmount the mounted DATASET and all its children | |
| 41 | 53 |
| 42 privs MOUNTPOINT | 54 privs MOUNTPOINT |
| 43 | 55 |
| 44 Adjust some Unix privileges to mounted jail datasets | 56 Adjust some Unix privileges to mounted jail datasets |
| 45 | 57 |
| 335 zfs send -R ${_zfscopyopts} "${_source}" | zfs receive ${_zfsopts} "${_dest}" || { echo "ERROR: ZFS operation failed" >&2; return 1; } | 347 zfs send -R ${_zfscopyopts} "${_source}" | zfs receive ${_zfsopts} "${_dest}" || { echo "ERROR: ZFS operation failed" >&2; return 1; } |
| 336 } | 348 } |
| 337 | 349 |
| 338 | 350 |
| 339 # | 351 # |
| 352 # "mount" -- recursively mount a dataset including subordinate datasets | |
| 353 # | |
| 354 # command_mount dataset mountpoint | |
| 355 # | |
| 356 command_mount() { | |
| 357 local _dsname _mountpoint | |
| 358 local _name _mp _canmount _mounted | |
| 359 local _rootds_mountpoint _relative_mp _real_mp | |
| 360 local _dry_run | |
| 361 | |
| 362 _dry_run="" | |
| 363 while getopts "nu" _opt ; do | |
| 364 case ${_opt} in | |
| 365 n|u) | |
| 366 _dry_run="yes" | |
| 367 ;; | |
| 368 \?|:) | |
| 369 return 2; | |
| 370 ;; | |
| 371 esac | |
| 372 done | |
| 373 shift $((OPTIND-1)) | |
| 374 OPTIND=1 | |
| 375 | |
| 376 _dsname="${1-}" | |
| 377 _mountpoint="${2-}" | |
| 378 | |
| 379 if [ -z "${_dsname}" ]; then | |
| 380 echo "ERROR: no dataset given" >&2 | |
| 381 return 2 | |
| 382 fi | |
| 383 if [ -z "${_mountpoint}" ]; then | |
| 384 echo "ERROR: no mountpoint given" >&2 | |
| 385 return 2 | |
| 386 fi | |
| 387 # Remove a trailing slash | |
| 388 _mountpoint="${_mountpoint%/}" | |
| 389 if [ -z "${_mountpoint}" ]; then | |
| 390 echo "ERROR: would mount over the root filesystem" >&2 | |
| 391 return 1 | |
| 392 fi | |
| 393 | |
| 394 _rootds_mountpoint="$(zfs list -H -o mountpoint -t filesystem "${_dsname}")" || \ | |
| 395 { echo "ERROR: root dataset does not exist" >&2; return 1; } | |
| 396 | |
| 397 zfs list -H -o name,mountpoint,canmount,mounted -s mountpoint -t filesystem -r "${_dsname}" | \ | |
| 398 while IFS=$'\t' read _name _mp _canmount _mounted ; do | |
| 399 # Skip filesystems that are already mounted | |
| 400 [ "${_mounted}" = "yes" ] && continue | |
| 401 # Skip filesystems that must not be mounted | |
| 402 [ "${_canmount}" = "off" ] && continue | |
| 403 case "${_mp}" in | |
| 404 "none"|"legacy") | |
| 405 # Do nothing for filesystem with unset or legacy mountpoints | |
| 406 ;; | |
| 407 "${_rootds_mountpoint}"|"${_rootds_mountpoint}/"*) | |
| 408 # | |
| 409 # Handle only mountpoints that have a mountpoint below | |
| 410 # the parent datasets mountpoint | |
| 411 # | |
| 412 | |
| 413 # Determine the mountpoint relative to the parent mountpoint | |
| 414 _relative_mp="${_mp#${_rootds_mountpoint}}" | |
| 415 # Remove a trailing slash | |
| 416 _relative_mp="${_relative_mp%/}" | |
| 417 _real_mp="${_mountpoint}${_relative_mp}" | |
| 418 if [ "${_dry_run}" = "yes" ]; then | |
| 419 echo "Would mount ${_name} on ${_real_mp}" | |
| 420 else | |
| 421 mkdir -p "${_real_mp}" 1> /dev/null 2> /dev/null || \ | |
| 422 { echo "ERROR: cannot create mountpoint ${_real_mp}" >&2; return 1; } | |
| 423 echo "Mounting ${_name} on ${_real_mp}" | |
| 424 mount -t zfs "${_name}" "${_real_mp}" || return 1 | |
| 425 fi | |
| 426 ;; | |
| 427 *) | |
| 428 # XXX FIXME Option to do a zfs mount $_name ??? | |
| 429 echo "Skipping ${_name} because its configured mountpoint is not relative to given root dataset" 2>&1 | |
| 430 ;; | |
| 431 esac | |
| 432 done | |
| 433 | |
| 434 return 0 | |
| 435 } | |
| 436 | |
| 437 | |
| 438 # | |
| 439 # "umount" -- Recursively unmount ZFS datasets | |
| 440 # | |
| 441 # command_umount dataset | |
| 442 # | |
| 443 command_umount() { | |
| 444 local _dsname | |
| 445 local _name _mp _rest | |
| 446 local _rootds_mountpoint | |
| 447 | |
| 448 _dsname="${1-}" | |
| 449 [ -z "${_dsname}" ] && \ | |
| 450 { echo "ERROR: no dataset given" >&2; return 2; } | |
| 451 | |
| 452 # Just determine whether the given dataset name exists | |
| 453 _rootds_mountpoint="$(zfs list -H -o mountpoint -t filesystem "${_dsname}")" | return 1 | |
| 454 | |
| 455 mount -t zfs -p | \ | |
| 456 grep -E "^${_dsname}(/|\s)" | \ | |
| 457 sort -n -r | \ | |
| 458 while IFS=' '$'\t' read _name _mp _rest ; do | |
| 459 echo "Umounting ${_name} on ${_mp}" | |
| 460 umount "${_mp}" || return 1 | |
| 461 done | |
| 462 return 0 | |
| 463 } | |
| 464 | |
| 465 | |
| 466 # | |
| 340 # "privs" -- adjust privileges | 467 # "privs" -- adjust privileges |
| 341 # | 468 # |
| 342 # To be used when all ZFS datasets are mounted. | 469 # To be used when all ZFS datasets are mounted. |
| 343 # | 470 # |
| 344 command_privs() { | 471 command_privs() { |
| 422 | 549 |
| 423 case "${command}" in | 550 case "${command}" in |
| 424 datasets) | 551 datasets) |
| 425 command_datasets "$@" | 552 command_datasets "$@" |
| 426 ;; | 553 ;; |
| 554 mount) | |
| 555 command_mount "$@" | |
| 556 ;; | |
| 557 umount|unmount) | |
| 558 command_umount "$@" | |
| 559 ;; | |
| 427 privs) | 560 privs) |
| 428 command_privs "$@" | 561 command_privs "$@" |
| 429 ;; | 562 ;; |
| 430 populate) | 563 populate) |
| 431 command_populate "$@" | 564 command_populate "$@" |
