X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udev_event.c;h=887537e0e97770c1a11dcf05e904c482e9a9722c;hp=8a3ed29315fd5fed00feea03b216c7e12d05ecb7;hb=fb6e4c28248cdeed30a1d3eb42aba477f0429472;hpb=e8d569b4145a358775e87058829133fa725b32fd diff --git a/udev_event.c b/udev_event.c index 8a3ed2931..887537e0e 100644 --- a/udev_event.c +++ b/udev_event.c @@ -28,42 +28,62 @@ #include #include #include -#include #include -#include -#include +#include "libsysfs/sysfs/libsysfs.h" #include "udev_libc_wrapper.h" #include "udev.h" #include "logging.h" #include "udev_rules.h" #include "udev_utils.h" -#include "udev_sysfs.h" #include "list.h" +dev_t get_devt(struct sysfs_class_device *class_dev) +{ + struct sysfs_attribute *attr = NULL; + unsigned int major, minor; + char *maj, *min; + + maj = getenv("MAJOR"); + min = getenv("MINOR"); + + if (maj && min) { + major = atoi(maj); + minor = atoi(min); + } else { + attr = sysfs_get_classdev_attr(class_dev, "dev"); + if (attr == NULL) + return 0; + dbg("dev='%s'", attr->value); + + if (sscanf(attr->value, "%u:%u", &major, &minor) != 2) + return 0; + } + + dbg("found major=%d, minor=%d", major, minor); + return makedev(major, minor); +} + int udev_process_event(struct udev_rules *rules, struct udevice *udev) { int retval; char path[PATH_SIZE]; - const char *error; if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS || udev->type == DEV_NET) { /* handle device node */ if (strcmp(udev->action, "add") == 0) { struct sysfs_class_device *class_dev; - /* wait for sysfs of /sys/class /sys/block */ dbg("node add"); snprintf(path, sizeof(path), "%s%s", sysfs_path, udev->devpath); path[sizeof(path)-1] = '\0'; - class_dev = wait_class_device_open(path); + class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { dbg("open class device failed"); return 0; } dbg("opened class_dev->name='%s'", class_dev->name); - wait_for_class_device(class_dev, &error); /* get major/minor */ if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) @@ -75,66 +95,66 @@ int udev_process_event(struct udev_rules *rules, struct udevice *udev) if (udev->ignore_device) { info("device event will be ignored"); sysfs_close_class_device(class_dev); - return -1; + return 0; } - if (udev->name[0] == '\0') { + if (udev->name[0] != '\0') { + /* create node, store in db */ + retval = udev_add_device(udev, class_dev); + } else { info("device node creation supressed"); - sysfs_close_class_device(class_dev); - return -1; } - /* create node, store in db */ - retval = udev_add_device(udev, class_dev); } else { dbg("no dev-file found"); udev_rules_get_run(rules, udev, class_dev, NULL); if (udev->ignore_device) { info("device event will be ignored"); sysfs_close_class_device(class_dev); - return -1; + return 0; } } sysfs_close_class_device(class_dev); } else if (strcmp(udev->action, "remove") == 0) { + struct name_entry *name_loop; + + /* get data from db, remove db-entry, delete node */ dbg("node remove"); + retval = udev_remove_device(udev); + + /* restore stored persistent data */ + list_for_each_entry(name_loop, &udev->env_list, node) + putenv(name_loop->name); + udev_rules_get_run(rules, udev, NULL, NULL); if (udev->ignore_device) { dbg("device event will be ignored"); - return -1; + return 0; } - - /* get name from db, remove db-entry, delete node */ - retval = udev_remove_device(udev); } - - /* export name of device node or netif */ - if (udev->devname[0] != '\0') - setenv("DEVNAME", udev->devname, 1); } else if (udev->type == DEV_DEVICE && strcmp(udev->action, "add") == 0) { struct sysfs_device *devices_dev; - /* wait for sysfs of /sys/devices/ */ dbg("devices add"); snprintf(path, sizeof(path), "%s%s", sysfs_path, udev->devpath); path[sizeof(path)-1] = '\0'; - devices_dev = wait_devices_device_open(path); + devices_dev = sysfs_open_device_path(path); if (!devices_dev) { dbg("devices device unavailable (probably remove has beaten us)"); return 0; } + dbg("devices device opened '%s'", path); - wait_for_devices_device(devices_dev, &error); udev_rules_get_run(rules, udev, NULL, devices_dev); sysfs_close_device(devices_dev); if (udev->ignore_device) { info("device event will be ignored"); - return -1; + return 0; } } else { dbg("default handling"); udev_rules_get_run(rules, udev, NULL, NULL); if (udev->ignore_device) { info("device event will be ignored"); - return -1; + return 0; } } return 0;