X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udevstart.c;h=cabafb0abc76689064131e41d87ebdcb90276d19;hp=3ecfd4cb61d55bab55e06d8d49287a89a9699ada;hb=8e0871196c916be60a9d0327ce8483c4f9763c17;hpb=462be028f18d94ab06c913768da78e30a1a66b68 diff --git a/udevstart.c b/udevstart.c index 3ecfd4cb6..cabafb0ab 100644 --- a/udevstart.c +++ b/udevstart.c @@ -36,25 +36,12 @@ #include "logging.h" #include "udev_lib.h" #include "list.h" - - -#ifdef LOG -unsigned char logname[LOGNAME_SIZE]; -void log_message(int level, const char *format, ...) -{ - va_list args; - - va_start(args, format); - vsyslog(level, format, args); - va_end(args); -} -#endif +#include "udev.h" #define MAX_PATHLEN 1024 #define SYSBLOCK "/sys/block" #define SYSCLASS "/sys/class" -#define UDEV_BIN "/sbin/udev" struct device { struct list_head list; @@ -83,51 +70,58 @@ static int device_list_insert(char *path, char *subsystem, struct list_head *dev strfieldcpy(new_device->path, path); strfieldcpy(new_device->subsys, subsystem); list_add_tail(&new_device->list, &loop_device->list); + dbg("add '%s' from subsys '%s'", new_device->path, new_device->subsys); return 0; } -static void udev_exec(const char *path, const char* subsystem) -{ - pid_t pid; - char action[] = "ACTION=add"; - char devpath[MAX_PATHLEN]; - char nosleep[] = "UDEV_NO_SLEEP=1"; - char *env[] = { action, devpath, nosleep, NULL }; - - strcpy(devpath, "DEVPATH="); - strfieldcat(devpath, path); - - pid = fork(); - switch (pid) { - case 0: - /* child */ - execle(UDEV_BIN, "udev", subsystem, NULL, env); - dbg("exec of child failed"); - exit(1); - break; - case -1: - dbg("fork of child failed"); - break; - default: - wait(NULL); - } -} - /* list of devices that we should run last due to any one of a number of reasons */ static char *last_list[] = { "/block/dm", /* on here because dm wants to have the block devices around before it */ NULL, }; +/* list of devices that we should run first due to any one of a number of reasons */ +static char *first_list[] = { + "/class/mem", /* people tend to like their memory devices around first... */ + NULL, +}; + +static void add_device(char *path, char *subsys, int fake) +{ + char *argv[3]; + + /* fake argument vector and environment for callouts and dev.d/ */ + argv[0] = "udev"; + argv[1] = subsys; + argv[2] = NULL; + + main_argv = argv; + setenv("DEVPATH", path, 1); + setenv("ACTION", "add", 1); + udev_add_device(path, subsys, fake); +} + static void exec_list(struct list_head *device_list) { struct device *loop_device; struct device *tmp_device; + int i; + + /* handle the "first" type devices first */ + list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { + for (i=0; first_list[i] != NULL; i++) { + if (strncmp(loop_device->path, first_list[i], strlen(first_list[i])) == 0) { + add_device(loop_device->path, loop_device->subsys, NOFAKE); + list_del(&loop_device->list); + free(loop_device); + break; + } + } + } /* handle the devices we are allowed to, excluding the "last" type devices */ list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { int found = 0; - int i; for (i=0; last_list[i] != NULL; i++) { if (strncmp(loop_device->path, last_list[i], strlen(last_list[i])) == 0) { found = 1; @@ -137,14 +131,14 @@ static void exec_list(struct list_head *device_list) if (found) continue; - udev_exec(loop_device->path, loop_device->subsys); + add_device(loop_device->path, loop_device->subsys, NOFAKE); list_del(&loop_device->list); free(loop_device); } /* handle the rest of the devices left over, if any */ list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { - udev_exec(loop_device->path, loop_device->subsys); + add_device(loop_device->path, loop_device->subsys, NOFAKE); list_del(&loop_device->list); free(loop_device); } @@ -232,7 +226,7 @@ static void udev_scan_class(void) dir2 = opendir(dirname); if (dir2 != NULL) { for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[MAX_PATHLEN-1]; + char dirname2[MAX_PATHLEN]; DIR *dir3; struct dirent *dent3; @@ -240,19 +234,27 @@ static void udev_scan_class(void) (strcmp(dent2->d_name, "..") == 0)) continue; + /* pass the net class as it is */ + if (strcmp(dent->d_name, "net") == 0) { + snprintf(dirname2, MAX_PATHLEN, "/class/net/%s", dent2->d_name); + device_list_insert(dirname2, "net", &device_list); + continue; + } + snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); dirname2[MAX_PATHLEN-1] = '\0'; - dir3 = opendir(dirname2); if (dir3 != NULL) { for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { char filename[MAX_PATHLEN]; + /* pass devices with a "dev" file */ if (strcmp(dent3->d_name, "dev") == 0) { snprintf(filename, MAX_PATHLEN, "/class/%s/%s", dent->d_name, dent2->d_name); filename[MAX_PATHLEN-1] = '\0'; device_list_insert(filename, dent->d_name, &device_list); + break; } } closedir(dir3); @@ -267,12 +269,9 @@ static void udev_scan_class(void) exec_list(&device_list); } -int main(int argc, char *argv[], char *envp[]) +int udev_start(void) { - init_logging("udevstart"); - udev_scan_class(); udev_scan_block(); - return 0; }