summaryrefslogtreecommitdiff
path: root/udevd.c
diff options
context:
space:
mode:
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>2005-01-05 05:35:24 +0100
committerGreg KH <gregkh@suse.de>2005-04-26 23:19:09 -0700
commit7b6571a9fc1909a7231ec9018ddd6602389363d3 (patch)
tree65ef10f4526a7b0a73009411c2ef33d288672815 /udevd.c
parente750d24b0552f4fb11672ab5bdf72f536a047446 (diff)
[PATCH] improve event sequence serialization
We delay the execution of events if there is already an event running for the same device, a parent or a child device. "add" events with a reference to a physical device will also wait for the physical device to finish. Here we fix the devpath comparison logic to return "busy" only if a complete device names is matching. /block/sdaa will not longer block a /block/sda event.
Diffstat (limited to 'udevd.c')
-rw-r--r--udevd.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/udevd.c b/udevd.c
index c6642f4359..5694584840 100644
--- a/udevd.c
+++ b/udevd.c
@@ -151,34 +151,51 @@ static void udev_run(struct hotplug_msg *msg)
}
}
-/* returns still running task for the same event sequence */
+static int compare_devpath(const char *running, const char *waiting)
+{
+ int i;
+
+ for (i = 0; i < DEVPATH_SIZE; i++) {
+ /* identical device event found */
+ if (running[i] == '\0' && waiting[i] == '\0')
+ return 1;
+
+ /* parent device event found */
+ if (running[i] == '\0' && waiting[i] == '/')
+ return 2;
+
+ /* child device event found */
+ if (running[i] == '/' && waiting[i] == '\0')
+ return 3;
+
+ /* no matching event */
+ if (running[i] != waiting[i])
+ break;
+ }
+
+ return 0;
+}
+
+/* returns still running task for the same device, its parent or its physical device */
static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg)
{
struct hotplug_msg *loop_msg;
- int i;
+
+ if (msg->devpath == NULL)
+ return NULL;
list_for_each_entry(loop_msg, &running_list, list) {
- if (loop_msg->devpath == NULL || msg->devpath == NULL)
+ if (loop_msg->devpath == NULL)
continue;
- /* is a parent or child device event still running */
- for (i = 0; i < DEVPATH_SIZE; i++) {
- if (loop_msg->devpath[i] == '\0' || msg->devpath[i] == '\0')
- return loop_msg;
+ /* return running parent/child device event */
+ if (compare_devpath(loop_msg->devpath, msg->devpath) != 0)
+ return loop_msg;
- if (loop_msg->devpath[i] != msg->devpath[i])
- break;
- }
-
- /* is the physical device event still running on an add sequence */
+ /* return running physical device event */
if (msg->physdevpath && msg->action && strcmp(msg->action, "add") == 0)
- for (i = 0; i < DEVPATH_SIZE; i++) {
- if (loop_msg->devpath[i] == '\0' || msg->physdevpath[i] == '\0')
- return loop_msg;
-
- if (loop_msg->devpath[i] != msg->physdevpath[i])
- break;
- }
+ if (compare_devpath(loop_msg->devpath, msg->physdevpath) != 0)
+ return loop_msg;
}
return NULL;