mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	"When an encrypted zvol is locked the zfs-volume-wait service does not start. The /sbin/zvol_wait should not wait for links when the volume has property keystatus=unavailable." -- https://bugs.launchpad.net/ubuntu/+source/zfs-linux/+bug/1888405 Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Damian Szuberski <szuberskidamian@gmail.com> Thanks: James Dingwall <james-launchpad@dingwall.me.uk> Signed-off-by: Richard Laager <rlaager@wiktel.com> Closes #10662
		
			
				
	
	
		
			116 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/sh
 | 
						|
 | 
						|
count_zvols() {
 | 
						|
	if [ -z "$zvols" ]; then
 | 
						|
		echo 0
 | 
						|
	else
 | 
						|
		echo "$zvols" | wc -l
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
filter_out_zvols_with_links() {
 | 
						|
	echo "$zvols" | tr ' ' '+' | while read -r zvol; do
 | 
						|
		if ! [ -L "/dev/zvol/$zvol" ]; then
 | 
						|
			echo "$zvol"
 | 
						|
		fi
 | 
						|
	done | tr '+' ' '
 | 
						|
}
 | 
						|
 | 
						|
filter_out_deleted_zvols() {
 | 
						|
	OIFS="$IFS"
 | 
						|
	IFS="
 | 
						|
"
 | 
						|
	# shellcheck disable=SC2086
 | 
						|
	zfs list -H -o name $zvols 2>/dev/null
 | 
						|
	IFS="$OIFS"
 | 
						|
}
 | 
						|
 | 
						|
list_zvols() {
 | 
						|
	read -r default_volmode < /sys/module/zfs/parameters/zvol_volmode
 | 
						|
	zfs list -t volume -H -o \
 | 
						|
	    name,volmode,receive_resume_token,redact_snaps,keystatus |
 | 
						|
	    while IFS="	" read -r name volmode token redacted keystatus; do # IFS=\t here!
 | 
						|
 | 
						|
		# /dev links are not created for zvols with volmode = "none",
 | 
						|
		# redacted zvols, or encrypted zvols for which the key has not
 | 
						|
		# been loaded.
 | 
						|
		[ "$volmode" = "none" ] && continue
 | 
						|
		[ "$volmode" = "default" ] && [ "$default_volmode" = "3" ] &&
 | 
						|
		    continue
 | 
						|
		[ "$redacted" = "-" ] || continue
 | 
						|
		[ "$keystatus" = "unavailable" ] && continue
 | 
						|
 | 
						|
		# We also ignore partially received zvols if it is
 | 
						|
		# not an incremental receive, as those won't even have a block
 | 
						|
		# device minor node created yet.
 | 
						|
		if [ "$token" != "-" ]; then
 | 
						|
 | 
						|
			# Incremental receives create an invisible clone that
 | 
						|
			# is not automatically displayed by zfs list.
 | 
						|
			if ! zfs list "$name/%recv" >/dev/null 2>&1; then
 | 
						|
				continue
 | 
						|
			fi
 | 
						|
		fi
 | 
						|
		echo "$name"
 | 
						|
	done
 | 
						|
}
 | 
						|
 | 
						|
zvols=$(list_zvols)
 | 
						|
zvols_count=$(count_zvols)
 | 
						|
if [ "$zvols_count" -eq 0 ]; then
 | 
						|
	echo "No zvols found, nothing to do."
 | 
						|
	exit 0
 | 
						|
fi
 | 
						|
 | 
						|
echo "Testing $zvols_count zvol links"
 | 
						|
 | 
						|
outer_loop=0
 | 
						|
while [ "$outer_loop" -lt 20 ]; do
 | 
						|
	outer_loop=$((outer_loop + 1))
 | 
						|
 | 
						|
	old_zvols_count=$(count_zvols)
 | 
						|
 | 
						|
	inner_loop=0
 | 
						|
	while [ "$inner_loop" -lt 30 ]; do
 | 
						|
		inner_loop=$((inner_loop + 1))
 | 
						|
 | 
						|
		zvols="$(filter_out_zvols_with_links)"
 | 
						|
 | 
						|
		zvols_count=$(count_zvols)
 | 
						|
		if [ "$zvols_count" -eq 0 ]; then
 | 
						|
			echo "All zvol links are now present."
 | 
						|
			exit 0
 | 
						|
		fi
 | 
						|
		sleep 1
 | 
						|
	done
 | 
						|
 | 
						|
	echo "Still waiting on $zvols_count zvol links ..."
 | 
						|
	#
 | 
						|
	# Although zvols should normally not be deleted at boot time,
 | 
						|
	# if that is the case then their links will be missing and
 | 
						|
	# we would stall.
 | 
						|
	#
 | 
						|
	if [ "$old_zvols_count" -eq "$zvols_count" ]; then
 | 
						|
		echo "No progress since last loop."
 | 
						|
		echo "Checking if any zvols were deleted."
 | 
						|
 | 
						|
		zvols=$(filter_out_deleted_zvols)
 | 
						|
		zvols_count=$(count_zvols)
 | 
						|
 | 
						|
		if [ "$old_zvols_count" -ne "$zvols_count" ]; then
 | 
						|
			echo "$((old_zvols_count - zvols_count)) zvol(s) deleted."
 | 
						|
		fi
 | 
						|
 | 
						|
		if [ "$zvols_count" -ne 0 ]; then
 | 
						|
			echo "Remaining zvols:"
 | 
						|
			echo "$zvols"
 | 
						|
		else
 | 
						|
			echo "All zvol links are now present."
 | 
						|
			exit 0
 | 
						|
		fi
 | 
						|
	fi
 | 
						|
done
 | 
						|
 | 
						|
echo "Timed out waiting on zvol links"
 | 
						|
exit 1
 |