Don't block udev if udev-helper sleeps
authorJeremy Kerr <jk@ozlabs.org>
Thu, 5 Apr 2007 04:36:34 +0000 (14:36 +1000)
committerJeremy Kerr <jk@ozlabs.org>
Thu, 5 Apr 2007 04:36:34 +0000 (14:36 +1000)
If udev-helper is going to sleep(), then detach from the main udev
process first. Previously, this meant that new devices were 'stuck'
behind polling helpers.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
devices/udev-helper.c

index 6a9a42bac12e9c626e1c768dd7664edf759ac74c..d70a1d716718e1ea4d6e3e88eb13140a6ddb5389 100644 (file)
@@ -417,6 +417,31 @@ static int found_new_device(const char *dev_path)
        return EXIT_SUCCESS;
 }
 
+static void detach_and_sleep(int sec)
+{
+       static int forked = 0;
+       int rc = 0;
+
+       if (sec <= 0)
+               return;
+
+       if (!forked) {
+               log("running in background...");
+               rc = fork();
+               forked = 1;
+       }
+
+       if (rc == 0) {
+               sleep(sec);
+
+       } else if (rc == -1) {
+               perror("fork()");
+               exit(EXIT_FAILURE);
+       } else {
+               exit(EXIT_SUCCESS);
+       }
+}
+
 static int poll_device_plug(const char *dev_path,
                            int *optical)
 {
@@ -439,7 +464,7 @@ static int poll_device_plug(const char *dev_path,
                        return EXIT_SUCCESS;
 
                printf("no... waiting\n");
-               sleep(REMOVABLE_SLEEP_DELAY);
+               detach_and_sleep(REMOVABLE_SLEEP_DELAY);
        }
 
        /* Fall back to bare open() */
@@ -453,7 +478,7 @@ static int poll_device_plug(const char *dev_path,
                if (fd >= 0)
                        return EXIT_SUCCESS;
                printf("no... waiting\n");
-               sleep(REMOVABLE_SLEEP_DELAY);
+               detach_and_sleep(REMOVABLE_SLEEP_DELAY);
        }
 }
 
@@ -471,7 +496,7 @@ static int poll_device_unplug(const char *dev_path, int optical)
                if (rc != CDS_DISC_OK)
                        return EXIT_SUCCESS;
                printf("no... waiting\n");
-               sleep(REMOVABLE_SLEEP_DELAY);
+               detach_and_sleep(REMOVABLE_SLEEP_DELAY);
        }
 
        /* Fall back to bare open() */
@@ -484,7 +509,7 @@ static int poll_device_unplug(const char *dev_path, int optical)
                if (fd < 0)
                        return EXIT_SUCCESS;
                printf("no... waiting\n");
-               sleep(REMOVABLE_SLEEP_DELAY);
+               detach_and_sleep(REMOVABLE_SLEEP_DELAY);
        }
 }
 
@@ -507,7 +532,7 @@ static int poll_removable_device(const char *sysfs_path,
                /* Unmount it repeatedly, if needs be */
                while (mounted && !unmount_device(dev_path))
                        ;
-               sleep(1);
+               detach_and_sleep(1);
        }
 }
 
@@ -516,9 +541,6 @@ int main(int argc, char **argv)
        char *dev_path, *action;
        int rc;
 
-       /*if (fork())
-               return EXIT_SUCCESS;
-               */
        action = getenv("ACTION");
 
        logf = stdout;