Robert Milasan
2012-11-08 09:42:08 UTC
From: Neil Brown <***@suse.com>
Date: Thu, 8 Nov 2012 10:39:06 +0100
Subject: [PATCH] If a 'change' event does not get handled by udev until
after the device has subsequently disappeared, udev mis-handles
it. This can happen with 'md' devices which emit a change
event and then a remove event when they are stopped. It is
normally only noticed if udev is very busy (lots of arrays
being stopped at once) or the machine is otherwise loaded
and reponding slowly.
There are two problems.
1/ udev_device_new_from_syspath() will refuse to create the device
structure if the device does not exist in /sys, and particularly if
the uevent file does not exist.
If a 'db' file does exist, that is sufficient evidence that the device
is genuine and should be created. Equally if we have just received an
event from the kernel about the device, it must be real.
This patch just disabled the test for the 'uevent' file, it doesn't
try imposing any other tests - it isn't clear that they are really
needed.
2/ udev_event_execute_rules() calls udev_device_read_db() on a 'device'
structure that is largely uninitialised and in particular does not
have the 'subsystem' set. udev_device_read_db() needs the subsystem
so it tries to read the 'subsystem' symlink out of sysfs. If the
device is already deleted, this naturally fails.
udev_event_execute_rules() knows the subsystem (as it was in the
event message) so this patch simply sets the subsystem for the device
structure to be loaded to match the subsystem of the device structure
that is handling the event.
With these two changes, deleted handling of change events will still
correctly remove any symlinks that are not needed any more.
---
src/libudev/libudev-device.c | 2 --
src/udev/udev-event.c | 2 ++
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c
index 08476e6..0ea5afe 100644
--- a/src/libudev/libudev-device.c
+++ b/src/libudev/libudev-device.c
@@ -662,8 +662,6 @@ _public_ struct udev_device
*udev_device_new_from_syspath(struct udev *udev, con
/* all "devices" require a "uevent" file */
util_strscpyl(file, sizeof(file), path, "/uevent",
NULL);
- if (stat(file, &statbuf) != 0)
- return NULL;
} else {
/* everything else just needs to be a directory */
if (stat(path, &statbuf) != 0
|| !S_ISDIR(statbuf.st_mode)) diff --git a/src/udev/udev-event.c
b/src/udev/udev-event.c index 2b9fdf6..bc936f4 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -799,6 +799,8 @@ int udev_event_execute_rules(struct udev_event
*event, struct udev_rules *rules, } else {
event->dev_db =
udev_device_new_from_syspath(event->udev,
udev_device_get_syspath(dev)); if (event->dev_db != NULL) {
+ udev_device_set_subsystem(event->dev_db,
+
udev_device_get_subsystem(dev)); udev_device_read_db(event->dev_db,
NULL); udev_device_set_info_loaded(event->dev_db);
--
1.7.7
--
Robert Milasan
L3 Support Engineer
SUSE Linux (http://www.suse.com)
email: ***@suse.com
GPG fingerprint: B6FE F4A8 0FA3 3040 3402 6FE7 2F64 167C 1909 6D1A
--
To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Date: Thu, 8 Nov 2012 10:39:06 +0100
Subject: [PATCH] If a 'change' event does not get handled by udev until
after the device has subsequently disappeared, udev mis-handles
it. This can happen with 'md' devices which emit a change
event and then a remove event when they are stopped. It is
normally only noticed if udev is very busy (lots of arrays
being stopped at once) or the machine is otherwise loaded
and reponding slowly.
There are two problems.
1/ udev_device_new_from_syspath() will refuse to create the device
structure if the device does not exist in /sys, and particularly if
the uevent file does not exist.
If a 'db' file does exist, that is sufficient evidence that the device
is genuine and should be created. Equally if we have just received an
event from the kernel about the device, it must be real.
This patch just disabled the test for the 'uevent' file, it doesn't
try imposing any other tests - it isn't clear that they are really
needed.
2/ udev_event_execute_rules() calls udev_device_read_db() on a 'device'
structure that is largely uninitialised and in particular does not
have the 'subsystem' set. udev_device_read_db() needs the subsystem
so it tries to read the 'subsystem' symlink out of sysfs. If the
device is already deleted, this naturally fails.
udev_event_execute_rules() knows the subsystem (as it was in the
event message) so this patch simply sets the subsystem for the device
structure to be loaded to match the subsystem of the device structure
that is handling the event.
With these two changes, deleted handling of change events will still
correctly remove any symlinks that are not needed any more.
---
src/libudev/libudev-device.c | 2 --
src/udev/udev-event.c | 2 ++
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c
index 08476e6..0ea5afe 100644
--- a/src/libudev/libudev-device.c
+++ b/src/libudev/libudev-device.c
@@ -662,8 +662,6 @@ _public_ struct udev_device
*udev_device_new_from_syspath(struct udev *udev, con
/* all "devices" require a "uevent" file */
util_strscpyl(file, sizeof(file), path, "/uevent",
NULL);
- if (stat(file, &statbuf) != 0)
- return NULL;
} else {
/* everything else just needs to be a directory */
if (stat(path, &statbuf) != 0
|| !S_ISDIR(statbuf.st_mode)) diff --git a/src/udev/udev-event.c
b/src/udev/udev-event.c index 2b9fdf6..bc936f4 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -799,6 +799,8 @@ int udev_event_execute_rules(struct udev_event
*event, struct udev_rules *rules, } else {
event->dev_db =
udev_device_new_from_syspath(event->udev,
udev_device_get_syspath(dev)); if (event->dev_db != NULL) {
+ udev_device_set_subsystem(event->dev_db,
+
udev_device_get_subsystem(dev)); udev_device_read_db(event->dev_db,
NULL); udev_device_set_info_loaded(event->dev_db);
--
1.7.7
--
Robert Milasan
L3 Support Engineer
SUSE Linux (http://www.suse.com)
email: ***@suse.com
GPG fingerprint: B6FE F4A8 0FA3 3040 3402 6FE7 2F64 167C 1909 6D1A
--
To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html