Yes, this is an old bug. :)
If anyone is interested, here's my own solution to this problem; the
idea is simply to add some randomness to the interval between locking
attempts.
In my experience with a 4-in-1 device, the first interval is scattered
enough for all attempts to go through on the first retry. Still, a
12-in-1 device or a slower system may require some more wiggle room; I
left the maximum number of retries to 3, which now translates to a total
wait time of up to 7 seconds.
This should also alleviate (but not resolve) #658028 ("Udev should not
wait for mounting").
>From d246ff9b4e622af3d18c93b2f612de336a204ca5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Bri=C3=A8re?= <[email protected]>
Date: Mon, 29 Sep 2014 16:35:46 -0400
Subject: [PATCH] Add some randomness to the interval between locking attempts
This ensures that when several instances of usbmount are launched at the
same time (which is often the case for N-in-1 memory card readers),
their attempts to acquire the lock will be scattered, to avoid competing
with each other.
---
usbmount | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/usbmount b/usbmount
index ee297bb..67e376e 100755
--- a/usbmount
+++ b/usbmount
@@ -75,11 +75,59 @@ fi
umask 022
+# lockfile_create_random <retry-count> <lockfile-create-arguments>
+#
+# Like lockfile-create(1), but with a variable amount of time between
+# attempts. Each retry attempt will be delayed by a random amount of time
+# between 0 and 2^(N-1) seconds for the Nth retry, up to <retry-count> times.
+#
+# All <lockfile-create-arguments> will be passed as-is to lockfile-create.
+
+lockfile_create_random() {
+ RETRY_COUNT=$1
+ shift
+
+ # Maximum (integer) number of seconds before the next attempt
+ MAX_WAIT=1
+
+ # Attempt to acquire the lock (capturing any error message)
+ until ERR_MSG="$(lockfile-create --retry 0 "$@" 2>&1)"; do
+ RETVAL=$?
+
+ # Abort on any error other than L_MAXTRYS
+ if [ $RETVAL -ne 4 ]; then
+ # Rethrow the error message output by lockfile-create
+ log err "$ERR_MSG"
+ return $RETVAL
+ fi
+ # Also quit on L_MAXTRYS after the maximum number of attempts
+ if [ $RETRY_COUNT -eq 0 ]; then
+ return $RETVAL
+ fi
+
+ # Generate a random (32-bit) number -- copied from (thanks!):
+ # http://www.linuxquestions.org/questions/programming-9/shell-script-random-variable-4088/#post2975909
+ RAND=$(dd if=/dev/urandom count=1 2>/dev/null | cksum | cut -f1 -d" ")
+ # Turn it into a decimal number between 0 and $MAX_WAIT
+ # (Granted, the resulting value is not *truly* random. <g>)
+ SLEEP_TIME=$(expr $RAND % $MAX_WAIT).$(expr $RAND % 1000)
+
+ log debug "lock unavailable; sleeping $SLEEP_TIME seconds before retrying"
+ sleep $SLEEP_TIME
+
+ MAX_WAIT=$(expr $MAX_WAIT \* 2)
+ RETRY_COUNT=$(expr $RETRY_COUNT - 1)
+ done
+
+ # Lock successfully acquired
+ return 0
+}
+
if [ "$1" = add ]; then
# Acquire lock.
log debug "trying to acquire lock /var/run/usbmount/.mount.lock"
- lockfile-create --retry 3 /var/run/usbmount/.mount || \
+ lockfile_create_random 3 /var/run/usbmount/.mount || \
{ log err "cannot acquire lock /var/run/usbmount/.mount.lock"; exit 1; }
trap '( lockfile-remove /var/run/usbmount/.mount )' 0
log debug "acquired lock /var/run/usbmount/.mount.lock"
--
2.1.1