]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: move parsers for config file, kerenel command line, and positional arguments...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 3 Dec 2024 17:33:47 +0000 (02:33 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 19 Dec 2024 03:28:44 +0000 (12:28 +0900)
No functional change, just refactoring and preparation for later
commits.

src/udev/meson.build
src/udev/udev-config.c [new file with mode: 0644]
src/udev/udev-config.h [new file with mode: 0644]
src/udev/udev-manager.c
src/udev/udev-manager.h
src/udev/udevd.c

index 3535551e7440dbd12e6b9f6f217ba94c1684a171..dff5a5a5e9cbaad66b674f4fdfc9dfb71796bc39 100644 (file)
@@ -19,6 +19,7 @@ udevadm_sources = files(
 
 libudevd_core_sources = files(
         'net/link-config.c',
+        'udev-config.c',
         'udev-ctrl.c',
         'udev-event.c',
         'udev-format.c',
diff --git a/src/udev/udev-config.c b/src/udev/udev-config.c
new file mode 100644 (file)
index 0000000..b774e76
--- /dev/null
@@ -0,0 +1,311 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <getopt.h>
+#include <unistd.h>
+
+#include "conf-parser.h"
+#include "cpu-set-util.h"
+#include "limits-util.h"
+#include "parse-util.h"
+#include "pretty-print.h"
+#include "proc-cmdline.h"
+#include "signal-util.h"
+#include "syslog-util.h"
+#include "udev-config.h"
+#include "udev-manager.h"
+#include "udev-rules.h"
+#include "udev-util.h"
+#include "udev-worker.h"
+#include "version.h"
+
+#define WORKER_NUM_MAX UINT64_C(2048)
+
+static bool arg_debug = false;
+bool arg_daemonize = false;
+
+static DEFINE_CONFIG_PARSE_ENUM(config_parse_resolve_name_timing, resolve_name_timing, ResolveNameTiming);
+
+static int manager_parse_udev_config(Manager *manager) {
+        int r, log_val = -1;
+
+        assert(manager);
+
+        const ConfigTableItem config_table[] = {
+                { NULL, "udev_log",       config_parse_log_level,           0, &log_val                      },
+                { NULL, "children_max",   config_parse_unsigned,            0, &manager->children_max        },
+                { NULL, "exec_delay",     config_parse_sec,                 0, &manager->exec_delay_usec     },
+                { NULL, "event_timeout",  config_parse_sec,                 0, &manager->timeout_usec        },
+                { NULL, "resolve_names",  config_parse_resolve_name_timing, 0, &manager->resolve_name_timing },
+                { NULL, "timeout_signal", config_parse_signal,              0, &manager->timeout_signal      },
+                {}
+        };
+
+        r = udev_parse_config_full(config_table);
+        if (r < 0)
+                return r;
+
+        if (log_val >= 0)
+                log_set_max_level(log_val);
+
+        return 0;
+}
+
+/*
+ * read the kernel command line, in case we need to get into debug mode
+ *   udev.log_level=<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
+ *   udev.event_timeout=<number of seconds>    seconds to wait before terminating an event
+ *   udev.blockdev_read_only<=bool>            mark all block devices read-only when they appear
+ */
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
+        Manager *manager = ASSERT_PTR(data);
+        int r;
+
+        assert(key);
+
+        if (proc_cmdline_key_streq(key, "udev.log_level") ||
+            proc_cmdline_key_streq(key, "udev.log_priority")) { /* kept for backward compatibility */
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
+
+                r = log_level_from_string(value);
+                if (r >= 0)
+                        manager->log_level = r;
+
+        } else if (proc_cmdline_key_streq(key, "udev.event_timeout")) {
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
+
+                r = parse_sec(value, &manager->timeout_usec);
+
+        } else if (proc_cmdline_key_streq(key, "udev.children_max")) {
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
+
+                r = safe_atou(value, &manager->children_max);
+
+        } else if (proc_cmdline_key_streq(key, "udev.exec_delay")) {
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
+
+                r = parse_sec(value, &manager->exec_delay_usec);
+
+        } else if (proc_cmdline_key_streq(key, "udev.timeout_signal")) {
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
+
+                r = signal_from_string(value);
+                if (r > 0)
+                        manager->timeout_signal = r;
+
+        } else if (proc_cmdline_key_streq(key, "udev.blockdev_read_only")) {
+
+                if (!value)
+                        manager->blockdev_read_only = true;
+                else {
+                        r = parse_boolean(value);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to parse udev.blockdev-read-only argument, ignoring: %s", value);
+                        else
+                                manager->blockdev_read_only = r;
+                }
+
+                if (manager->blockdev_read_only)
+                        log_notice("All physical block devices will be marked read-only.");
+
+                return 0;
+
+        } else {
+                if (startswith(key, "udev."))
+                        log_warning("Unknown udev kernel command line option \"%s\", ignoring.", key);
+
+                return 0;
+        }
+
+        if (r < 0)
+                log_warning_errno(r, "Failed to parse \"%s=%s\", ignoring: %m", key, value);
+
+        return 0;
+}
+
+static int help(void) {
+        _cleanup_free_ char *link = NULL;
+        int r;
+
+        r = terminal_urlify_man("systemd-udevd.service", "8", &link);
+        if (r < 0)
+                return log_oom();
+
+        printf("%s [OPTIONS...]\n\n"
+               "Rule-based manager for device events and files.\n\n"
+               "  -h --help                   Print this message\n"
+               "  -V --version                Print version of the program\n"
+               "  -d --daemon                 Detach and run in the background\n"
+               "  -D --debug                  Enable debug output\n"
+               "  -c --children-max=INT       Set maximum number of workers\n"
+               "  -e --exec-delay=SECONDS     Seconds to wait before executing RUN=\n"
+               "  -t --event-timeout=SECONDS  Seconds to wait before terminating an event\n"
+               "  -N --resolve-names=early|late|never\n"
+               "                              When to resolve users and groups\n"
+               "\nSee the %s for details.\n",
+               program_invocation_short_name,
+               link);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[], Manager *manager) {
+        enum {
+                ARG_TIMEOUT_SIGNAL,
+        };
+
+        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'                 },
+                { "timeout-signal",     required_argument,      NULL,  ARG_TIMEOUT_SIGNAL },
+                {}
+        };
+
+        int c, r;
+
+        assert(argc >= 0);
+        assert(argv);
+        assert(manager);
+
+        while ((c = getopt_long(argc, argv, "c:de:Dt:N:hV", options, NULL)) >= 0) {
+                switch (c) {
+
+                case 'd':
+                        arg_daemonize = true;
+                        break;
+                case 'c':
+                        r = safe_atou(optarg, &manager->children_max);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to parse --children-max= value '%s', ignoring: %m", optarg);
+                        break;
+                case 'e':
+                        r = parse_sec(optarg, &manager->exec_delay_usec);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to parse --exec-delay= value '%s', ignoring: %m", optarg);
+                        break;
+                case ARG_TIMEOUT_SIGNAL:
+                        r = signal_from_string(optarg);
+                        if (r <= 0)
+                                log_warning_errno(r, "Failed to parse --timeout-signal= value '%s', ignoring: %m", optarg);
+                        else
+                                manager->timeout_signal = r;
+
+                        break;
+                case 't':
+                        r = parse_sec(optarg, &manager->timeout_usec);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to parse --event-timeout= value '%s', ignoring: %m", optarg);
+                        break;
+                case 'D':
+                        arg_debug = true;
+                        break;
+                case 'N': {
+                        ResolveNameTiming t;
+
+                        t = resolve_name_timing_from_string(optarg);
+                        if (t < 0)
+                                log_warning("Invalid --resolve-names= value '%s', ignoring.", optarg);
+                        else
+                                manager->resolve_name_timing = t;
+                        break;
+                }
+                case 'h':
+                        return help();
+                case 'V':
+                        printf("%s\n", GIT_VERSION);
+                        return 0;
+                case '?':
+                        return -EINVAL;
+                default:
+                        assert_not_reached();
+
+                }
+        }
+
+        return 1;
+}
+
+void manager_set_default_children_max(Manager *manager) {
+        uint64_t cpu_limit, mem_limit, cpu_count = 1;
+        int r;
+
+        assert(manager);
+
+        if (manager->children_max != 0)
+                return;
+
+        r = cpus_in_affinity_mask();
+        if (r < 0)
+                log_warning_errno(r, "Failed to determine number of local CPUs, ignoring: %m");
+        else
+                cpu_count = r;
+
+        cpu_limit = cpu_count * 2 + 16;
+        mem_limit = MAX(physical_memory() / (128*1024*1024), UINT64_C(10));
+
+        manager->children_max = MIN3(cpu_limit, mem_limit, WORKER_NUM_MAX);
+        log_debug("Set children_max to %u", manager->children_max);
+}
+
+static void manager_adjust_config(Manager *manager) {
+        assert(manager);
+
+        if (manager->timeout_usec < MIN_WORKER_TIMEOUT_USEC) {
+                log_debug("Timeout (%s) for processing event is too small, using the default: %s",
+                          FORMAT_TIMESPAN(manager->timeout_usec, 1),
+                          FORMAT_TIMESPAN(DEFAULT_WORKER_TIMEOUT_USEC, 1));
+
+                manager->timeout_usec = DEFAULT_WORKER_TIMEOUT_USEC;
+        }
+
+        if (manager->exec_delay_usec >= manager->timeout_usec) {
+                log_debug("Delay (%s) for executing RUN= commands is too large compared with the timeout (%s) for event execution, ignoring the delay.",
+                          FORMAT_TIMESPAN(manager->exec_delay_usec, 1),
+                          FORMAT_TIMESPAN(manager->timeout_usec, 1));
+
+                manager->exec_delay_usec = 0;
+        }
+
+        manager_set_default_children_max(manager);
+}
+
+int manager_load(Manager *manager, int argc, char *argv[]) {
+        int r;
+
+        assert(manager);
+
+        manager_parse_udev_config(manager);
+
+        r = parse_argv(argc, argv, manager);
+        if (r <= 0)
+                return r;
+
+        r = proc_cmdline_parse(parse_proc_cmdline_item, manager, PROC_CMDLINE_STRIP_RD_PREFIX);
+        if (r < 0)
+                log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
+
+        if (arg_debug) {
+                log_set_target(LOG_TARGET_CONSOLE);
+                log_set_max_level(LOG_DEBUG);
+        }
+
+        manager_adjust_config(manager);
+        return 1;
+}
diff --git a/src/udev/udev-config.h b/src/udev/udev-config.h
new file mode 100644 (file)
index 0000000..9a8a188
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#pragma once
+
+#include <stdbool.h>
+
+extern bool arg_daemonize;
+
+typedef struct Manager Manager;
+
+int manager_load(Manager *manager, int argc, char *argv[]);
+void manager_set_default_children_max(Manager *manager);
index 6e1935a731073111333465f58019cf8a26cdbce8..23a57dbed30e5e4d8471e7f7dee8a48fe46c9e2c 100644 (file)
@@ -3,7 +3,6 @@
 #include "blockdev-util.h"
 #include "cgroup-util.h"
 #include "common-signal.h"
-#include "cpu-set-util.h"
 #include "daemon-util.h"
 #include "device-monitor-private.h"
 #include "device-private.h"
@@ -15,7 +14,6 @@
 #include "hashmap.h"
 #include "inotify-util.h"
 #include "iovec-util.h"
-#include "limits-util.h"
 #include "list.h"
 #include "mkdir.h"
 #include "process-util.h"
@@ -25,6 +23,7 @@
 #include "string-util.h"
 #include "syslog-util.h"
 #include "udev-builtin.h"
+#include "udev-config.h"
 #include "udev-ctrl.h"
 #include "udev-event.h"
 #include "udev-manager.h"
@@ -36,8 +35,6 @@
 #include "udev-watch.h"
 #include "udev-worker.h"
 
-#define WORKER_NUM_MAX UINT64_C(2048)
-
 #define EVENT_RETRY_INTERVAL_USEC (200 * USEC_PER_MSEC)
 #define EVENT_RETRY_TIMEOUT_USEC  (3 * USEC_PER_MINUTE)
 
@@ -845,28 +842,6 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
         return 1;
 }
 
