From: Kay Sievers Date: Fri, 28 May 2010 10:07:27 +0000 (+0200) Subject: udevd: read debug settings from kernel commandline X-Git-Tag: 174~468 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=c830e98d6a8e43b1b5cc8470aa750960989778bc udevd: read debug settings from kernel commandline --- diff --git a/libudev/libudev-util.c b/libudev/libudev-util.c index 3a67b0cd5..030b78cd2 100644 --- a/libudev/libudev-util.c +++ b/libudev/libudev-util.c @@ -87,13 +87,13 @@ int util_log_priority(const char *priority) int prio; prio = strtol(priority, &endptr, 10); - if (endptr[0] == '\0') + if (endptr[0] == '\0' || isspace(endptr[0])) return prio; if (strncmp(priority, "err", 3) == 0) return LOG_ERR; - if (strcmp(priority, "info") == 0) + if (strncmp(priority, "info", 4) == 0) return LOG_INFO; - if (strcmp(priority, "debug") == 0) + if (strncmp(priority, "debug", 5) == 0) return LOG_DEBUG; return 0; } diff --git a/udev/udev-event.c b/udev/udev-event.c index 44e24313f..7591d5e31 100644 --- a/udev/udev-event.c +++ b/udev/udev-event.c @@ -681,6 +681,10 @@ int udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask) udev_event_apply_format(event, cmd, program, sizeof(program)); envp = udev_device_get_properties_envp(event->dev); + if (event->exec_delay > 0) { + info(event->udev, "delay execution of '%s'\n", program); + sleep(event->exec_delay); + } if (util_run_program(event->udev, program, envp, NULL, 0, NULL, sigmask, true) != 0) { if (udev_list_entry_get_flags(list_entry)) err = -1; diff --git a/udev/udev.h b/udev/udev.h index 4150c16af..23b720a46 100644 --- a/udev/udev.h +++ b/udev/udev.h @@ -43,6 +43,7 @@ struct udev_event { uid_t uid; gid_t gid; struct udev_list_node run_list; + int exec_delay; bool group_final; bool owner_final; bool mode_final; diff --git a/udev/udevd.c b/udev/udevd.c index 79a269ada..612f04d1b 100644 --- a/udev/udevd.c +++ b/udev/udevd.c @@ -79,6 +79,7 @@ static bool stop_exec_queue; static bool reload_config; static int children; static int children_max; +static int exec_delay; static sigset_t orig_sigmask; static struct udev_list_node event_list; static struct udev_list_node worker_list; @@ -285,6 +286,9 @@ static void worker_new(struct event *event) /* set timeout to prevent hanging processes */ alarm(UDEV_EVENT_TIMEOUT); + if (exec_delay > 0) + udev_event->exec_delay = exec_delay; + /* apply rules, create node, symlinks */ err = udev_event_execute_rules(udev_event, rules); @@ -386,7 +390,8 @@ static void event_run(struct event *event, bool force) } if (!force && children >= children_max) { - info(event->udev, "maximum number (%i) of children reached\n", children); + if (children_max > 1) + info(event->udev, "maximum number (%i) of children reached\n", children); return; } @@ -957,6 +962,7 @@ int main(int argc, char *argv[]) { "daemon", no_argument, NULL, 'd' }, { "debug", no_argument, NULL, 'D' }, { "children-max", required_argument, NULL, 'c' }, + { "exec-delay", required_argument, NULL, 'e' }, { "resolve-names", required_argument, NULL, 'N' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, @@ -976,7 +982,7 @@ int main(int argc, char *argv[]) for (;;) { int option; - option = getopt_long(argc, argv, "dDthV", options, NULL); + option = getopt_long(argc, argv, "cdeDthV", options, NULL); if (option == -1) break; @@ -985,7 +991,10 @@ int main(int argc, char *argv[]) daemonize = true; break; case 'c': - children_max = strtoul(optarg, NULL, 10); + children_max = strtoul(optarg, NULL, 0); + break; + case 'e': + exec_delay = strtoul(optarg, NULL, 0); break; case 'D': debug = true; @@ -1006,8 +1015,15 @@ int main(int argc, char *argv[]) } break; case 'h': - printf("Usage: udevd [--help] [--daemon] [--children-max] [--debug] " - "[--resolve-names=early|late|never] [--version]\n"); + printf("Usage: udevd OPTIONS\n" + " --daemon\n" + " --debug\n" + " --children-max=\n" + " --exec-delay=\n" + " --resolve-names=early|late|never\n" + " --version\n" + " --help\n" + "\n"); goto exit; case 'V': printf("%s\n", VERSION); @@ -1023,6 +1039,40 @@ int main(int argc, char *argv[]) goto exit; } + /* + * read the kernel commandline, in case we need to get into debug mode + * udev.log-priority= syslog priority + * udev.children-max= events are fully serialized if set to 1 + * + */ + f = fopen("/proc/cmdline", "r"); + if (f != NULL) { + char cmdline[4096]; + + if (fgets(cmdline, sizeof(cmdline), f) != NULL) { + char *pos; + + pos = strstr(cmdline, "udev.log-priority="); + if (pos != NULL) { + pos += strlen("udev.log-priority="); + udev_set_log_priority(udev, util_log_priority(pos)); + } + + pos = strstr(cmdline, "udev.children-max="); + if (pos != NULL) { + pos += strlen("udev.children-max="); + children_max = strtoul(pos, NULL, 0); + } + + pos = strstr(cmdline, "udev.exec-delay="); + if (pos != NULL) { + pos += strlen("udev.exec-delay="); + exec_delay = strtoul(pos, NULL, 0); + } + } + fclose(f); + } + /* make sure std{in,out,err} fds are in a sane state */ fd = open("/dev/null", O_RDWR); if (fd < 0) { @@ -1172,19 +1222,13 @@ int main(int argc, char *argv[]) } if (children_max <= 0) { - const char *value = getenv("UDEVD_CHILDREN_MAX"); + int memsize = mem_size_mb(); - if (value) { - children_max = strtoul(value, NULL, 10); - } else { - int memsize = mem_size_mb(); - - /* set value depending on the amount of RAM */ - if (memsize > 0) - children_max = 128 + (memsize / 8); - else - children_max = 128; - } + /* set value depending on the amount of RAM */ + if (memsize > 0) + children_max = 128 + (memsize / 8); + else + children_max = 128; } info(udev, "set children_max to %u\n", children_max);