From f3a367d66cd502c5127aec9962304b643d914df9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 17 Jan 2018 15:31:23 +0100 Subject: [PATCH] util: introduce more accurate definitions of TASKS_MAX The maximum number of processes a tasks on the system is usually lower than what pid_t would allow, and is compiled into the kernel (and documented in proc(5)). Let's add proper defines for that, so that we can adjust the pid_max sysctl without fearing invalid accesses. --- src/basic/process-util.h | 19 +++++++++++++++++++ src/basic/util.c | 12 ++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 267888a..581525c 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -179,3 +179,22 @@ static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) { } int fork_agent(const char *name, const int except[], unsigned n_except, pid_t *pid, const char *path, ...); + +#if SIZEOF_PID_T == 4 +/* The highest possibly (theoretic) pid_t value on this architecture. */ +#define PID_T_MAX ((pid_t) INT32_MAX) +/* The maximum number of concurrent processes Linux allows on this architecture, as well as the highest valid PID value + * the kernel will potentially assign. This reflects a value compiled into the kernel (PID_MAX_LIMIT), and sets the + * upper boundary on what may be written to the /proc/sys/kernel/pid_max sysctl (but do note that the sysctl is off by + * 1, since PID 0 can never exist and there can hence only be one process less than the limit would suggest). Since + * these values are documented in proc(5) we feel quite confident that they are stable enough for the near future at + * least to define them here too. */ +#define TASKS_MAX 4194303U +#elif SIZEOF_PID_T == 2 +#define PID_T_MAX ((pid_t) INT16_MAX) +#define TASKS_MAX 32767U +#else +#error "Unknown pid_t size" +#endif + +assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX) diff --git a/src/basic/util.c b/src/basic/util.c index 2d31d84..e9e925b 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -473,23 +473,15 @@ uint64_t physical_memory_scale(uint64_t v, uint64_t max) { uint64_t system_tasks_max(void) { -#if SIZEOF_PID_T == 4 -#define TASKS_MAX ((uint64_t) (INT32_MAX-1)) -#elif SIZEOF_PID_T == 2 -#define TASKS_MAX ((uint64_t) (INT16_MAX-1)) -#else -#error "Unknown pid_t size" -#endif - _cleanup_free_ char *value = NULL, *root = NULL; uint64_t a = TASKS_MAX, b = TASKS_MAX; /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this * limit: * - * a) the maximum value for the pid_t type + * a) the maximum tasks value the kernel allows on this architecture * b) the cgroups pids_max attribute for the system - * c) the kernel's configure maximum PID value + * c) the kernel's configured maximum PID value * * And then pick the smallest of the three */ -- 2.7.4