diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-11-05 13:50:28 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-11-05 20:53:47 +0100 |
commit | f7d2991539635b25ab1005887e1502dd8b98f18d (patch) | |
tree | 4014a8d334efa21fb6068887e8d8aec1eb1587f6 /src/core/load-fragment.c | |
parent | c631c3d6a340c13adf05dc9b06bd7bd566bd6c9e (diff) | |
download | systemd-f7d2991539635b25ab1005887e1502dd8b98f18d.tar.gz |
core: make TasksMax a partially dynamic property
TasksMax= and DefaultTasksMax= can be specified as percentages. We don't
actually document of what the percentage is relative to, but the implementation
uses the smallest of /proc/sys/kernel/pid_max, /proc/sys/kernel/threads-max,
and /sys/fs/cgroup/pids.max (when present). When the value is a percentage,
we immediately convert it to an absolute value. If the limit later changes
(which can happen e.g. when systemd-sysctl runs), the absolute value becomes
outdated.
So let's store either the percentage or absolute value, whatever was specified,
and only convert to an absolute value when the value is used. For example, when
starting a unit, the absolute value will be calculated when the cgroup for
the unit is created.
Fixes #13419.
Diffstat (limited to 'src/core/load-fragment.c')
-rw-r--r-- | src/core/load-fragment.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 288de616b6..8e33c83398 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -3263,36 +3263,38 @@ int config_parse_tasks_max( void *data, void *userdata) { - uint64_t *tasks_max = data, v; - const Unit *u = userdata; + TasksMax *tasks_max = data; + uint64_t v; int r; if (isempty(rvalue)) { - *tasks_max = u ? u->manager->default_tasks_max : UINT64_MAX; + *tasks_max = (TasksMax) {}; return 0; } if (streq(rvalue, "infinity")) { - *tasks_max = CGROUP_LIMIT_MAX; + *tasks_max = (TasksMax) { CGROUP_LIMIT_MAX }; return 0; } r = parse_permille(rvalue); - if (r < 0) { + if (r >= 0) + *tasks_max = (TasksMax) { v, 1000U }; + else { r = safe_atou64(rvalue, &v); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Invalid maximum tasks value '%s', ignoring: %m", rvalue); return 0; } - } else - v = system_tasks_max_scale(r, 1000U); - if (v <= 0 || v >= UINT64_MAX) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Maximum tasks value '%s' out of range, ignoring.", rvalue); - return 0; + if (v <= 0 || v >= UINT64_MAX) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Maximum tasks value '%s' out of range, ignoring.", rvalue); + return 0; + } + + *tasks_max = (TasksMax) { v }; } - *tasks_max = v; return 0; } |