docs: Amend documentation for LimitNPROC=
#23242
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PR details
The configuration item
LimitNPROC=
is often not doing what it is expected to do (see details below). Since systemd already contains a better way (TasksMax=
instead ofLimitNPROC=
, based on cgroups instead of rlimit) of limiting the number of processes launched by a service, no actual code changes are needed. This PR will amend the documentation and recommend usingTasksMax=
instead ofLimitNPROC=
.Problem background/additional information
The
LimitNPROC
item in the service definition will directly be translated to a correspondingprlimit
call to setRLIMIT_NPROC
to the configured value. However, theRLIMIT_NPROC
will limit the number of processes of a given real user ID (globally on the whole system) and not the number of processes which can be created (forked) by the started service. Please also note that when the service is running as root, theRLIMIT_NPROC
setting is not actually enforced by the kernel. This means that theLimitNPROC
setting is only actually useful when the service has a dedicated UID and switches to that UID after startup. In all other cases (service is running asroot
or with an unprivileged default account likenobody
shared among multiple services), theLimitNPROC
setting will not work as expected.Additional issues when running in an LXC container
When running under LXC, the
RLIMIT_NPROC
limit is actually enforced by the kernel even when the service is running as root (and not ignored as it would be on a non-virtualized system). This results in some service configurations to fail when running under LXC, most notably with OpenVPN (see for example #6011, many more bug reports have been opened about this issue with running OpenVPN in LXC).Summary of cases in which
LimitNPROC=
will misbehave:LimitNPROC=
limit is silently ignored since root is not affected byRLIMIT_NPROC
.LimitNPROC=
limit will count all processes running as root in the container and may already be exhausted at the time the service is starting.nobody
for many Linux distributions): All processes using the same shared account will be counted for theLimitNPROC=
limit.How to reproduce the issue with a simple test service:
/root/limitnproc.c
:/etc/systemd/system/limitnproc.service
:Then compile it (
cc -o /root/limitnproc /root/limitnproc.c
) and runsystemctl daemon-reload && systemctl restart limitnproc
to start it. On a non-virtualized system it will launch 10 child processes in parallel (in spite of theLimitNPROC=3
limit), see the following syslog output:When running the same service in an LXC container it will fail to start any child processes at all since the limit of 3 processes owned by root is already exhausted by other processes on the system (with LXC the limit is actually enforced even for root):