1*716fd348SMartin Matuska#!/bin/sh 216038816SMartin Matuska 3*716fd348SMartin Matuskacount_zvols() { 4*716fd348SMartin Matuska if [ -z "$zvols" ]; then 5*716fd348SMartin Matuska echo 0 6*716fd348SMartin Matuska else 7*716fd348SMartin Matuska echo "$zvols" | wc -l 8*716fd348SMartin Matuska fi 9*716fd348SMartin Matuska} 10e92ffd9bSMartin Matuska 11*716fd348SMartin Matuskafilter_out_zvols_with_links() { 12*716fd348SMartin Matuska echo "$zvols" | tr ' ' '+' | while read -r zvol; do 13*716fd348SMartin Matuska if ! [ -L "/dev/zvol/$zvol" ]; then 14*716fd348SMartin Matuska echo "$zvol" 15*716fd348SMartin Matuska fi 16*716fd348SMartin Matuska done | tr '+' ' ' 17*716fd348SMartin Matuska} 18*716fd348SMartin Matuska 19*716fd348SMartin Matuskafilter_out_deleted_zvols() { 20*716fd348SMartin Matuska OIFS="$IFS" 21*716fd348SMartin Matuska IFS=" 22*716fd348SMartin Matuska" 23*716fd348SMartin Matuska # shellcheck disable=SC2086 24*716fd348SMartin Matuska zfs list -H -o name $zvols 2>/dev/null 25*716fd348SMartin Matuska IFS="$OIFS" 26*716fd348SMartin Matuska} 27*716fd348SMartin Matuska 28*716fd348SMartin Matuskalist_zvols() { 29*716fd348SMartin Matuska read -r default_volmode < /sys/module/zfs/parameters/zvol_volmode 30*716fd348SMartin Matuska zfs list -t volume -H -o \ 31*716fd348SMartin Matuska name,volmode,receive_resume_token,redact_snaps,keystatus | 32*716fd348SMartin Matuska while IFS=" " read -r name volmode token redacted keystatus; do # IFS=\t here! 33*716fd348SMartin Matuska 34*716fd348SMartin Matuska # /dev links are not created for zvols with volmode = "none", 35*716fd348SMartin Matuska # redacted zvols, or encrypted zvols for which the key has not 36*716fd348SMartin Matuska # been loaded. 37*716fd348SMartin Matuska [ "$volmode" = "none" ] && continue 38*716fd348SMartin Matuska [ "$volmode" = "default" ] && [ "$default_volmode" = "3" ] && 39*716fd348SMartin Matuska continue 40*716fd348SMartin Matuska [ "$redacted" = "-" ] || continue 41*716fd348SMartin Matuska [ "$keystatus" = "unavailable" ] && continue 42*716fd348SMartin Matuska 43*716fd348SMartin Matuska # We also ignore partially received zvols if it is 44*716fd348SMartin Matuska # not an incremental receive, as those won't even have a block 45*716fd348SMartin Matuska # device minor node created yet. 46*716fd348SMartin Matuska if [ "$token" != "-" ]; then 47*716fd348SMartin Matuska 48*716fd348SMartin Matuska # Incremental receives create an invisible clone that 49*716fd348SMartin Matuska # is not automatically displayed by zfs list. 50*716fd348SMartin Matuska if ! zfs list "$name/%recv" >/dev/null 2>&1; then 51*716fd348SMartin Matuska continue 52*716fd348SMartin Matuska fi 53*716fd348SMartin Matuska fi 54*716fd348SMartin Matuska echo "$name" 55*716fd348SMartin Matuska done 56*716fd348SMartin Matuska} 57*716fd348SMartin Matuska 58*716fd348SMartin Matuskazvols=$(list_zvols) 59*716fd348SMartin Matuskazvols_count=$(count_zvols) 60*716fd348SMartin Matuskaif [ "$zvols_count" -eq 0 ]; then 61*716fd348SMartin Matuska echo "No zvols found, nothing to do." 62*716fd348SMartin Matuska exit 0 63*716fd348SMartin Matuskafi 64*716fd348SMartin Matuska 65*716fd348SMartin Matuskaecho "Testing $zvols_count zvol links" 66*716fd348SMartin Matuska 67*716fd348SMartin Matuskaouter_loop=0 68*716fd348SMartin Matuskawhile [ "$outer_loop" -lt 20 ]; do 69*716fd348SMartin Matuska outer_loop=$((outer_loop + 1)) 70*716fd348SMartin Matuska 71*716fd348SMartin Matuska old_zvols_count=$(count_zvols) 72*716fd348SMartin Matuska 73*716fd348SMartin Matuska inner_loop=0 74*716fd348SMartin Matuska while [ "$inner_loop" -lt 30 ]; do 75*716fd348SMartin Matuska inner_loop=$((inner_loop + 1)) 76*716fd348SMartin Matuska 77*716fd348SMartin Matuska zvols="$(filter_out_zvols_with_links)" 78*716fd348SMartin Matuska 79*716fd348SMartin Matuska zvols_count=$(count_zvols) 80*716fd348SMartin Matuska if [ "$zvols_count" -eq 0 ]; then 81*716fd348SMartin Matuska echo "All zvol links are now present." 82*716fd348SMartin Matuska exit 0 83*716fd348SMartin Matuska fi 84*716fd348SMartin Matuska sleep 1 85*716fd348SMartin Matuska done 86*716fd348SMartin Matuska 87*716fd348SMartin Matuska echo "Still waiting on $zvols_count zvol links ..." 88*716fd348SMartin Matuska # 89*716fd348SMartin Matuska # Although zvols should normally not be deleted at boot time, 90*716fd348SMartin Matuska # if that is the case then their links will be missing and 91*716fd348SMartin Matuska # we would stall. 92*716fd348SMartin Matuska # 93*716fd348SMartin Matuska if [ "$old_zvols_count" -eq "$zvols_count" ]; then 94*716fd348SMartin Matuska echo "No progress since last loop." 95*716fd348SMartin Matuska echo "Checking if any zvols were deleted." 96*716fd348SMartin Matuska 97*716fd348SMartin Matuska zvols=$(filter_out_deleted_zvols) 98*716fd348SMartin Matuska zvols_count=$(count_zvols) 99*716fd348SMartin Matuska 100*716fd348SMartin Matuska if [ "$old_zvols_count" -ne "$zvols_count" ]; then 101*716fd348SMartin Matuska echo "$((old_zvols_count - zvols_count)) zvol(s) deleted." 102*716fd348SMartin Matuska fi 103*716fd348SMartin Matuska 104*716fd348SMartin Matuska if [ "$zvols_count" -ne 0 ]; then 105*716fd348SMartin Matuska echo "Remaining zvols:" 106*716fd348SMartin Matuska echo "$zvols" 107*716fd348SMartin Matuska else 108*716fd348SMartin Matuska echo "All zvol links are now present." 109*716fd348SMartin Matuska exit 0 110*716fd348SMartin Matuska fi 111*716fd348SMartin Matuska fi 112*716fd348SMartin Matuskadone 113*716fd348SMartin Matuska 114*716fd348SMartin Matuskaecho "Timed out waiting on zvol links" 115*716fd348SMartin Matuskaexit 1 116