socket-proxyd: raise RLIMIT_NOFILE at startup
Each proxied connection uses eight file descriptors: the accepted and the outgoing socket, a duplicate of each, and a pipe for each direction. With the default soft RLIMIT_NOFILE of 1024, setting up forwarding fails with "Too many open files" at about 127 concurrent connections, well before the default --connections-max=256, and the connection is closed right after being accepted. socket-proxyd's I/O is sd-event based and handles fds above 1023, so it does not need the select()-compatible soft limit. Call rlimit_nofile_bump(-1) at startup to raise RLIMIT_NOFILE as far as permitted, like udevd does. (cherry picked from commit 98752540be47778e253cbafe51c7ccdd30f4995e)
This commit is contained in:
committed by
Luca Boccassi
parent
c74f6f85ed
commit
bcf0a9ac58
@@ -21,6 +21,7 @@
|
||||
#include "main-func.h"
|
||||
#include "parse-util.h"
|
||||
#include "resolve-private.h"
|
||||
#include "rlimit-util.h"
|
||||
#include "set.h"
|
||||
#include "socket-forward.h"
|
||||
#include "socket-util.h"
|
||||
@@ -563,6 +564,10 @@ static int run(int argc, char *argv[]) {
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
/* Each connection holds several fds (two sockets, their duplicates and a pipe per direction), so
|
||||
* the default soft limit of 1024 would run out well before the default connection limit. */
|
||||
(void) rlimit_nofile_bump(-1);
|
||||
|
||||
r = sd_event_default(&context.event);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate event loop: %m");
|
||||
|
||||
@@ -38,6 +38,8 @@ EOF
|
||||
cat >/run/systemd/system/test-proxyd.service <<EOF
|
||||
[Service]
|
||||
ExecStart=/usr/lib/systemd/systemd-socket-proxyd $BACKEND_SOCK
|
||||
LimitNOFILE=1024:4096
|
||||
CapabilityBoundingSet=~CAP_SYS_RESOURCE
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
@@ -56,3 +58,10 @@ assert_eq "$(echo -n world | proxy_echo)" "world"
|
||||
# Test with larger data (64KB random, base64-encoded)
|
||||
LARGE_DATA="$(dd if=/dev/urandom bs=1024 count=64 status=none | base64)"
|
||||
assert_eq "$(echo -n "$LARGE_DATA" | proxy_echo)" "$LARGE_DATA"
|
||||
|
||||
# Every connection costs the proxy several fds, so it raises its soft RLIMIT_NOFILE. Without
|
||||
# CAP_SYS_RESOURCE it cannot raise the hard limit, so the result is exactly the unit's hard limit.
|
||||
PROXY_PID="$(systemctl show -P MainPID test-proxyd.service)"
|
||||
read -r _ _ _ SOFT HARD _ < <(grep '^Max open files' "/proc/$PROXY_PID/limits")
|
||||
assert_eq "$SOFT" 4096
|
||||
assert_eq "$HARD" 4096
|
||||
|
||||
Reference in New Issue
Block a user