summaryrefslogtreecommitdiff
path: root/src/udev
diff options
context:
space:
mode:
Diffstat (limited to 'src/udev')
-rw-r--r--src/udev/udevd.c174
1 files changed, 95 insertions, 79 deletions
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index f967f78172..83f65b27ba 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -53,8 +53,6 @@
#include "dev-setup.h"
#include "fileio.h"
-static bool debug;
-
void udev_main_log(struct udev *udev, int priority,
const char *file, int line, const char *fn,
const char *format, va_list args) {
@@ -71,10 +69,13 @@ static int fd_inotify = -1;
static bool stop_exec_queue;
static bool reload;
static int children;
-static int children_max;
-static int exec_delay;
-static usec_t event_timeout_usec = 180 * USEC_PER_SEC;
-static usec_t event_timeout_warn_usec = 180 * USEC_PER_SEC / 3;
+static bool arg_debug = false;
+static int arg_daemonize = false;
+static int arg_resolve_names = 1;
+static int arg_children_max;
+static int arg_exec_delay;
+static usec_t arg_event_timeout_usec = 180 * USEC_PER_SEC;
+static usec_t arg_event_timeout_warn_usec = 180 * USEC_PER_SEC / 3;
static sigset_t sigmask_orig;
static UDEV_LIST(event_list);
static UDEV_LIST(worker_list);
@@ -272,8 +273,8 @@ static void worker_new(struct event *event) {
/* needed for SIGCHLD/SIGTERM in spawn() */
udev_event->fd_signal = fd_signal;
- if (exec_delay > 0)
- udev_event->exec_delay = exec_delay;
+ if (arg_exec_delay > 0)
+ udev_event->exec_delay = arg_exec_delay;
/*
* Take a shared lock on the device node; this establishes
@@ -304,9 +305,9 @@ static void worker_new(struct event *event) {
}
/* apply rules, create node, symlinks */
- udev_event_execute_rules(udev_event, event_timeout_usec, event_timeout_warn_usec, rules, &sigmask_orig);
+ udev_event_execute_rules(udev_event, arg_event_timeout_usec, arg_event_timeout_warn_usec, rules, &sigmask_orig);
- udev_event_execute_run(udev_event, event_timeout_usec, event_timeout_warn_usec, &sigmask_orig);
+ udev_event_execute_run(udev_event, arg_event_timeout_usec, arg_event_timeout_warn_usec, &sigmask_orig);
/* apply/restore inotify watch */
if (udev_event->inotify_watch) {
@@ -433,8 +434,8 @@ static void event_run(struct event *event) {
return;
}
- if (children >= children_max) {
- if (children_max > 1)
+ if (children >= arg_children_max) {
+ if (arg_children_max > 1)
log_debug("maximum number (%i) of children reached", children);
return;
}
@@ -684,7 +685,7 @@ static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl) {
i = udev_ctrl_get_set_children_max(ctrl_msg);
if (i >= 0) {
log_debug("udevd message (SET_MAX_CHILDREN) received, children_max=%i", i);
- children_max = i;
+ arg_children_max = i;
}
if (udev_ctrl_get_ping(ctrl_msg) > 0)
@@ -1012,12 +1013,12 @@ static void kernel_cmdline_options(struct udev *udev) {
log_set_max_level(prio);
udev_set_log_priority(udev, prio);
} else if (startswith(opt, "udev.children-max=")) {
- children_max = strtoul(opt + 18, NULL, 0);
+ arg_children_max = strtoul(opt + 18, NULL, 0);
} else if (startswith(opt, "udev.exec-delay=")) {
- exec_delay = strtoul(opt + 16, NULL, 0);
+ arg_exec_delay = strtoul(opt + 16, NULL, 0);
} else if (startswith(opt, "udev.event-timeout=")) {
- event_timeout_usec = strtoul(opt + 16, NULL, 0) * USEC_PER_SEC;
- event_timeout_warn_usec = (event_timeout_usec / 3) ? : 1;
+ arg_event_timeout_usec = strtoul(opt + 16, NULL, 0) * USEC_PER_SEC;
+ arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1;
}
free(s);
@@ -1038,94 +1039,109 @@ static void help(void) {
, program_invocation_short_name);
}
-int main(int argc, char *argv[]) {
- struct udev *udev;
- sigset_t mask;
- int daemonize = false;
- int resolve_names = 1;
+static int parse_argv(int argc, char *argv[]) {
static const struct option options[] = {
- { "daemon", no_argument, NULL, 'd' },
- { "debug", no_argument, NULL, 'D' },
- { "children-max", required_argument, NULL, 'c' },
- { "exec-delay", required_argument, NULL, 'e' },
- { "event-timeout", required_argument, NULL, 't' },
- { "resolve-names", required_argument, NULL, 'N' },
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'V' },
+ { "daemon", no_argument, NULL, 'd' },
+ { "debug", no_argument, NULL, 'D' },
+ { "children-max", required_argument, NULL, 'c' },
+ { "exec-delay", required_argument, NULL, 'e' },
+ { "event-timeout", required_argument, NULL, 't' },
+ { "resolve-names", required_argument, NULL, 'N' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'V' },
{}
};
- int fd_ctrl = -1;
- int fd_netlink = -1;
- int fd_worker = -1;
- struct epoll_event ep_ctrl, ep_inotify, ep_signal, ep_netlink, ep_worker;
- struct udev_ctrl_connection *ctrl_conn = NULL;
- int rc = 1;
+ int c;
- udev = udev_new();
- if (udev == NULL)
- goto exit;
+ assert(argc >= 0);
+ assert(argv);
- log_set_target(LOG_TARGET_AUTO);
- log_open();
+ while ((c = getopt_long(argc, argv, "c:de:DtN:hV", options, NULL)) >= 0) {
- udev_set_log_fn(udev, udev_main_log);
- log_set_max_level(udev_get_log_priority(udev));
-
- log_debug("version %s", VERSION);
- label_init("/dev");
- for (;;) {
- int option;
-
- option = getopt_long(argc, argv, "c:de:DtN:hV", options, NULL);
- if (option == -1)
- break;
+ switch (c) {
- switch (option) {
case 'd':
- daemonize = true;
+ arg_daemonize = true;
break;
case 'c':
- children_max = strtoul(optarg, NULL, 0);
+ arg_children_max = strtoul(optarg, NULL, 0);
break;
case 'e':
- exec_delay = strtoul(optarg, NULL, 0);
+ arg_exec_delay = strtoul(optarg, NULL, 0);
break;
case 't':
- event_timeout_usec = strtoul(optarg, NULL, 0) * USEC_PER_SEC;
- event_timeout_warn_usec = (event_timeout_usec / 3) ? : 1;
+ arg_event_timeout_usec = strtoul(optarg, NULL, 0) * USEC_PER_SEC;
+ arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1;
break;
case 'D':
- debug = true;
- log_set_max_level(LOG_DEBUG);
- udev_set_log_priority(udev, LOG_DEBUG);
+ arg_debug = true;
break;
case 'N':
if (streq(optarg, "early")) {
- resolve_names = 1;
+ arg_resolve_names = 1;
} else if (streq(optarg, "late")) {
- resolve_names = 0;
+ arg_resolve_names = 0;
} else if (streq(optarg, "never")) {
- resolve_names = -1;
+ arg_resolve_names = -1;
} else {
fprintf(stderr, "resolve-names must be early, late or never\n");
log_error("resolve-names must be early, late or never");
- goto exit;
+ return 0;
}
break;
case 'h':
help();
- goto exit;
+ return 0;
case 'V':
printf("%s\n", UDEV_VERSION);
- goto exit;
+ return 0;
+ case '?':
+ return -EINVAL;
default:
- goto exit;
+ assert_not_reached("Unhandled option");
+
}
}
+ return 1;
+}
+
+int main(int argc, char *argv[]) {
+ struct udev *udev;
+ sigset_t mask;
+ int fd_ctrl = -1;
+ int fd_netlink = -1;
+ int fd_worker = -1;
+ struct epoll_event ep_ctrl, ep_inotify, ep_signal, ep_netlink, ep_worker;
+ struct udev_ctrl_connection *ctrl_conn = NULL;
+ int rc = 1, r;
+
+ udev = udev_new();
+ if (udev == NULL)
+ goto exit;
+
+ log_set_target(LOG_TARGET_AUTO);
+ log_parse_environment();
+ log_open();
+
+ udev_set_log_fn(udev, udev_main_log);
+ log_set_max_level(udev_get_log_priority(udev));
+
+ log_debug("version %s", VERSION);
+ label_init("/dev");
+
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ goto exit;
+
kernel_cmdline_options(udev);
+ if (arg_debug) {
+ log_set_max_level(LOG_DEBUG);
+ udev_set_log_priority(udev, LOG_DEBUG);
+ }
+
if (getuid() != 0) {
fprintf(stderr, "root privileges required\n");
log_error("root privileges required");
@@ -1145,7 +1161,7 @@ int main(int argc, char *argv[]) {
static_dev_create_from_modules(udev);
/* before opening new files, make sure std{in,out,err} fds are in a sane state */
- if (daemonize) {
+ if (arg_daemonize) {
int fd;
fd = open("/dev/null", O_RDWR);
@@ -1197,7 +1213,7 @@ int main(int argc, char *argv[]) {
udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024);
- if (daemonize) {
+ if (arg_daemonize) {
pid_t pid;
pid = fork();
@@ -1220,7 +1236,7 @@ int main(int argc, char *argv[]) {
log_info("starting version " VERSION "\n");
- if (!debug) {
+ if (!arg_debug) {
int fd;
fd = open("/dev/null", O_RDWR);
@@ -1275,7 +1291,7 @@ int main(int argc, char *argv[]) {
udev_builtin_init(udev);
- rules = udev_rules_new(udev, resolve_names);
+ rules = udev_rules_new(udev, arg_resolve_names);
if (rules == NULL) {
log_error("error reading rules");
goto exit;
@@ -1315,16 +1331,16 @@ int main(int argc, char *argv[]) {
goto exit;
}
- if (children_max <= 0) {
+ if (arg_children_max <= 0) {
cpu_set_t cpu_set;
- children_max = 8;
+ arg_children_max = 8;
if (sched_getaffinity(0, sizeof (cpu_set), &cpu_set) == 0) {
- children_max += CPU_COUNT(&cpu_set) * 2;
+ arg_children_max += CPU_COUNT(&cpu_set) * 2;
}
}
- log_debug("set children_max to %u", children_max);
+ log_debug("set children_max to %u", arg_children_max);
rc = udev_rules_apply_static_dev_perms(rules);
if (rc < 0)
@@ -1420,8 +1436,8 @@ int main(int argc, char *argv[]) {
ts = now(CLOCK_MONOTONIC);
- if ((ts - worker->event_start_usec) > event_timeout_warn_usec) {
- if ((ts - worker->event_start_usec) > event_timeout_usec) {
+ if ((ts - worker->event_start_usec) > arg_event_timeout_warn_usec) {
+ if ((ts - worker->event_start_usec) > arg_event_timeout_usec) {
log_error("worker [%u] %s timeout; kill it", worker->pid, worker->event->devpath);
kill(worker->pid, SIGKILL);
worker->state = WORKER_KILLED;
@@ -1492,7 +1508,7 @@ int main(int argc, char *argv[]) {
if (!udev_list_node_is_empty(&event_list) && !udev_exit && !stop_exec_queue) {
udev_builtin_init(udev);
if (rules == NULL)
- rules = udev_rules_new(udev, resolve_names);
+ rules = udev_rules_new(udev, arg_resolve_names);
if (rules != NULL)
event_queue_start(udev);
}