-static void manager_set_default_children_max(Manager *manager) {
-        uint64_t cpu_limit, mem_limit, cpu_count = 1;
-        int r;
-
-        assert(manager);
-
-        if (manager->children_max != 0)
-                return;
-
-        r = cpus_in_affinity_mask();
-        if (r < 0)
-                log_warning_errno(r, "Failed to determine number of local CPUs, ignoring: %m");
-        else
-                cpu_count = r;
-
-        cpu_limit = cpu_count * 2 + 16;
-        mem_limit = MAX(physical_memory() / (128*1024*1024), UINT64_C(10));
-
-        manager->children_max = MIN3(cpu_limit, mem_limit, WORKER_NUM_MAX);
-        log_debug("Set children_max to %u", manager->children_max);
-}
-
 /* receive the udevd message from userspace */
 static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrlMessageValue *value, void *userdata) {
         Manager *manager = ASSERT_PTR(userdata);
@@ -1208,26 +1183,6 @@ Manager* manager_new(void) {
         return manager;
 }
 
-void manager_adjust_arguments(Manager *manager) {
-        assert(manager);
-
-        if (manager->timeout_usec < MIN_WORKER_TIMEOUT_USEC) {
-                log_debug("Timeout (%s) for processing event is too small, using the default: %s",
-                          FORMAT_TIMESPAN(manager->timeout_usec, 1),
-                          FORMAT_TIMESPAN(DEFAULT_WORKER_TIMEOUT_USEC, 1));
-
-                manager->timeout_usec = DEFAULT_WORKER_TIMEOUT_USEC;
-        }
-
-        if (manager->exec_delay_usec >= manager->timeout_usec) {
-                log_debug("Delay (%s) for executing RUN= commands is too large compared with the timeout (%s) for event execution, ignoring the delay.",
-                          FORMAT_TIMESPAN(manager->exec_delay_usec, 1),
-                          FORMAT_TIMESPAN(manager->timeout_usec, 1));
-
-                manager->exec_delay_usec = 0;
-        }
-}
-
 static int listen_fds(int *ret_ctrl, int *ret_netlink) {
         _cleanup_strv_free_ char **names = NULL;
         _cleanup_close_ int ctrl_fd = -EBADF, netlink_fd = -EBADF;
@@ -1319,8 +1274,6 @@ int manager_init(Manager *manager) {
 int manager_main(Manager *manager) {
         int fd_worker, r;
 
-        manager_set_default_children_max(manager);
-
         /* unnamed socket from workers to the main daemon */
         r = socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, manager->worker_watch);
         if (r < 0)
index 7c20e2959433d53c8b42575a881ba7c8c7a958c8..14b458bcdb4ea97009d3a1c04e00385722165cfc 100644 (file)
@@ -53,7 +53,6 @@ Manager* manager_new(void);
 Manager* manager_free(Manager *manager);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
 
-void manager_adjust_arguments(Manager *manager);
 int manager_init(Manager *manager);
 int manager_main(Manager *manager);
 
index ef1c07a2cac70a5d5ba6247a2ae16616a78d1069..018a3cd6e79ebf669846d52df38adcf9e28eb11b 100644 (file)
  * Copyright © 2009 Scott James Remnant <scott@netsplit.com>
  */
 
-#include <getopt.h>
-#include <unistd.h>
-
-#include "conf-parser.h"
-#include "env-file.h"
 #include "errno-util.h"
 #include "fd-util.h"
 #include "mkdir.h"
-#include "parse-util.h"
-#include "pretty-print.h"
-#include "proc-cmdline.h"
 #include "process-util.h"
 #include "rlimit-util.h"
 #include "selinux-util.h"
-#include "signal-util.h"
-#include "syslog-util.h"
+#include "udev-config.h"
 #include "udev-manager.h"
-#include "udev-rules.h"
-#include "udev-util.h"
 #include "udevd.h"
 #include "version.h"
 
-static bool arg_debug = false;
-static int arg_daemonize = false;
-
-static DEFINE_CONFIG_PARSE_ENUM(config_parse_resolve_name_timing, resolve_name_timing, ResolveNameTiming);
-
-static int manager_parse_udev_config(Manager *manager) {
-        int r, log_val = -1;
-
-        assert(manager);
-
-        const ConfigTableItem config_table[] = {
-                { NULL, "udev_log",       config_parse_log_level,           0, &log_val                      },
-                { NULL, "children_max",   config_parse_unsigned,            0, &manager->children_max        },
-                { NULL, "exec_delay",     config_parse_sec,                 0, &manager->exec_delay_usec     },
-                { NULL, "event_timeout",  config_parse_sec,                 0, &manager->timeout_usec        },
-                { NULL, "resolve_names",  config_parse_resolve_name_timing, 0, &manager->resolve_name_timing },
-                { NULL, "timeout_signal", config_parse_signal,              0, &manager->timeout_signal      },
-                {}
-        };
-
-        r = udev_parse_config_full(config_table);
-        if (r < 0)
-                return r;
-
-        if (log_val >= 0)
-                log_set_max_level(log_val);
-
-        return 0;
-}
-
-/*
- * read the kernel command line, in case we need to get into debug mode
- *   udev.log_level=<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
- *   udev.event_timeout=<number of seconds>    seconds to wait before terminating an event
- *   udev.blockdev_read_only<=bool>            mark all block devices read-only when they appear
- */
-static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
-        Manager *manager = ASSERT_PTR(data);
-        int r;
-
-        assert(key);
-
-        if (proc_cmdline_key_streq(key, "udev.log_level") ||
-            proc_cmdline_key_streq(key, "udev.log_priority")) { /* kept for backward compatibility */
-
-                if (proc_cmdline_value_missing(key, value))
-                        return 0;
-
-                r = log_level_from_string(value);
-                if (r >= 0)
-                        log_set_max_level(r);
-
-        } else if (proc_cmdline_key_streq(key, "udev.event_timeout")) {
-
-                if (proc_cmdline_value_missing(key, value))
-                        return 0;
-
-                r = parse_sec(value, &manager->timeout_usec);
-
-        } else if (proc_cmdline_key_streq(key, "udev.children_max")) {
-
-                if (proc_cmdline_value_missing(key, value))
-                        return 0;
-
-                r = safe_atou(value, &manager->children_max);
-
-        } else if (proc_cmdline_key_streq(key, "udev.exec_delay")) {
-
-                if (proc_cmdline_value_missing(key, value))
-                        return 0;
-
-                r = parse_sec(value, &manager->exec_delay_usec);
-
-        } else if (proc_cmdline_key_streq(key, "udev.timeout_signal")) {
-
-                if (proc_cmdline_value_missing(key, value))
-                        return 0;
-
-                r = signal_from_string(value);
-                if (r > 0)
-                        manager->timeout_signal = r;
-
-        } else if (proc_cmdline_key_streq(key, "udev.blockdev_read_only")) {
-
-                if (!value)
-                        manager->blockdev_read_only = true;
-                else {
-                        r = parse_boolean(value);
-                        if (r < 0)
-                                log_warning_errno(r, "Failed to parse udev.blockdev-read-only argument, ignoring: %s", value);
-                        else
-                                manager->blockdev_read_only = r;
-                }
-
-                if (manager->blockdev_read_only)
-                        log_notice("All physical block devices will be marked read-only.");
-
-                return 0;
-
-        } else {
-                if (startswith(key, "udev."))
-                        log_warning("Unknown udev kernel command line option \"%s\", ignoring.", key);
-
-                return 0;
-        }
-
-        if (r < 0)
-                log_warning_errno(r, "Failed to parse \"%s=%s\", ignoring: %m", key, value);
-
-        return 0;
-}
-
-static int help(void) {
-        _cleanup_free_ char *link = NULL;
-        int r;
-
-        r = terminal_urlify_man("systemd-udevd.service", "8", &link);
-        if (r < 0)
-                return log_oom();
-
-        printf("%s [OPTIONS...]\n\n"
-               "Rule-based manager for device events and files.\n\n"
-               "  -h --help                   Print this message\n"
-               "  -V --version                Print version of the program\n"
-               "  -d --daemon                 Detach and run in the background\n"
-               "  -D --debug                  Enable debug output\n"
-               "  -c --children-max=INT       Set maximum number of workers\n"
-               "  -e --exec-delay=SECONDS     Seconds to wait before executing RUN=\n"
-               "  -t --event-timeout=SECONDS  Seconds to wait before terminating an event\n"
-               "  -N --resolve-names=early|late|never\n"
-               "                              When to resolve users and groups\n"
-               "\nSee the %s for details.\n",
-               program_invocation_short_name,
-               link);
-
-        return 0;
-}
-
-static int parse_argv(int argc, char *argv[], Manager *manager) {
-        enum {
-                ARG_TIMEOUT_SIGNAL,
-        };
-
-        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'                 },
-                { "timeout-signal",     required_argument,      NULL,  ARG_TIMEOUT_SIGNAL },
-                {}
-        };
-
-        int c, r;
-
-        assert(argc >= 0);
-        assert(argv);
-        assert(manager);
-
-        while ((c = getopt_long(argc, argv, "c:de:Dt:N:hV", options, NULL)) >= 0) {
-                switch (c) {
-
-                case 'd':
-                        arg_daemonize = true;
-                        break;
-                case 'c':
-                        r = safe_atou(optarg, &manager->children_max);
-                        if (r < 0)
-                                log_warning_errno(r, "Failed to parse --children-max= value '%s', ignoring: %m", optarg);
-                        break;
-                case 'e':
-                        r = parse_sec(optarg, &manager->exec_delay_usec);
-                        if (r < 0)
-                                log_warning_errno(r, "Failed to parse --exec-delay= value '%s', ignoring: %m", optarg);
-                        break;
-                case ARG_TIMEOUT_SIGNAL:
-                        r = signal_from_string(optarg);
-                        if (r <= 0)
-                                log_warning_errno(r, "Failed to parse --timeout-signal= value '%s', ignoring: %m", optarg);
-                        else
-                                manager->timeout_signal = r;
-
-                        break;
-                case 't':
-                        r = parse_sec(optarg, &manager->timeout_usec);
-                        if (r < 0)
-                                log_warning_errno(r, "Failed to parse --event-timeout= value '%s', ignoring: %m", optarg);
-                        break;
-                case 'D':
-                        arg_debug = true;
-                        break;
-                case 'N': {
-                        ResolveNameTiming t;
-
-                        t = resolve_name_timing_from_string(optarg);
-                        if (t < 0)
-                                log_warning("Invalid --resolve-names= value '%s', ignoring.", optarg);
-                        else
-                                manager->resolve_name_timing = t;
-                        break;
-                }
-                case 'h':
-                        return help();
-                case 'V':
-                        printf("%s\n", GIT_VERSION);
-                        return 0;
-                case '?':
-                        return -EINVAL;
-                default:
-                        assert_not_reached();
-
-                }
-        }
-
-        return 1;
-}
-
 int run_udevd(int argc, char *argv[]) {
         _cleanup_(manager_freep) Manager *manager = NULL;
         int r;
@@ -259,23 +26,10 @@ int run_udevd(int argc, char *argv[]) {
         if (!manager)
                 return log_oom();
 
-        manager_parse_udev_config(manager);
-
-        r = parse_argv(argc, argv, manager);
+        r = manager_load(manager, argc, argv);
         if (r <= 0)
                 return r;
 
-        r = proc_cmdline_parse(parse_proc_cmdline_item, manager, PROC_CMDLINE_STRIP_RD_PREFIX);
-        if (r < 0)
-                log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
-
-        if (arg_debug) {
-                log_set_target(LOG_TARGET_CONSOLE);
-                log_set_max_level(LOG_DEBUG);
-        }
-
-        manager_adjust_arguments(manager);
-
         r = must_be_root();
         if (r < 0)
                 return r;