comparison sbin/fzfs @ 492:312aebce590c

FIX: Handle severe error in "fzfs mount" when the root dataset naturally mounts at root filesystem
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 30 Aug 2024 14:17:45 +0200
parents a2011285f054
children eb42828c0cbf
comparison
equal deleted inserted replaced
491:ae454a761fa3 492:312aebce590c
53 command_mount() { 53 command_mount() {
54 local _dsname _mountpoint 54 local _dsname _mountpoint
55 local _opt_dry_run _opt_mount_outside _opt_mount_natural 55 local _opt_dry_run _opt_mount_outside _opt_mount_natural
56 local _opt_mount_children_only 56 local _opt_mount_children_only
57 57
58 local _name _mp _canmount _mounted _rootds_mountpoint _relative_mp _real_mp 58 local _name _mp _canmount _mounted _rootds_mountpoint _rootds_mountpoint_prefix _relative_mp _real_mp
59 59
60 _opt_dry_run="" 60 _opt_dry_run=""
61 _opt_mount_outside="" 61 _opt_mount_outside=""
62 _opt_mount_natural="" 62 _opt_mount_natural=""
63 _opt_mount_children_only="" 63 _opt_mount_children_only=""
111 # Eventually remove a trailing slash 111 # Eventually remove a trailing slash
112 _mountpoint="${_mountpoint%/}" 112 _mountpoint="${_mountpoint%/}"
113 if [ -z "${_mountpoint}" ]; then 113 if [ -z "${_mountpoint}" ]; then
114 echo "ERROR: would mount over the root filesystem" >&2 114 echo "ERROR: would mount over the root filesystem" >&2
115 return 1 115 return 1
116 fi
117
118 if [ "${_rootds_mountpoint}" = "/" ]; then
119 _rootds_mountpoint_prefix="/"
120 else
121 _rootds_mountpoint_prefix="${_rootds_mountpoint}/"
116 fi 122 fi
117 123
118 zfs list -H -o name,mountpoint,canmount,mounted -s mountpoint -t filesystem -r "${_dsname}" \ 124 zfs list -H -o name,mountpoint,canmount,mounted -s mountpoint -t filesystem -r "${_dsname}" \
119 | { 125 | {
120 while IFS=$'\t' read -r _name _mp _canmount _mounted ; do 126 while IFS=$'\t' read -r _name _mp _canmount _mounted ; do
129 [ \( "${_opt_mount_children_only}" = "yes" \) -a \( "${_name}" = "${_dsname}" \) ] && continue 135 [ \( "${_opt_mount_children_only}" = "yes" \) -a \( "${_name}" = "${_dsname}" \) ] && continue
130 case "${_mp}" in 136 case "${_mp}" in
131 "none"|"legacy") 137 "none"|"legacy")
132 # Do nothing for filesystem with unset or legacy mountpoints 138 # Do nothing for filesystem with unset or legacy mountpoints
133 ;; 139 ;;
134 "${_rootds_mountpoint}"|"${_rootds_mountpoint}/"*) 140 "${_rootds_mountpoint}"|"${_rootds_mountpoint_prefix}"*)
135 # 141 #
136 # Handle only mountpoints that have a mountpoint below 142 # Handle only mountpoints that have a mountpoint below
137 # the parent datasets mountpoint 143 # or exactly at the parent datasets mountpoint
138 # 144 #
139 145
140 # Determine the mountpoint relative to the parent mountpoint 146 #
141 _relative_mp="${_mp#${_rootds_mountpoint}}" 147 # Determine the mountpoint relative to the parent
142 # Eventually remove a trailing slash 148 # mountpoint. Extra effort is needed because the root
143 _relative_mp="${_relative_mp%/}" 149 # filesystem mount is just a single slash.
144 # The real effective full mountpoint 150 #
145 _real_mp="${_mountpoint}${_relative_mp}" 151 if [ "${_mp}" = "${_rootds_mountpoint}" ]; then
152 if [ "${_name}" != "${_dsname}" ]; then
153 echo "ERRROR: child dataset mounts over root dataset" >&2
154 return 1
155 fi
156 _relative_mp=""
157 _real_mp="${_mountpoint}"
158 else
159 _relative_mp="${_mp#${_rootds_mountpoint_prefix}}"
160 # Eventually remove a trailing slash
161 _relative_mp="${_relative_mp%/}"
162 if [ -z "${_relative_mp}" ]; then
163 echo "ERROR: got an empty relative mountpoint in child" >&2
164 return 1
165 fi
166 # The real effective full mountpoint
167 _real_mp="${_mountpoint}/${_relative_mp}"
168 fi
146 169
147 # 170 #
148 # Consistency and sanity check: computed real mountpoint must 171 # Consistency and sanity check: computed real mountpoint must
149 # be equal to the configured mountpoint when no custom mountpoint 172 # be equal to the configured mountpoint when no custom mountpoint
150 # is given. 173 # is given.