1716fd348SMartin Matuska#!/bin/sh 216038816SMartin Matuska 3716fd348SMartin Matuskacount_zvols() { 4716fd348SMartin Matuska if [ -z "$zvols" ]; then 5716fd348SMartin Matuska echo 0 6716fd348SMartin Matuska else 7716fd348SMartin Matuska echo "$zvols" | wc -l 8716fd348SMartin Matuska fi 9716fd348SMartin Matuska} 10e92ffd9bSMartin Matuska 11716fd348SMartin Matuskafilter_out_zvols_with_links() { 12716fd348SMartin Matuska echo "$zvols" | tr ' ' '+' | while read -r zvol; do 13716fd348SMartin Matuska if ! [ -L "/dev/zvol/$zvol" ]; then 14716fd348SMartin Matuska echo "$zvol" 15716fd348SMartin Matuska fi 16716fd348SMartin Matuska done | tr '+' ' ' 17716fd348SMartin Matuska} 18716fd348SMartin Matuska 19716fd348SMartin Matuskafilter_out_deleted_zvols() { 20716fd348SMartin Matuska OIFS="$IFS" 21716fd348SMartin Matuska IFS=" 22716fd348SMartin Matuska" 23716fd348SMartin Matuska # shellcheck disable=SC2086 24716fd348SMartin Matuska zfs list -H -o name $zvols 2>/dev/null 25716fd348SMartin Matuska IFS="$OIFS" 26716fd348SMartin Matuska} 27716fd348SMartin Matuska 28716fd348SMartin Matuskalist_zvols() { 29716fd348SMartin Matuska read -r default_volmode < /sys/module/zfs/parameters/zvol_volmode 30716fd348SMartin Matuska zfs list -t volume -H -o \ 31716fd348SMartin Matuska name,volmode,receive_resume_token,redact_snaps,keystatus | 32716fd348SMartin Matuska while IFS=" " read -r name volmode token redacted keystatus; do # IFS=\t here! 33716fd348SMartin Matuska 34716fd348SMartin Matuska # /dev links are not created for zvols with volmode = "none", 35716fd348SMartin Matuska # redacted zvols, or encrypted zvols for which the key has not 36716fd348SMartin Matuska # been loaded. 37716fd348SMartin Matuska [ "$volmode" = "none" ] && continue 38716fd348SMartin Matuska [ "$volmode" = "default" ] && [ "$default_volmode" = "3" ] && 39716fd348SMartin Matuska continue 40716fd348SMartin Matuska [ "$redacted" = "-" ] || continue 41716fd348SMartin Matuska [ "$keystatus" = "unavailable" ] && continue 42716fd348SMartin Matuska 43716fd348SMartin Matuska # We also ignore partially received zvols if it is 44716fd348SMartin Matuska # not an incremental receive, as those won't even have a block 45716fd348SMartin Matuska # device minor node created yet. 46716fd348SMartin Matuska if [ "$token" != "-" ]; then 47716fd348SMartin Matuska 48716fd348SMartin Matuska # Incremental receives create an invisible clone that 49716fd348SMartin Matuska # is not automatically displayed by zfs list. 50716fd348SMartin Matuska if ! zfs list "$name/%recv" >/dev/null 2>&1; then 51716fd348SMartin Matuska continue 52716fd348SMartin Matuska fi 53716fd348SMartin Matuska fi 54716fd348SMartin Matuska echo "$name" 55716fd348SMartin Matuska done 56716fd348SMartin Matuska} 57716fd348SMartin Matuska 58716fd348SMartin Matuskazvols=$(list_zvols) 59716fd348SMartin Matuskazvols_count=$(count_zvols) 60716fd348SMartin Matuskaif [ "$zvols_count" -eq 0 ]; then 61716fd348SMartin Matuska echo "No zvols found, nothing to do." 62716fd348SMartin Matuska exit 0 63716fd348SMartin Matuskafi 64716fd348SMartin Matuska 65716fd348SMartin Matuskaecho "Testing $zvols_count zvol links" 66716fd348SMartin Matuska 67716fd348SMartin Matuskaouter_loop=0 68716fd348SMartin Matuskawhile [ "$outer_loop" -lt 20 ]; do 69716fd348SMartin Matuska outer_loop=$((outer_loop + 1)) 70716fd348SMartin Matuska 71716fd348SMartin Matuska old_zvols_count=$(count_zvols) 72716fd348SMartin Matuska 73716fd348SMartin Matuska inner_loop=0 74716fd348SMartin Matuska while [ "$inner_loop" -lt 30 ]; do 75716fd348SMartin Matuska inner_loop=$((inner_loop + 1)) 76716fd348SMartin Matuska 77716fd348SMartin Matuska zvols="$(filter_out_zvols_with_links)" 78716fd348SMartin Matuska 79716fd348SMartin Matuska zvols_count=$(count_zvols) 80716fd348SMartin Matuska if [ "$zvols_count" -eq 0 ]; then 81716fd348SMartin Matuska echo "All zvol links are now present." 82716fd348SMartin Matuska exit 0 83716fd348SMartin Matuska fi 84716fd348SMartin Matuska sleep 1 85716fd348SMartin Matuska done 86716fd348SMartin Matuska 87716fd348SMartin Matuska echo "Still waiting on $zvols_count zvol links ..." 88716fd348SMartin Matuska # 89716fd348SMartin Matuska # Although zvols should normally not be deleted at boot time, 90716fd348SMartin Matuska # if that is the case then their links will be missing and 91716fd348SMartin Matuska # we would stall. 92716fd348SMartin Matuska # 93716fd348SMartin Matuska if [ "$old_zvols_count" -eq "$zvols_count" ]; then 94716fd348SMartin Matuska echo "No progress since last loop." 95716fd348SMartin Matuska echo "Checking if any zvols were deleted." 96716fd348SMartin Matuska 97716fd348SMartin Matuska zvols=$(filter_out_deleted_zvols) 98716fd348SMartin Matuska zvols_count=$(count_zvols) 99716fd348SMartin Matuska 100716fd348SMartin Matuska if [ "$old_zvols_count" -ne "$zvols_count" ]; then 101716fd348SMartin Matuska echo "$((old_zvols_count - zvols_count)) zvol(s) deleted." 102716fd348SMartin Matuska fi 103716fd348SMartin Matuska 104716fd348SMartin Matuska if [ "$zvols_count" -ne 0 ]; then 105716fd348SMartin Matuska echo "Remaining zvols:" 106716fd348SMartin Matuska echo "$zvols" 107716fd348SMartin Matuska else 108716fd348SMartin Matuska echo "All zvol links are now present." 109716fd348SMartin Matuska exit 0 110716fd348SMartin Matuska fi 111716fd348SMartin Matuska fi 112*dbd5678dSMartin Matuska 113*dbd5678dSMartin Matuska # 114*dbd5678dSMartin Matuska # zvol_count made some progress - let's stay in this loop. 115*dbd5678dSMartin Matuska # 116*dbd5678dSMartin Matuska if [ "$old_zvols_count" -gt "$zvols_count" ]; then 117*dbd5678dSMartin Matuska outer_loop=$((outer_loop - 1)) 118*dbd5678dSMartin Matuska fi 119716fd348SMartin Matuskadone 120716fd348SMartin Matuska 121716fd348SMartin Matuskaecho "Timed out waiting on zvol links" 122716fd348SMartin Matuskaexit 1 123