--- udev-084/udevstart.c.udevstart2 2006-01-30 08:51:38.000000000 +0100 +++ udev-084/udevstart.c 2006-02-07 10:11:31.000000000 +0100 @@ -37,13 +37,13 @@ #include #include #include +#include +#include #include "udev.h" #include "udev_rules.h" -static const char *udev_run_str; static const char *udev_log_str; -static struct udev_rules rules; #ifdef USE_LOG void log_message(int priority, const char *format, ...) @@ -101,76 +101,60 @@ static char *first_list[] = { "/class/mem", "/class/tty", + "/bus", + NULL, +}; + +/* list of devices whose modaliases we should run last */ +static char *last_modalias_list[] = { + "pci:v*d*sv*sd*bc0Csc03i*", /* USB controller */ + "pci:v*d*sv*sd*bc0Csc00i10*", /* Firewire controller */ NULL, }; static int add_device(const char *devpath) { - struct sysfs_device *dev; - struct udevice *udev; - int retval = 0; - - /* clear and set environment for next event */ - clearenv(); - setenv("ACTION", "add", 1); - setenv("UDEV_START", "1", 1); - if (udev_log_str) - setenv("UDEV_LOG", udev_log_str, 1); - if (udev_run_str) - setenv("UDEV_RUN", udev_run_str, 1); - - dev = sysfs_device_get(devpath); - if (dev == NULL) - return -1; - - udev = udev_device_init(); - if (udev == NULL) - return -1; - - /* override built-in sysfs device */ - udev->dev = dev; - strcpy(udev->action, "add"); - udev->devt = udev_device_get_devt(udev); - - if (strcmp(udev->dev->subsystem, "net") != 0) { - udev->devt = udev_device_get_devt(udev); - if (major(udev->devt) == 0) - return -1; - } + char filename[PATH_SIZE]; + int fd; + + snprintf(filename, sizeof(filename), "%s/%s/uevent", sysfs_path, devpath); + filename[sizeof(filename)-1] = '\0'; + + dbg("Trigger %s", filename); + fd = open(filename, O_WRONLY); + if (fd > 0) { + write(fd, "add\n", 4); + close(fd); + } + else return 1; + + return 0; +} - dbg("add '%s'", udev->dev->devpath); - setenv("DEVPATH", udev->dev->devpath, 1); - setenv("SUBSYSTEM", udev->dev->subsystem, 1); - - udev_rules_get_name(&rules, udev); - if (udev->ignore_device) { - dbg("device event will be ignored"); - goto exit; - } - if (udev->name[0] != '\0') - retval = udev_add_device(udev); - else - info("device node creation supressed"); - - if (retval == 0 && udev_run) { - struct name_entry *name_loop; - - dbg("executing run list"); - list_for_each_entry(name_loop, &udev->run_list, node) { - if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0) - pass_env_to_socket(&name_loop->name[strlen("socket:")], udev->dev->devpath, "add"); - else { - char program[PATH_SIZE]; - - strlcpy(program, name_loop->name, sizeof(program)); - udev_rules_apply_format(udev, program, sizeof(program)); - run_program(program, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); - } +static int modalias_is_greylisted(struct device *dev) +{ + + char filename[PATH_SIZE]; + char alias[PATH_SIZE]; + int fd, i; + + snprintf(filename,sizeof(filename),"%s/%s/modalias", sysfs_path, dev->path); + filename[sizeof(filename)-1] = '\0'; + + fd = open(filename, O_RDONLY); + if (fd == -1) + return 0; + read(fd,alias,PATH_SIZE); + alias[sizeof(alias)-1] = '\0'; + alias[strlen(alias)-1] = '\0'; + + for (i = 0; last_modalias_list[i] != NULL; i++) + if (!fnmatch(last_modalias_list[i], alias, 0)) { + close(fd); + return 1; } - } -exit: - udev_device_cleanup(udev); + close(fd); return 0; } @@ -184,6 +168,8 @@ list_for_each_entry_safe(loop_device, tmp_device, device_list, node) { for (i = 0; first_list[i] != NULL; i++) { if (strncmp(loop_device->path, first_list[i], strlen(first_list[i])) == 0) { + if (modalias_is_greylisted(loop_device)) + continue; add_device(loop_device->path); list_del(&loop_device->node); free(loop_device); @@ -203,6 +189,8 @@ } if (found) continue; + if (modalias_is_greylisted(loop_device)) + continue; add_device(loop_device->path); list_del(&loop_device->node); @@ -222,7 +210,7 @@ char filename[PATH_SIZE]; struct stat statbuf; - snprintf(filename, sizeof(filename), "%s/dev", path); + snprintf(filename, sizeof(filename), "%s/uevent", path); filename[sizeof(filename)-1] = '\0'; if (stat(filename, &statbuf) == 0) @@ -279,6 +267,50 @@ } } +static void udev_scan_bus(struct list_head *device_list) +{ + char base[PATH_SIZE]; + DIR *dir; + struct dirent *dent; + + snprintf(base, sizeof(base), "%s/bus", sysfs_path); + base[sizeof(base)-1] = '\0'; + + dir = opendir(base); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[PATH_SIZE]; + DIR *dir2; + struct dirent *dent2; + + if (dent->d_name[0] == '.') + continue; + + snprintf(dirname, sizeof(dirname), "%s/%s/devices", base, dent->d_name); + dirname[sizeof(dirname)-1] = '\0'; + + dir2 = opendir(dirname); + if (dir2 != NULL) { + for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { + char dirname2[PATH_SIZE]; + + if (dent2->d_name[0] == '.') + continue; + + snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name); + dirname2[sizeof(dirname2)-1] = '\0'; + + if (has_devt(dirname2)) + device_list_insert(dirname2, device_list); + } + closedir(dir2); + } + } + closedir(dir); + } +} + + static void udev_scan_class(struct list_head *device_list) { char base[PATH_SIZE]; @@ -312,7 +344,7 @@ snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name); dirname2[sizeof(dirname2)-1] = '\0'; - if (has_devt(dirname2) || strcmp(dent->d_name, "net") == 0) + if (has_devt(dirname2)) device_list_insert(dirname2, device_list); } closedir(dir2); @@ -342,7 +374,6 @@ udev_config_init(); dbg("version %s", UDEV_VERSION); - udev_run_str = getenv("UDEV_RUN"); udev_log_str = getenv("UDEV_LOG"); /* disable all logging if not explicitely requested */ @@ -362,13 +393,12 @@ alarm(UDEV_ALARM_TIMEOUT); sysfs_init(); - udev_rules_init(&rules, 1); + udev_scan_bus(&device_list); udev_scan_class(&device_list); udev_scan_block(&device_list); exec_list(&device_list); - udev_rules_cleanup(&rules); sysfs_cleanup(); logging_close(); return 0;