X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=udev%2Fudevd.c;h=23d594f5569312c57bebdbd1219473f06f94147d;hb=f9b3f88f71f5bdfb18aa4bfba00d72fa41fdf286;hp=d9de26ea6cc705e8912bebc897ae3451f8d021fc;hpb=116254097ad3c07d9f7ed06042dbec7ba4f0f4fd;p=elogind.git diff --git a/udev/udevd.c b/udev/udevd.c index d9de26ea6..23d594f55 100644 --- a/udev/udevd.c +++ b/udev/udevd.c @@ -67,10 +67,10 @@ static int debug_trace; static struct udev_rules *rules; static struct udev_ctrl *udev_ctrl; static struct udev_monitor *kernel_monitor; -static volatile int sigchilds_waiting; -static volatile int udev_exit; -static volatile int reload_config; -static volatile int signal_received; +static volatile sig_atomic_t sigchilds_waiting; +static volatile sig_atomic_t udev_exit; +static volatile sig_atomic_t reload_config; +static volatile sig_atomic_t signal_received; static volatile pid_t settle_pid; static int run_exec_q; static int stop_exec_q; @@ -97,18 +97,17 @@ static void export_event_state(struct udev_event *event, enum event_state state) { char filename[UTIL_PATH_SIZE]; char filename_failed[UTIL_PATH_SIZE]; - size_t start; + char *s; + size_t l; /* location of queue file */ snprintf(filename, sizeof(filename), "%s/.udev/queue/%llu", udev_get_dev_path(event->udev), udev_device_get_seqnum(event->dev)); /* location of failed file */ - util_strlcpy(filename_failed, udev_get_dev_path(event->udev), sizeof(filename_failed)); - util_strlcat(filename_failed, "/", sizeof(filename_failed)); - start = util_strlcat(filename_failed, ".udev/failed/", sizeof(filename_failed)); - util_strlcat(filename_failed, udev_device_get_devpath(event->dev), sizeof(filename_failed)); - util_path_encode(&filename_failed[start], sizeof(filename_failed) - start); + s = filename_failed; + l = util_strpcpyl(&s, sizeof(filename_failed), udev_get_dev_path(event->udev), "/.udev/failed/", NULL); + util_path_encode(udev_device_get_devpath(event->dev), s, l); switch (state) { case EVENT_QUEUED: @@ -124,12 +123,9 @@ static void export_event_state(struct udev_event *event, enum event_state state) /* "move" event - rename failed file to current name, do not delete failed */ char filename_failed_old[UTIL_PATH_SIZE]; - util_strlcpy(filename_failed_old, udev_get_dev_path(event->udev), sizeof(filename_failed_old)); - util_strlcat(filename_failed_old, "/", sizeof(filename_failed_old)); - start = util_strlcat(filename_failed_old, ".udev/failed/", sizeof(filename_failed_old)); - util_strlcat(filename_failed_old, udev_device_get_devpath_old(event->dev), sizeof(filename_failed_old)); - util_path_encode(&filename_failed_old[start], sizeof(filename) - start); - + s = filename_failed_old; + l = util_strpcpyl(&s, sizeof(filename_failed_old), udev_get_dev_path(event->udev), "/.udev/failed/", NULL); + util_path_encode(udev_device_get_devpath_old(event->dev), s, l); if (rename(filename_failed_old, filename_failed) == 0) info(event->udev, "renamed devpath, moved failed state of '%s' to %s'\n", udev_device_get_devpath_old(event->dev), udev_device_get_devpath(event->dev)); @@ -172,10 +168,10 @@ static void event_queue_delete(struct udev_event *event) udev_event_unref(event); } -static void asmlinkage event_sig_handler(int signum) +static void event_sig_handler(int signum) { if (signum == SIGALRM) - exit(1); + _exit(1); } static void event_fork(struct udev_event *event) @@ -184,6 +180,16 @@ static void event_fork(struct udev_event *event) struct sigaction act; int err; +#if 0 + /* single process, no forking, just for testing/profiling */ + err = udev_event_execute_rules(event, rules); + if (err == 0 && !event->ignore_device && udev_get_run(event->udev)) + udev_event_execute_run(event); + info(event->udev, "seq %llu exit with %i\n", udev_device_get_seqnum(event->dev), err); + event_queue_delete(event); + return; +#endif + if (debug_trace) { event->trace = 1; fprintf(stderr, "fork %s (%llu)\n", @@ -202,7 +208,7 @@ static void event_fork(struct udev_event *event) /* set signal handlers */ memset(&act, 0x00, sizeof(act)); - act.sa_handler = (void (*)(int)) event_sig_handler; + act.sa_handler = event_sig_handler; sigemptyset (&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, NULL); @@ -270,8 +276,7 @@ static void event_queue_insert(struct udev_event *event) info(event->udev, "seq %llu queued, '%s' '%s'\n", udev_device_get_seqnum(event->dev), udev_device_get_action(event->dev), udev_device_get_subsystem(event->dev)); - util_strlcpy(filename, udev_get_dev_path(event->udev), sizeof(filename)); - util_strlcat(filename, "/.udev/uevent_seqnum", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/.udev/uevent_seqnum", NULL); fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644); if (fd >= 0) { char str[32]; @@ -295,7 +300,7 @@ static void event_queue_insert(struct udev_event *event) static int mem_size_mb(void) { - FILE* f; + FILE *f; char buf[4096]; long int memsize = -1; @@ -339,13 +344,11 @@ static int compare_devpath(const char *running, const char *waiting) return 0; } -/* lookup event for identical, parent, child, or physical device */ +/* lookup event for identical, parent, child device */ static int devpath_busy(struct udev_event *event) { struct udev_list_node *loop; - if (event->delaying_seqnum > 0) { - } /* check if queue contains events we depend on */ udev_list_node_foreach(loop, &event_list) { struct udev_event *loop_event = node_to_event(loop); @@ -390,19 +393,6 @@ static int devpath_busy(struct udev_event *event) event->delaying_seqnum = udev_device_get_seqnum(loop_event->dev); return 5; } - - /* check physical device event (special case of parent) */ - if (udev_device_get_physdevpath(event->dev) != NULL && - strcmp(udev_device_get_action(event->dev), "add") == 0) - if (compare_devpath(udev_device_get_devpath(loop_event->dev), - udev_device_get_physdevpath(event->dev)) != 0) { - dbg(event->udev, "%llu, physical device event still pending %llu (%s)\n", - udev_device_get_seqnum(event->dev), - udev_device_get_seqnum(loop_event->dev), - udev_device_get_devpath(loop_event->dev)); - event->delaying_seqnum = udev_device_get_seqnum(loop_event->dev); - return 6; - } } return 0; } @@ -564,8 +554,7 @@ static int handle_inotify(struct udev *udev) int fd; info(udev, "device %s closed, synthesising 'change'\n", udev_device_get_devnode(dev)); - util_strlcpy(filename, udev_device_get_syspath(dev), sizeof(filename)); - util_strlcat(filename, "/uevent", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL); fd = open(filename, O_WRONLY); if (fd < 0 || write(fd, "change", 6) < 0) info(udev, "error writing uevent: %m\n"); @@ -583,7 +572,7 @@ static int handle_inotify(struct udev *udev) return 0; } -static void asmlinkage sig_handler(int signum) +static void sig_handler(int signum) { switch (signum) { case SIGINT: @@ -654,12 +643,10 @@ static void cleanup_queue_dir(struct udev *udev) char filename[UTIL_PATH_SIZE]; DIR *dir; - util_strlcpy(filename, udev_get_dev_path(udev), sizeof(filename)); - util_strlcat(filename, "/.udev/uevent_seqnum", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/uevent_seqnum", NULL); unlink(filename); - util_strlcpy(dirname, udev_get_dev_path(udev), sizeof(dirname)); - util_strlcat(dirname, "/.udev/queue", sizeof(dirname)); + util_strscpyl(dirname, sizeof(dirname), udev_get_dev_path(udev), "/.udev/queue", NULL); dir = opendir(dirname); if (dir != NULL) { while (1) { @@ -670,10 +657,7 @@ static void cleanup_queue_dir(struct udev *udev) break; if (dent->d_name[0] == '.') continue; - util_strlcpy(filename, dirname, sizeof(filename)); - util_strlcat(filename, "/", sizeof(filename)); - util_strlcat(filename, dent->d_name, sizeof(filename)); - unlink(filename); + unlinkat(dirfd(dir), dent->d_name, 0); } closedir(dir); rmdir(dirname); @@ -687,8 +671,7 @@ static void export_initial_seqnum(struct udev *udev) char seqnum[32]; ssize_t len = 0; - util_strlcpy(filename, udev_get_sys_path(udev), sizeof(filename)); - util_strlcat(filename, "/kernel/uevent_seqnum", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_get_sys_path(udev), "/kernel/uevent_seqnum", NULL); fd = open(filename, O_RDONLY); if (fd >= 0) { len = read(fd, seqnum, sizeof(seqnum)-1); @@ -698,8 +681,7 @@ static void export_initial_seqnum(struct udev *udev) strcpy(seqnum, "0\n"); len = 3; } - util_strlcpy(filename, udev_get_dev_path(udev), sizeof(filename)); - util_strlcat(filename, "/.udev/uevent_seqnum", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/uevent_seqnum", NULL); util_create_path(udev, filename); fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644); if (fd >= 0) { @@ -708,6 +690,33 @@ static void export_initial_seqnum(struct udev *udev) } } +static void startup_log(struct udev *udev) +{ + FILE *f; + char path[UTIL_PATH_SIZE]; + struct stat statbuf; + + f = fopen("/dev/kmsg", "w"); + if (f != NULL) + fprintf(f, "<6>udev: starting version " VERSION "\n"); + + util_strscpyl(path, sizeof(path), udev_get_sys_path(udev), "/class/mem/null", NULL); + if (lstat(path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) { + const char *depr_str = + "udev: missing sysfs features; please update the kernel " + "or disable the kernel's CONFIG_SYSFS_DEPRECATED option; " + "udev may fail to work correctly"; + + if (f != NULL) + fprintf(f, "<3>%s\n", depr_str); + err(udev, "%s\n", depr_str); + sleep(3); + } + + if (f != NULL) + fclose(f); +} + int main(int argc, char *argv[]) { struct udev *udev; @@ -813,7 +822,7 @@ int main(int argc, char *argv[]) goto exit; } - kernel_monitor = udev_monitor_new_from_netlink(udev, UDEV_MONITOR_KERNEL); + kernel_monitor = udev_monitor_new_from_netlink(udev, "kernel"); if (kernel_monitor == NULL || udev_monitor_enable_receiving(kernel_monitor) < 0) { fprintf(stderr, "error initializing netlink socket\n"); err(udev, "error initializing netlink socket\n"); @@ -875,31 +884,11 @@ int main(int argc, char *argv[]) close(fd); } - fd = open("/dev/kmsg", O_WRONLY); - if (fd > 0) { - const char *ver_str = "<6>udev: starting version " VERSION "\n"; - char path[UTIL_PATH_SIZE]; - struct stat statbuf; - - write(fd, ver_str, strlen(ver_str)); - util_strlcpy(path, udev_get_sys_path(udev), sizeof(path)); - util_strlcat(path, "/class/mem/null", sizeof(path)); - if (lstat(path, &statbuf) == 0) { - if (S_ISDIR(statbuf.st_mode)) { - const char *depr_str = - "<6>udev: deprecated sysfs layout; update the kernel or " - "disable CONFIG_SYSFS_DEPRECATED; some udev features will " - "not work correctly\n"; - - write(fd, depr_str, strlen(depr_str)); - } - } - close(fd); - } + startup_log(udev); /* set signal handlers */ memset(&act, 0x00, sizeof(struct sigaction)); - act.sa_handler = (void (*)(int)) sig_handler; + act.sa_handler = sig_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; sigaction(SIGINT, &act, NULL); @@ -922,8 +911,7 @@ int main(int argc, char *argv[]) IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE); /* watch dynamic rules directory */ - util_strlcpy(filename, udev_get_dev_path(udev), sizeof(filename)); - util_strlcat(filename, "/.udev/rules.d", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/rules.d", NULL); inotify_add_watch(inotify_fd, filename, IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE); }