diff --git a/man/udev.conf.xml b/man/udev.conf.xml index 29c9743d1d6..7b7cae16b20 100644 --- a/man/udev.conf.xml +++ b/man/udev.conf.xml @@ -42,7 +42,7 @@ - udev_log + udev_log= The log level. Valid values are the numerical @@ -51,6 +51,42 @@ . + + + children_max= + + + An integer. The maximum number of events executed in parallel. + + This is the same as the option. + + + + + exec_delay= + + + An integer. Delay the execution of RUN + instructions by the given number of seconds. This option + might be useful when debugging system crashes during + coldplug caused by loading non-working kernel + modules. + + This is the same as the option. + + + + + event_timeout= + + + An integer. The number of seconds to wait for events to finish. After + this time, the event will be terminated. The default is 180 seconds. + + This is the same as the option. + + + diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c index a603867b16e..057aabcd542 100644 --- a/src/shared/udev-util.c +++ b/src/shared/udev-util.c @@ -6,36 +6,68 @@ #include "alloc-util.h" #include "fileio.h" #include "log.h" +#include "parse-util.h" #include "string-util.h" #include "udev-util.h" +#include "udev.h" -int udev_parse_config(void) { - _cleanup_free_ char *val = NULL; - const char *log; - size_t n; +int udev_parse_config_full( + unsigned *ret_children_max, + usec_t *ret_exec_delay_usec, + usec_t *ret_event_timeout_usec) { + + _cleanup_free_ char *log_val = NULL, *children_max = NULL, *exec_delay = NULL, *event_timeout = NULL; int r; - r = parse_env_file(NULL, "/etc/udev/udev.conf", NEWLINE, "udev_log", &val, NULL); - if (r == -ENOENT || !val) + r = parse_env_file(NULL, "/etc/udev/udev.conf", NEWLINE, + "udev_log", &log_val, + "children_max", &children_max, + "exec_delay", &exec_delay, + "event_timeout", &event_timeout, + NULL); + if (r == -ENOENT) return 0; if (r < 0) return r; - /* unquote */ - n = strlen(val); - if (n >= 2 && - ((val[0] == '"' && val[n-1] == '"') || - (val[0] == '\'' && val[n-1] == '\''))) { - val[n - 1] = '\0'; - log = val + 1; - } else - log = val; + if (log_val) { + const char *log; + size_t n; - /* we set the udev log level here explicitly, this is supposed - * to regulate the code in libudev/ and udev/. */ - r = log_set_max_level_from_string_realm(LOG_REALM_UDEV, log); - if (r < 0) - log_debug_errno(r, "/etc/udev/udev.conf: failed to set udev log level '%s', ignoring: %m", log); + /* unquote */ + n = strlen(log_val); + if (n >= 2 && + ((log_val[0] == '"' && log_val[n-1] == '"') || + (log_val[0] == '\'' && log_val[n-1] == '\''))) { + log_val[n - 1] = '\0'; + log = log_val + 1; + } else + log = log_val; + + /* we set the udev log level here explicitly, this is supposed + * to regulate the code in libudev/ and udev/. */ + r = log_set_max_level_from_string_realm(LOG_REALM_UDEV, log); + if (r < 0) + log_debug_errno(r, "/etc/udev/udev.conf: failed to set udev log level '%s', ignoring: %m", log); + } + + if (ret_children_max && children_max) { + r = safe_atou(children_max, ret_children_max); + if (r < 0) + log_notice_errno(r, "/etc/udev/udev.conf: failed to set parse children_max=%s, ignoring: %m", children_max); + } + + if (ret_exec_delay_usec && exec_delay) { + r = parse_sec(exec_delay, ret_exec_delay_usec); + if (r < 0) + log_notice_errno(r, "/etc/udev/udev.conf: failed to set parse exec_delay=%s, ignoring: %m", exec_delay); + } + + if (ret_event_timeout_usec && event_timeout) { + r = parse_sec(event_timeout, ret_event_timeout_usec); + if (r < 0) + log_notice_errno(r, "/etc/udev/udev.conf: failed to set parse event_timeout=%s, ignoring: %m", event_timeout); + } return 0; } diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h index 0df2cf9eb19..efbcd82976f 100644 --- a/src/shared/udev-util.h +++ b/src/shared/udev-util.h @@ -1,4 +1,13 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -int udev_parse_config(void); +#include "time-util.h" + +int udev_parse_config_full( + unsigned *ret_children_max, + usec_t *ret_exec_delay_usec, + usec_t *ret_event_timeout_usec); + +static inline int udev_parse_config(void) { + return udev_parse_config_full(NULL, NULL, NULL); +} diff --git a/src/udev/udev.conf b/src/udev/udev.conf index 0d812d4a656..3395a8b7ea6 100644 --- a/src/udev/udev.conf +++ b/src/udev/udev.conf @@ -3,4 +3,7 @@ # udevd is also started in the initrd. When this file is modified you might # also want to rebuild the initrd, so that it will include the modified configuration. -#udev_log="info" +#udev_log=info +#children_max= +#exec_delay= +#event_timeout=180 diff --git a/src/udev/udevd.c b/src/udev/udevd.c index c77ca57d933..9b316c80db1 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -1703,7 +1703,7 @@ int main(int argc, char *argv[]) { int r; log_set_target(LOG_TARGET_AUTO); - udev_parse_config(); + udev_parse_config_full(&arg_children_max, &arg_exec_delay_usec, &arg_event_timeout_usec); log_parse_environment(); log_open();