#include "dev-setup.h"
#include "fileio.h"
-void udev_main_log(struct udev *udev, int priority,
- const char *file, int line, const char *fn,
- const char *format, va_list args) {
- log_metav(priority, file, line, fn, format, args);
-}
-
static struct udev_rules *rules;
static struct udev_ctrl *udev_ctrl;
static struct udev_monitor *monitor;
static UDEV_LIST(event_list);
static UDEV_LIST(worker_list);
static char *udev_cgroup;
+static struct udev_list properties_list;
static bool udev_exit;
enum event_state {
sigfillset(&mask);
fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
if (fd_signal < 0) {
- log_error("error creating signalfd %m");
+ log_error_errno(errno, "error creating signalfd %m");
rc = 2;
goto out;
}
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
- log_error("error creating epoll fd: %m");
+ log_error_errno(errno, "error creating epoll fd: %m");
rc = 3;
goto out;
}
if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_monitor, &ep_monitor) < 0) {
- log_error("fail to add fds to epoll: %m");
+ log_error_errno(errno, "fail to add fds to epoll: %m");
rc = 4;
goto out;
}
if (d) {
fd_lock = open(udev_device_get_devnode(d), O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
if (fd_lock >= 0 && flock(fd_lock, LOCK_SH|LOCK_NB) < 0) {
- log_debug("Unable to flock(%s), skipping event handling: %m", udev_device_get_devnode(d));
+ log_debug_errno(errno, "Unable to flock(%s), skipping event handling: %m", udev_device_get_devnode(d));
err = -EWOULDBLOCK;
fd_lock = safe_close(fd_lock);
goto skip;
udev_event->rtnl = rtnl;
/* apply rules, create node, symlinks */
- udev_event_execute_rules(udev_event, arg_event_timeout_usec, arg_event_timeout_warn_usec, rules, &sigmask_orig);
+ udev_event_execute_rules(udev_event,
+ arg_event_timeout_usec, arg_event_timeout_warn_usec,
+ &properties_list,
+ rules,
+ &sigmask_orig);
- udev_event_execute_run(udev_event, arg_event_timeout_usec, arg_event_timeout_warn_usec, &sigmask_orig);
+ udev_event_execute_run(udev_event,
+ arg_event_timeout_usec, arg_event_timeout_warn_usec,
+ &sigmask_orig);
- /* in case rtnl was initialized */
- rtnl = sd_rtnl_ref(udev_event->rtnl);
+ if (udev_event->rtnl)
+ /* in case rtnl was initialized */
+ rtnl = sd_rtnl_ref(udev_event->rtnl);
/* apply/restore inotify watch */
if (udev_event->inotify_watch) {
if (fdcount < 0) {
if (errno == EINTR)
continue;
- log_error("failed to poll: %m");
+ log_error_errno(errno, "failed to poll: %m");
goto out;
}
udev_monitor_unref(worker_monitor);
event->state = EVENT_QUEUED;
free(worker);
- log_error("fork of child failed: %m");
+ log_error_errno(errno, "fork of child failed: %m");
break;
default:
/* close monitor, but keep address around */
count = udev_monitor_send_device(monitor, worker->monitor, event->dev);
if (count < 0) {
- log_error("worker [%u] did not accept message %zi (%m), kill it", worker->pid, count);
+ log_error_errno(errno, "worker [%u] did not accept message %zi (%m), kill it", worker->pid, count);
kill(worker->pid, SIGKILL);
worker->state = WORKER_KILLED;
continue;
if (i >= 0) {
log_debug("udevd message (SET_LOG_LEVEL) received, log_priority=%i", i);
log_set_max_level(i);
- udev_set_log_priority(udev, i);
worker_kill(udev);
}
val = &val[1];
if (val[0] == '\0') {
log_debug("udevd message (ENV) received, unset '%s'", key);
- udev_add_property(udev, key, NULL);
+ udev_list_entry_add(&properties_list, key, NULL);
} else {
log_debug("udevd message (ENV) received, set '%s=%s'", key, val);
- udev_add_property(udev, key, val);
+ udev_list_entry_add(&properties_list, key, val);
}
} else {
log_error("wrong key format '%s'", key);
}
/*
- * read the kernel commandline, in case we need to get into debug mode
+ * read the kernel command line, in case we need to get into debug mode
* udev.log-priority=<level> syslog priority
* udev.children-max=<number of workers> events are fully serialized if set to 1
* udev.exec-delay=<number of seconds> delay execution of every executed program
int r;
r = proc_cmdline(&line);
- if (r < 0)
- log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
- if (r <= 0)
+ if (r < 0) {
+ log_warning_errno(r, "Failed to read /proc/cmdline, ignoring: %m");
return;
+ }
FOREACH_WORD_QUOTED(word, l, line, state) {
- char *s, *opt;
+ char *s, *opt, *value;
s = strndup(word, l);
if (!s)
else
opt = s;
- if (startswith(opt, "udev.log-priority=")) {
+ if ((value = startswith(opt, "udev.log-priority="))) {
int prio;
- prio = util_log_priority(opt + 18);
+ prio = util_log_priority(value);
log_set_max_level(prio);
- udev_set_log_priority(udev, prio);
- } else if (startswith(opt, "udev.children-max=")) {
- arg_children_max = strtoul(opt + 18, NULL, 0);
- } else if (startswith(opt, "udev.exec-delay=")) {
- arg_exec_delay = strtoul(opt + 16, NULL, 0);
- } else if (startswith(opt, "udev.event-timeout=")) {
- arg_event_timeout_usec = strtoul(opt + 16, NULL, 0) * USEC_PER_SEC;
+ } else if ((value = startswith(opt, "udev.children-max="))) {
+ r = safe_atoi(value, &arg_children_max);
+ if (r < 0)
+ log_warning("Invalid udev.children-max ignored: %s", value);
+ } else if ((value = startswith(opt, "udev.exec-delay="))) {
+ r = safe_atoi(value, &arg_exec_delay);
+ if (r < 0)
+ log_warning("Invalid udev.exec-delay ignored: %s", value);
+ } else if ((value = startswith(opt, "udev.event-timeout="))) {
+ r = safe_atou64(value, &arg_event_timeout_usec);
+ if (r < 0) {
+ log_warning("Invalid udev.event-timeout ignored: %s", value);
+ break;
+ }
+ arg_event_timeout_usec *= USEC_PER_SEC;
arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1;
}
assert(argv);
while ((c = getopt_long(argc, argv, "c:de:DtN:hV", options, NULL)) >= 0) {
+ int r;
switch (c) {
arg_daemonize = true;
break;
case 'c':
- arg_children_max = strtoul(optarg, NULL, 0);
+ r = safe_atoi(optarg, &arg_children_max);
+ if (r < 0)
+ log_warning("Invalid --children-max ignored: %s", optarg);
break;
case 'e':
- arg_exec_delay = strtoul(optarg, NULL, 0);
+ r = safe_atoi(optarg, &arg_exec_delay);
+ if (r < 0)
+ log_warning("Invalid --exec-delay ignored: %s", optarg);
break;
case 't':
- arg_event_timeout_usec = strtoul(optarg, NULL, 0) * USEC_PER_SEC;
- arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1;
+ r = safe_atou64(optarg, &arg_event_timeout_usec);
+ if (r < 0)
+ log_warning("Invalid --event-timeout ignored: %s", optarg);
+ else {
+ arg_event_timeout_usec *= USEC_PER_SEC;
+ arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1;
+ }
break;
case 'D':
arg_debug = true;
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) {
+ if (arg_debug)
log_set_max_level(LOG_DEBUG);
- udev_set_log_priority(udev, LOG_DEBUG);
- }
if (getuid() != 0) {
log_error("root privileges required");
goto exit;
}
+ r = mac_selinux_init("/dev");
+ if (r < 0) {
+ log_error_errno(r, "could not initialize labelling: %m");
+ goto exit;
+ }
+
/* set umask before creating any file/directory */
- chdir("/");
+ r = chdir("/");
+ if (r < 0) {
+ log_error_errno(errno, "could not change dir to /: %m");
+ goto exit;
+ }
+
umask(022);
- mkdir("/run/udev", 0755);
+ udev_list_init(udev, &properties_list, true);
+
+ r = mkdir("/run/udev", 0755);
+ if (r < 0 && errno != EEXIST) {
+ log_error_errno(errno, "could not create /run/udev: %m");
+ goto exit;
+ }
dev_setup(NULL);
goto exit;
}
fd_netlink = udev_monitor_get_fd(monitor);
+
+ udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024);
}
if (udev_monitor_enable_receiving(monitor) < 0) {
goto exit;
}
- udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024);
+ log_info("starting version " VERSION);
+
+ udev_builtin_init(udev);
+
+ rules = udev_rules_new(udev, arg_resolve_names);
+ if (rules == NULL) {
+ log_error("error reading rules");
+ goto exit;
+ }
+
+ rc = udev_rules_apply_static_dev_perms(rules);
+ if (rc < 0)
+ log_error_errno(rc, "failed to apply permissions on static device nodes - %m");
if (arg_daemonize) {
pid_t pid;
case 0:
break;
case -1:
- log_error("fork of daemon failed: %m");
+ log_error_errno(errno, "fork of daemon failed: %m");
rc = 4;
goto exit;
default:
sd_notify(1, "READY=1");
}
- log_info("starting version " VERSION "\n");
-
- udev_builtin_init(udev);
-
- rules = udev_rules_new(udev, arg_resolve_names);
- if (rules == NULL) {
- log_error("error reading rules");
- goto exit;
- }
-
- rc = udev_rules_apply_static_dev_perms(rules);
- if (rc < 0)
- log_error("failed to apply permissions on static device nodes - %s", strerror(-rc));
-
if (arg_children_max <= 0) {
cpu_set_t cpu_set;
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
- log_error("error creating epoll fd: %m");
+ log_error_errno(errno, "error creating epoll fd: %m");
goto exit;
}
if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_ctrl, &ep_ctrl) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_netlink, &ep_netlink) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_worker, &ep_worker) < 0) {
- log_error("fail to add fds to epoll: %m");
+ log_error_errno(errno, "fail to add fds to epoll: %m");
goto exit;
}
udev_monitor_unref(monitor);
udev_ctrl_connection_unref(ctrl_conn);
udev_ctrl_unref(udev_ctrl);
- label_finish();
+ udev_list_cleanup(&properties_list);
+ mac_selinux_finish();
udev_unref(udev);
log_close();
return rc;