summaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorPavel Zakharov <[email protected]>2019-07-17 18:33:05 -0400
committerTony Hutter <[email protected]>2019-09-25 11:27:51 -0700
commit38528476bf0b64e7462a1141ff73d016a94f3471 (patch)
tree546f0df623a9dc17a5027a1d5354a5370267ee4d /cmd
parentbeb21db3c6ac503a43ef7c6532d099c056f89f5b (diff)
New service that waits on zvol links to be created
The zfs-volume-wait.service scans existing zvols and waits for their links under /dev to be created. Any service that depends on zvol links to be there should add a dependency on zfs-volumes.target. By default, this target is not enabled. Reviewed-by: Fabian Grünbichler <[email protected]> Reviewed-by: Antonio Russo <[email protected]> Reviewed-by: Richard Laager <[email protected]> Reviewed-by: loli10K <[email protected]> Reviewed-by: John Gallagher <[email protected]> Reviewed-by: George Wilson <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Pavel Zakharov <[email protected]> Closes #8975
Diffstat (limited to 'cmd')
-rw-r--r--cmd/Makefile.am2
-rw-r--r--cmd/zvol_wait/Makefile.am1
-rwxr-xr-xcmd/zvol_wait/zvol_wait93
3 files changed, 95 insertions, 1 deletions
diff --git a/cmd/Makefile.am b/cmd/Makefile.am
index 0d990789b..88609e455 100644
--- a/cmd/Makefile.am
+++ b/cmd/Makefile.am
@@ -5,4 +5,4 @@ if USING_PYTHON
SUBDIRS += arcstat arc_summary dbufstat
endif
-SUBDIRS += mount_zfs zed zvol_id
+SUBDIRS += mount_zfs zed zvol_id zvol_wait
diff --git a/cmd/zvol_wait/Makefile.am b/cmd/zvol_wait/Makefile.am
new file mode 100644
index 000000000..564031c97
--- /dev/null
+++ b/cmd/zvol_wait/Makefile.am
@@ -0,0 +1 @@
+dist_bin_SCRIPTS = zvol_wait
diff --git a/cmd/zvol_wait/zvol_wait b/cmd/zvol_wait/zvol_wait
new file mode 100755
index 000000000..d512be41b
--- /dev/null
+++ b/cmd/zvol_wait/zvol_wait
@@ -0,0 +1,93 @@
+#!/bin/sh
+
+count_zvols() {
+ if [ -z "$zvols" ]; then
+ echo 0
+ else
+ echo "$zvols" | wc -l
+ fi
+}
+
+filter_out_zvols_with_links() {
+ while read -r zvol; do
+ if [ ! -L "/dev/zvol/$zvol" ]; then
+ echo "$zvol"
+ fi
+ done
+}
+
+filter_out_deleted_zvols() {
+ while read -r zvol; do
+ if zfs list "$zvol" >/dev/null 2>&1; then
+ echo "$zvol"
+ fi
+ done
+}
+
+list_zvols() {
+ zfs list -t volume -H -o name,volmode | while read -r zvol_line; do
+ name=$(echo "$zvol_line" | awk '{print $1}')
+ volmode=$(echo "$zvol_line" | awk '{print $2}')
+ # /dev links are not created for zvols with volmode = "none".
+ [ "$volmode" = "none" ] || 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="$(echo "$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=$(echo "$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