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