forked from pool/systemd
70 lines
3.4 KiB
Diff
70 lines
3.4 KiB
Diff
|
From bf9d233f781f27841be6638ee745e9c80bda5f4d Mon Sep 17 00:00:00 2001
|
||
|
From: Kay Sievers <kay@vrfy.org>
|
||
|
Date: Tue, 13 Nov 2012 02:05:06 +0100
|
||
|
Subject: [PATCH] udev: properly handle symlink removal by 'change' event
|
||
|
|
||
|
If a 'change' event is supposed to remove created symlinks, we create
|
||
|
a new device structure from the sysfs device and fill it with the list
|
||
|
of links, to compute the delta of the old and new list of links to apply.
|
||
|
If the device is already 'remove'd by the kernel though, udev fails to
|
||
|
create the device structure, so the links are not removed properly.
|
||
|
|
||
|
> From: Neil Brown <nfbrown@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.
|
||
|
|
||
|
Use udev_device_new() instead of allowing udev_device_new_from_syspath()
|
||
|
to proceed without a sysfs device.
|
||
|
---
|
||
|
src/udev/udev-event.c | 4 +++-
|
||
|
1 files changed, 3 insertions(+), 1 deletions(-)
|
||
|
|
||
|
Index: systemd-195/src/udev/udev-event.c
|
||
|
===================================================================
|
||
|
--- systemd-195.orig/src/udev/udev-event.c
|
||
|
+++ systemd-195/src/udev/udev-event.c
|
||
|
@@ -797,8 +797,10 @@ int udev_event_execute_rules(struct udev
|
||
|
if (major(udev_device_get_devnum(dev)) != 0)
|
||
|
udev_node_remove(dev);
|
||
|
} else {
|
||
|
- event->dev_db = udev_device_new_from_syspath(event->udev, udev_device_get_syspath(dev));
|
||
|
+ event->dev_db = udev_device_new(event->udev);
|
||
|
if (event->dev_db != NULL) {
|
||
|
+ udev_device_set_syspath(event->dev_db, udev_device_get_syspath(dev));
|
||
|
+ 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);
|
||
|
|