diff --git a/man/udev.conf.xml b/man/udev.conf.xml
index 0f51a1aaef..f4d573ddc6 100644
--- a/man/udev.conf.xml
+++ b/man/udev.conf.xml
@@ -53,7 +53,8 @@
children_max=
- An integer. The maximum number of events executed in parallel.
+ An integer. The maximum number of events executed in parallel. When unspecified or 0 is
+ specified, the maximum is determined based on the system resources.
This is the same as the option.
diff --git a/man/udevadm.xml b/man/udevadm.xml
index 900bdac4b3..1c339a6b6d 100644
--- a/man/udevadm.xml
+++ b/man/udevadm.xml
@@ -607,8 +607,8 @@
value
- Set the maximum number of events, systemd-udevd will handle at the
- same time.
+ Set the maximum number of events, systemd-udevd will handle at the same time. When 0 is
+ specified, then the maximum is determined based on the system resources.
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index b97ccab3b0..6653de6b45 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -3,6 +3,7 @@
#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"
@@ -14,6 +15,7 @@
#include "hashmap.h"
#include "inotify-util.h"
#include "io-util.h"
+#include "limits-util.h"
#include "list.h"
#include "mkdir.h"
#include "process-util.h"
@@ -33,6 +35,8 @@
#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)
@@ -829,6 +833,28 @@ 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);
@@ -921,7 +947,7 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
break;
}
case UDEV_CTRL_SET_CHILDREN_MAX:
- if (value->intval <= 0) {
+ if (value->intval < 0) {
log_debug("Received invalid udev control message (SET_MAX_CHILDREN, %i), ignoring.", value->intval);
return 0;
}
@@ -929,6 +955,9 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
log_debug("Received udev control message (SET_MAX_CHILDREN), setting children_max=%i", value->intval);
manager->children_max = value->intval;
+ /* When 0 is specified, determine the maximum based on the system resources. */
+ manager_set_default_children_max(manager);
+
notify_ready(manager);
break;
case UDEV_CTRL_PING:
@@ -1227,6 +1256,8 @@ int manager_init(Manager *manager, int fd_ctrl, int fd_uevent) {
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)
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index d0856b4a55..257336aec6 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -6,14 +6,13 @@
*/
#include
+#include
#include "sd-daemon.h"
-#include "cpu-set-util.h"
#include "env-file.h"
#include "errno-util.h"
#include "fd-util.h"
-#include "limits-util.h"
#include "mkdir.h"
#include "parse-util.h"
#include "pretty-print.h"
@@ -27,8 +26,6 @@
#include "udevd.h"
#include "version.h"
-#define WORKER_NUM_MAX 2048U
-
static bool arg_debug = false;
static int arg_daemonize = false;
@@ -361,22 +358,6 @@ int run_udevd(int argc, char *argv[]) {
if (r < 0)
return r;
- if (manager->children_max == 0) {
- unsigned long cpu_limit, mem_limit, cpu_count = 1;
-
- 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() / (128UL*1024*1024), 10U);
-
- manager->children_max = MIN3(cpu_limit, mem_limit, WORKER_NUM_MAX);
- log_debug("Set children_max to %u", manager->children_max);
- }
-
/* set umask before creating any file/directory */
umask(022);