# HG changeset patch # User Franz Glasner # Date 1725020265 -7200 # Node ID 312aebce590ce3ed30540fb09bafd6a8ce83a2fe # Parent ae454a761fa3c7ccdc3347926a3cb22930878b3f FIX: Handle severe error in "fzfs mount" when the root dataset naturally mounts at root filesystem diff -r ae454a761fa3 -r 312aebce590c sbin/fzfs --- a/sbin/fzfs Fri Aug 30 10:49:36 2024 +0200 +++ b/sbin/fzfs Fri Aug 30 14:17:45 2024 +0200 @@ -55,7 +55,7 @@ local _opt_dry_run _opt_mount_outside _opt_mount_natural local _opt_mount_children_only - local _name _mp _canmount _mounted _rootds_mountpoint _relative_mp _real_mp + local _name _mp _canmount _mounted _rootds_mountpoint _rootds_mountpoint_prefix _relative_mp _real_mp _opt_dry_run="" _opt_mount_outside="" @@ -115,6 +115,12 @@ return 1 fi + if [ "${_rootds_mountpoint}" = "/" ]; then + _rootds_mountpoint_prefix="/" + else + _rootds_mountpoint_prefix="${_rootds_mountpoint}/" + fi + zfs list -H -o name,mountpoint,canmount,mounted -s mountpoint -t filesystem -r "${_dsname}" \ | { while IFS=$'\t' read -r _name _mp _canmount _mounted ; do @@ -131,18 +137,35 @@ "none"|"legacy") # Do nothing for filesystem with unset or legacy mountpoints ;; - "${_rootds_mountpoint}"|"${_rootds_mountpoint}/"*) + "${_rootds_mountpoint}"|"${_rootds_mountpoint_prefix}"*) # # Handle only mountpoints that have a mountpoint below - # the parent datasets mountpoint + # or exactly at the parent datasets mountpoint # - # Determine the mountpoint relative to the parent mountpoint - _relative_mp="${_mp#${_rootds_mountpoint}}" - # Eventually remove a trailing slash - _relative_mp="${_relative_mp%/}" - # The real effective full mountpoint - _real_mp="${_mountpoint}${_relative_mp}" + # + # Determine the mountpoint relative to the parent + # mountpoint. Extra effort is needed because the root + # filesystem mount is just a single slash. + # + if [ "${_mp}" = "${_rootds_mountpoint}" ]; then + if [ "${_name}" != "${_dsname}" ]; then + echo "ERRROR: child dataset mounts over root dataset" >&2 + return 1 + fi + _relative_mp="" + _real_mp="${_mountpoint}" + else + _relative_mp="${_mp#${_rootds_mountpoint_prefix}}" + # Eventually remove a trailing slash + _relative_mp="${_relative_mp%/}" + if [ -z "${_relative_mp}" ]; then + echo "ERROR: got an empty relative mountpoint in child" >&2 + return 1 + fi + # The real effective full mountpoint + _real_mp="${_mountpoint}/${_relative_mp}" + fi # # Consistency and sanity check: computed real mountpoint must