bug-parted
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] tests: avoid a race condition in the scsi_debug-using tests


From: Jim Meyering
Subject: [PATCH] tests: avoid a race condition in the scsi_debug-using tests
Date: Thu, 14 Apr 2011 12:41:17 +0200

Testing parted on s390, I saw some odd problems,
but only with parallel "make check".

For example, this was a common failure,

    FAIL: t9020-alignment.sh (exit: 1)

      -Warning: Error fsyncing/closing /dev/sda: Input/output error
      -Error: /dev/sda: unrecognised disk label
      -Warning: Error fsyncing/closing /dev/sda: Input/output error

And this one failed, but only intermittently:

    FAIL: t9030-align-check.sh (exit: 1)

      + parted -s /dev/sda mklabel gpt
      Warning: Error fsyncing/closing /dev/sda: Input/output error
      Error: Input/output error during read on /dev/sda
      Error: Input/output error during read on /dev/sda
      Error: Input/output error during write on /dev/sda
      Warning: Error fsyncing/closing /dev/sda: Input/output error

and sometimes this:

    FAIL: t9040-many-partitions.sh (exit: 1)

I traced those to a race condition in the test infrastructure,
(the scsi_debug_setup_ function), when tests are run in parallel.

FYI, here's the patch to fix that:

-- 8< --
Subject: [PATCH] tests: avoid a race condition in the scsi_debug-using
 tests

* tests/t-local.sh (new_sdX_): New function.
(scsi_debug_setup_): Use new_sdX_ to find the just-created device name,
rather relying on the list of file names in /sys/block/sd* changing.
Sometimes the list would not change, which would lead to tests failing
with I/O errors when run in parallel.  Thanks to Brian Lane for the
tip that /sys/block/sd*/device/model contains "scsi_debug" if there
is a device created by our "modprobe scsi_debug" command.
---
 tests/t-local.sh |   28 +++++++++++++++++-----------
 1 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/tests/t-local.sh b/tests/t-local.sh
index 3a4d398..135563a 100644
--- a/tests/t-local.sh
+++ b/tests/t-local.sh
@@ -70,7 +70,18 @@ scsi_debug_acquire_lock_()
   return 1
 }

-print_sd_names_() { (cd /sys/block && printf '%s\n' sd*); }
+# If there is a scsi_debug device, print the corresponding "sdN" and return 0.
+# Otherwise, return 1.
+new_sdX_()
+{
+  local m=$(grep -lw scsi_debug /sys/block/sd*/device/model) || return 1
+
+  # Remove the /sys/block/ prefix, and then the /device/model suffix.
+  m=${m#/sys/block/}
+  m=${m%/device/model}
+  echo "$m"
+  return 0
+}

 # Create a device using the scsi_debug module with the options passed to
 # this function as arguments.  Upon success, print the name of the new device.
@@ -80,8 +91,8 @@ scsi_debug_setup_()

   # It is not trivial to determine the name of the device we're creating.
   # Record the names of all /sys/block/sd* devices *before* probing:
-  print_sd_names_ > before
-  modprobe scsi_debug "$@" || { rm -f before; return 1; }
+  touch stamp
+  modprobe scsi_debug "$@" || { rm -f stamp; return 1; }
   scsi_debug_modprobe_succeeded_=1
   test $VERBOSE = yes \
     && warn_ $ME_ modprobe scsi_debug succeeded
@@ -92,18 +103,13 @@ scsi_debug_setup_()
   # FIXME-portability: using "cmp - ..." probably requires GNU cmp.
   local incr=1
   local i=0
-  while print_sd_names_ | cmp -s - before; do
+  local new_dev
+  while :; do
+    new_dev=$(new_sdX_) && break
     sleep .1 2>/dev/null || { sleep 1; incr=10; }
     i=$(expr $i + $incr); test $i = 20 && break
   done

-  # Record the names of all /sys/block/sd* devices *after* probe+wait.
-  print_sd_names_ > after
-
-  # Determine which device names (if any) are new.
-  # There could be more than one new device, and there have been a removal.
-  local new_dev=$(comm -13 before after)
-  rm -f before after
   case $new_dev in
     sd[a-z]) ;;
     sd[a-z][a-z]) ;;
--
1.7.5.rc1.228.g86d60b



reply via email to

[Prev in Thread] Current Thread [Next in Thread]