]> git.ozlabs.org Git - petitboot/blobdiff - devices/udev-helper.c
Don't block udev if udev-helper sleeps
[petitboot] / devices / udev-helper.c
index f54ca238fd03178d165a169c520c36efa2f6b5e0..d70a1d716718e1ea4d6e3e88eb13140a6ddb5389 100644 (file)
 #include <sys/ioctl.h>
 
 #include "udev-helper.h"
-#define REMOVABLE_SLEEP_DELAY  2
-
 #include "petitboot-paths.h"
 
+/* Define below to operate without the frontend */
+#undef USE_FAKE_SOCKET
+
+/* Delay in seconds between polling of removable devices */
+#define REMOVABLE_SLEEP_DELAY  2
+
 extern struct parser native_parser;
 extern struct parser yaboot_parser;
+extern struct parser kboot_parser;
 static FILE *logf;
 static int sock;
 
@@ -29,6 +34,7 @@ static int sock;
 static struct parser *parsers[] = {
        &native_parser,
        &yaboot_parser,
+       &kboot_parser,
        NULL
 };
 
@@ -44,7 +50,7 @@ static void iterate_parsers(const char *devpath, const char *mountpoint)
                log("\ttrying parser '%s'\n", parsers[i]->name);
                /* just use a dummy device path for now */
                if (parsers[i]->parse(devpath, mountpoint))
-                       return;
+                       /*return*/;
        }
        log("\tno boot_options found\n");
 }
@@ -195,7 +201,7 @@ int remove_device(const char *dev_path)
 
 int connect_to_socket()
 {
-#if 1
+#ifndef USE_FAKE_SOCKET
        int fd;
        struct sockaddr_un addr;
 
@@ -366,6 +372,8 @@ enum generic_icon_type guess_device_type(void)
        const char *bus = getenv("ID_BUS");
        if (type && streq(type, "cd"))
                return ICON_TYPE_OPTICAL;
+       if (!bus)
+               return ICON_TYPE_UNKNOWN;
        if (streq(bus, "usb"))
                return ICON_TYPE_USB;
        if (streq(bus, "ata") || streq(bus, "scsi"))
@@ -409,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)
 {
@@ -431,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() */
@@ -445,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);
        }
 }
 
@@ -463,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() */
@@ -476,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);
        }
 }
 
@@ -499,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);
        }
 }
 
@@ -508,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;
@@ -564,3 +594,19 @@ int main(int argc, char **argv)
        }
        return rc;
 }
+
+/* convenience function for parsers */
+char *join_paths(const char *a, const char *b)
+{
+       char *full_path;
+
+       full_path = malloc(strlen(a) + strlen(b) + 2);
+
+       strcpy(full_path, a);
+       if (b[0] != '/')
+               strcat(full_path, "/");
+       strcat(full_path, b);
+
+       return full_path;
+}
+