+ }
+ closedir(dir);
+
+ return running;
+}
+
+static int compare_devpath(const char *running, const char *waiting)
+{
+ int i;
+
+ for (i = 0; i < PATH_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;
+}
+
+/* lookup event for identical, parent, child, or physical device */
+static int devpath_busy(struct udevd_uevent_msg *msg, int limit)
+{
+ struct udevd_uevent_msg *loop_msg;
+ int childs_count = 0;
+
+ /* check exec-queue which may still contain delayed events we depend on */
+ list_for_each_entry(loop_msg, &exec_list, node) {
+ /* skip ourself and all later events */
+ if (loop_msg->seqnum >= msg->seqnum)
+ break;
+
+ /* check our old name */
+ if (msg->devpath_old != NULL)
+ if (strcmp(loop_msg->devpath , msg->devpath_old) == 0)
+ return 2;
+
+ /* check identical, parent, or child device event */
+ if (compare_devpath(loop_msg->devpath, msg->devpath) != 0) {
+ dbg("%llu, device event still pending %llu (%s)\n",
+ msg->seqnum, loop_msg->seqnum, loop_msg->devpath);
+ return 3;
+ }
+
+ /* check for our major:minor number */
+ if (msg->devt && loop_msg->devt == msg->devt &&
+ strcmp(msg->subsystem, loop_msg->subsystem) == 0) {
+ dbg("%llu, device event still pending %llu (%d:%d)\n", msg->seqnum,
+ loop_msg->seqnum, major(loop_msg->devt), minor(loop_msg->devt));
+ return 4;
+ }
+
+ /* check physical device event (special case of parent) */
+ if (msg->physdevpath && msg->action && strcmp(msg->action, "add") == 0)
+ if (compare_devpath(loop_msg->devpath, msg->physdevpath) != 0) {
+ dbg("%llu, physical device event still pending %llu (%s)\n",
+ msg->seqnum, loop_msg->seqnum, loop_msg->devpath);
+ return 5;
+ }
+ }
+
+ /* check run queue for still running events */
+ list_for_each_entry(loop_msg, &running_list, node) {
+ if (limit && childs_count++ > limit) {
+ dbg("%llu, maximum number (%i) of childs reached\n", msg->seqnum, childs_count);
+ return 1;
+ }
+
+ /* check our old name */
+ if (msg->devpath_old != NULL)
+ if (strcmp(loop_msg->devpath , msg->devpath_old) == 0)
+ return 2;
+
+ /* check identical, parent, or child device event */
+ if (compare_devpath(loop_msg->devpath, msg->devpath) != 0) {
+ dbg("%llu, device event still running %llu (%s)\n",
+ msg->seqnum, loop_msg->seqnum, loop_msg->devpath);
+ return 3;
+ }
+
+ /* check for our major:minor number */
+ if (msg->devt && loop_msg->devt == msg->devt &&
+ strcmp(msg->subsystem, loop_msg->subsystem) == 0) {
+ dbg("%llu, device event still running %llu (%d:%d)\n", msg->seqnum,
+ loop_msg->seqnum, major(loop_msg->devt), minor(loop_msg->devt));
+ return 4;