--- systemd-213.old/src/udev/udevd.c 2014-06-06 01:09:22.464595897 -0400 +++ systemd-213.new/src/udev/udevd.c 2014-06-06 01:18:04.499589005 -0400 @@ -297,13 +297,30 @@ static void worker_new(struct event *eve d = udev_device_get_parent(d); if (d) { - fd_lock = open(udev_device_get_devnode(d), O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK); - if (fd_lock >= 0 && flock(fd_lock, LOCK_SH|LOCK_NB) < 0) { - log_debug("Unable to flock(%s), skipping event handling: %m", udev_device_get_devnode(d)); - err = -EWOULDBLOCK; - fd_lock = safe_close(fd_lock); - goto skip; + /* + * to accommodate cases where other prcoesses may already hold an + * incompatible flock (LOCK_EX), allow up to approximately 8 seconds + * (in 250 ms increments) to acquire an flock + */ + int fl_err, fl_tries = 32, fl_try_us = 250000; + if ((fd_lock=open(udev_device_get_devnode(d), + O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK)) >= 0) { + + while ((fl_err=flock(fd_lock, LOCK_SH|LOCK_NB)) && --fl_tries) { + log_debug("Unable to flock(%s[%s]); %d tries remaining: %m", + udev_device_get_devnode(d), udev_device_get_devnode(dev), + fl_tries); + usleep(fl_try_us); + } + if (fl_err) { + log_error("Unable to flock(%s[%s]); skipping event handling: %m", + udev_device_get_devnode(d), udev_device_get_devnode(dev)); + err = -EWOULDBLOCK; + safe_close(fd_lock); + goto skip; + } } + /* handle open failures? */ } } @@ -318,6 +335,14 @@ static void worker_new(struct event *eve udev_device_update_db(dev); } + /* + * explicitly unlock in case there are other open file descriptors + * on the device; closing will only unlock the file after all such + * descriptors are closed + */ + if (fd_lock >= 0) + flock(fd_lock, LOCK_UN); + safe_close(fd_lock); /* send processed event back to libudev listeners */