X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fudev%2Fudevd.c;h=0a3ab687fda0822a8a926dc11743cf512df69a5f;hp=23351aebd5685b9c02e51af23e0ad2a34d30036b;hb=1d600df55bdba448b05d6f8293028d6b6702914b;hpb=7781e063e8e9d3e92e4e158e1588b885808cda24 diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 23351aebd..0a3ab687f 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Kay Sievers + * Copyright (C) 2004-2012 Kay Sievers * Copyright (C) 2004 Chris Friesen * Copyright (C) 2009 Canonical Ltd. * Copyright (C) 2009 Scott James Remnant @@ -48,6 +48,7 @@ #include "sd-daemon.h" #include "cgroup-util.h" #include "dev-setup.h" +#include "fileio.h" static bool debug; @@ -95,8 +96,9 @@ struct event { size_t devpath_len; const char *devpath_old; dev_t devnum; - bool is_block; int ifindex; + bool is_block; + bool nodelay; }; static inline struct event *node_to_event(struct udev_list_node *node) @@ -121,7 +123,7 @@ struct worker { struct udev_monitor *monitor; enum worker_state state; struct event *event; - unsigned long long event_start_usec; + usec_t event_start_usec; }; /* passed from worker to main process */ @@ -377,7 +379,7 @@ out: worker->monitor = worker_monitor; worker->pid = pid; worker->state = WORKER_RUNNING; - worker->event_start_usec = now_usec(); + worker->event_start_usec = now(CLOCK_MONOTONIC); worker->event = event; event->state = EVENT_RUNNING; udev_list_node_append(&worker->node, &worker_list); @@ -408,7 +410,7 @@ static void event_run(struct event *event) worker_ref(worker); worker->event = event; worker->state = WORKER_RUNNING; - worker->event_start_usec = now_usec(); + worker->event_start_usec = now(CLOCK_MONOTONIC); event->state = EVENT_RUNNING; return; } @@ -438,8 +440,10 @@ static int event_queue_insert(struct udev_device *dev) event->devpath_len = strlen(event->devpath); event->devpath_old = udev_device_get_devpath_old(dev); event->devnum = udev_device_get_devnum(dev); - event->is_block = (strcmp("block", udev_device_get_subsystem(dev)) == 0); + event->is_block = streq("block", udev_device_get_subsystem(dev)); event->ifindex = udev_device_get_ifindex(dev); + if (streq(udev_device_get_subsystem(dev), "firmware")) + event->nodelay = true; udev_queue_export_device_queued(udev_queue_export, dev); log_debug("seq %llu queued, '%s' '%s'\n", udev_device_get_seqnum(dev), @@ -496,7 +500,7 @@ static bool is_devpath_busy(struct event *event) return true; /* check our old name */ - if (event->devpath_old != NULL && strcmp(loop_event->devpath, event->devpath_old) == 0) { + if (event->devpath_old != NULL && streq(loop_event->devpath, event->devpath_old)) { event->delaying_seqnum = loop_event->seqnum; return true; } @@ -519,6 +523,10 @@ static bool is_devpath_busy(struct event *event) return true; } + /* allow to bypass the dependency tracking */ + if (event->nodelay) + continue; + /* parent device event found */ if (event->devpath[common] == '/') { event->delaying_seqnum = loop_event->seqnum; @@ -719,7 +727,7 @@ static int handle_inotify(struct udev *udev) int fd; log_debug("device %s closed, synthesising 'change'\n", udev_device_get_devnode(dev)); - util_strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL); + strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL); fd = open(filename, O_WRONLY); if (fd >= 0) { if (write(fd, "change", 6) < 0) @@ -806,7 +814,7 @@ static void static_dev_create_from_modules(struct udev *udev) FILE *f; uname(&kernel); - util_strscpyl(modules, sizeof(modules), ROOTPREFIX "/lib/modules/", kernel.release, "/modules.devname", NULL); + strscpyl(modules, sizeof(modules), ROOTPREFIX "/lib/modules/", kernel.release, "/modules.devname", NULL); f = fopen(modules, "re"); if (f == NULL) return; @@ -853,7 +861,7 @@ static void static_dev_create_from_modules(struct udev *udev) else continue; - util_strscpyl(filename, sizeof(filename), "/dev/", devname, NULL); + strscpyl(filename, sizeof(filename), "/dev/", devname, NULL); mkdir_parents_label(filename, 0755); label_context_set(filename, mode); log_debug("mknod '%s' %c%u:%u\n", filename, type, maj, min); @@ -888,90 +896,6 @@ static int mem_size_mb(void) return memsize; } -static int convert_db(struct udev *udev) -{ - char filename[UTIL_PATH_SIZE]; - struct udev_enumerate *udev_enumerate; - struct udev_list_entry *list_entry; - - /* current database */ - if (access("/run/udev/data", F_OK) >= 0) - return 0; - - /* make sure we do not get here again */ - mkdir_p("/run/udev/data", 0755); - - /* old database */ - util_strscpyl(filename, sizeof(filename), "/dev/.udev/db", NULL); - if (access(filename, F_OK) < 0) - return 0; - - print_kmsg("converting old udev database\n"); - - udev_enumerate = udev_enumerate_new(udev); - if (udev_enumerate == NULL) - return -1; - udev_enumerate_scan_devices(udev_enumerate); - udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) { - struct udev_device *device; - - device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry)); - if (device == NULL) - continue; - - /* try to find the old database for devices without a current one */ - if (udev_device_read_db(device, NULL) < 0) { - bool have_db; - const char *id; - struct stat stats; - char devpath[UTIL_PATH_SIZE]; - char from[UTIL_PATH_SIZE]; - - have_db = false; - - /* find database in old location */ - id = udev_device_get_id_filename(device); - util_strscpyl(from, sizeof(from), "/dev/.udev/db/", id, NULL); - if (lstat(from, &stats) == 0) { - if (!have_db) { - udev_device_read_db(device, from); - have_db = true; - } - unlink(from); - } - - /* find old database with $subsys:$sysname name */ - util_strscpyl(from, sizeof(from), "/dev/.udev/db/", - udev_device_get_subsystem(device), ":", udev_device_get_sysname(device), NULL); - if (lstat(from, &stats) == 0) { - if (!have_db) { - udev_device_read_db(device, from); - have_db = true; - } - unlink(from); - } - - /* find old database with the encoded devpath name */ - util_path_encode(udev_device_get_devpath(device), devpath, sizeof(devpath)); - util_strscpyl(from, sizeof(from), "/dev/.udev/db/", devpath, NULL); - if (lstat(from, &stats) == 0) { - if (!have_db) { - udev_device_read_db(device, from); - have_db = true; - } - unlink(from); - } - - /* write out new database */ - if (have_db) - udev_device_update_db(device); - } - udev_device_unref(device); - } - udev_enumerate_unref(udev_enumerate); - return 0; -} - static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink) { int ctrl = -1, netlink = -1; @@ -1090,7 +1014,7 @@ int main(int argc, char *argv[]) for (;;) { int option; - option = getopt_long(argc, argv, "c:deDtN:hV", options, NULL); + option = getopt_long(argc, argv, "c:de:DtN:hV", options, NULL); if (option == -1) break; @@ -1110,11 +1034,11 @@ int main(int argc, char *argv[]) udev_set_log_priority(udev, LOG_DEBUG); break; case 'N': - if (strcmp (optarg, "early") == 0) { + if (streq(optarg, "early")) { resolve_names = 1; - } else if (strcmp (optarg, "late") == 0) { + } else if (streq(optarg, "late")) { resolve_names = 0; - } else if (strcmp (optarg, "never") == 0) { + } else if (streq(optarg, "never")) { resolve_names = -1; } else { fprintf(stderr, "resolve-names must be early, late or never\n"); @@ -1155,7 +1079,7 @@ int main(int argc, char *argv[]) mkdir("/run/udev", 0755); - dev_setup(); + dev_setup(NULL); static_dev_create_from_modules(udev); /* before opening new files, make sure std{in,out,err} fds are in a sane state */ @@ -1177,7 +1101,7 @@ int main(int argc, char *argv[]) } if (systemd_fds(udev, &fd_ctrl, &fd_netlink) >= 0) { - /* get control and netlink socket from from systemd */ + /* get control and netlink socket from systemd */ udev_ctrl = udev_ctrl_new_from_fd(udev, fd_ctrl); if (udev_ctrl == NULL) { log_error("error taking over udev control socket"); @@ -1347,9 +1271,6 @@ int main(int argc, char *argv[]) goto exit; } - /* if needed, convert old database from earlier udev version */ - convert_db(udev); - if (children_max <= 0) { int memsize = mem_size_mb(); @@ -1367,7 +1288,7 @@ int main(int argc, char *argv[]) udev_list_node_init(&worker_list); for (;;) { - static unsigned long long last_usec; + static usec_t last_usec; struct epoll_event ev[8]; int fdcount; int timeout; @@ -1438,7 +1359,7 @@ int main(int argc, char *argv[]) if (worker->state != WORKER_RUNNING) continue; - if ((now_usec() - worker->event_start_usec) > 30 * 1000 * 1000) { + if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * 1000 * 1000) { log_error("worker [%u] %s timeout; kill it\n", worker->pid, worker->event ? worker->event->devpath : ""); kill(worker->pid, SIGKILL); @@ -1472,13 +1393,13 @@ int main(int argc, char *argv[]) } /* check for changed config, every 3 seconds at most */ - if ((now_usec() - last_usec) > 3 * 1000 * 1000) { + if ((now(CLOCK_MONOTONIC) - last_usec) > 3 * 1000 * 1000) { if (udev_rules_check_timestamp(rules)) reload = true; if (udev_builtin_validate(udev)) reload = true; - last_usec = now_usec(); + last_usec = now(CLOCK_MONOTONIC); } /* reload requested, HUP signal received, rules changed, builtin changed */ @@ -1498,7 +1419,7 @@ int main(int argc, char *argv[]) dev = udev_monitor_receive_device(monitor); if (dev != NULL) { - udev_device_set_usec_initialized(dev, now_usec()); + udev_device_set_usec_initialized(dev, now(CLOCK_MONOTONIC)); if (event_queue_insert(dev) < 0) udev_device_unref(dev); }