From: kay.sievers@vrfy.org Date: Wed, 5 Jan 2005 04:35:24 +0000 (+0100) Subject: [PATCH] improve event sequence serialization X-Git-Tag: 051~23 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=7b6571a9fc1909a7231ec9018ddd6602389363d3 [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. --- diff --git a/udevd.c b/udevd.c index c6642f435..569458484 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;