[lvm-devel] [PATCH] libdm: fix races with udev
Mikulas Patocka
mpatocka at redhat.com
Mon Sep 23 18:07:09 UTC 2013
On Thu, 19 Sep 2013, Peter Rajnoha wrote:
> On 09/16/2013 09:23 PM, Mikulas Patocka wrote:
> > libdm: fix races with udev
> >
> > On newer systems (Debian 6 and newer), udev manages nodes in /dev/mapper
> > directory. It creates, deletes and renames the nodes according to the
> > state of the kernel driver.
> >
> > dmsetup tries to manage nodes in /dev/mapper too, so it can race with
> > udev. dmsetup checks if the node was created/deleted/renamed with the stat
> > syscall, and skips the operation if it was. However, if udev
> > creates/deletes/renames the node after the stat syscall and before the
> > mknod/unlink/rename syscall, dmsetup reports an error.
> >
>
> These checks are performed after udev is synchronized (the dm_udev_wait call)
> and after the udev processing is complete, so we normally shouldn't get into this
> problem unless there is some bug in certain version of lvm2/udev rules.
>
> Is this reproducible with upstream code as well or was that with some older version only
> that is currently in Debian?
>
> Peter
This race condition can be easily provoked with this patch. Apply it and
try dmsetup create/remove/rename.
One Debian 6, races in all three operations create/remove/rename can be
provoked.
On Debian Sid and on RHEL 6, only races in create/rename can be provoked.
Race in remove doesn't happen.
Mikulas
Index: LVM2.2.02.102/libdm/libdm-common.c
===================================================================
--- LVM2.2.02.102.orig/libdm/libdm-common.c 2013-09-23 16:51:29.000000000 +0200
+++ LVM2.2.02.102/libdm/libdm-common.c 2013-09-23 19:10:32.028514000 +0200
@@ -964,6 +964,8 @@
log_warn("%s not set up by udev: Falling back to direct "
"node creation.", path);
+ fprintf(stderr, "sleeping 1\n"); sleep(3);
+
(void) dm_prepare_selinux_context(path, S_IFBLK);
old_mask = umask(0);
if (mknod(path, S_IFBLK | mode, dev) < 0) {
@@ -998,6 +1000,8 @@
log_warn("Node %s was not removed by udev. "
"Falling back to direct node removal.", path);
+ fprintf(stderr, "sleeping 2\n"); sleep(3);
+
if (unlink(path) < 0) {
log_error("Unable to unlink device node for '%s'", dev_name);
return 0;
@@ -1054,6 +1058,8 @@
"Falling back to direct node rename.",
oldpath, newpath);
+ fprintf(stderr, "sleeping 3\n"); sleep(3);
+
if (rename(oldpath, newpath) < 0) {
log_error("Unable to rename device node from '%s' to '%s'",
old_name, new_name);
More information about the lvm-devel
mailing list