Systemd

通過 systemd 套接字啟動傳遞 8192 個套接字 - E2BIG 失敗

  • October 3, 2020

我正在嘗試讓 systemd 啟動一個守護程序並將 8,192 個監聽套接字傳遞給它。我有一個.service.socket文件可以可靠地使用更多“正常”數量的偵聽套接字,如下所示:

# a-daemon.socket
[Unit]
Description=A Daemon (sockets)
After=network.target

[Socket]
Accept=no
ListenStream=8192

# a-daemon.service
[Unit]
Description=A Daemon
After=network.target
Requires=a-daemon.socket

[Install]
WantedBy=multi-user.target

[Service]
Type=notify
ExecStart=/usr/local/sbin/a-daemon

但是如果我換成a-daemon.socket一個有 8,192ListenStream行的版本,每個 TCP 埠從 8192 到 16383(含)一個,那麼守護程序將不再啟動。套接字單元可以正常啟動,但服務單元失敗;我得到的唯一錯誤資訊是

systemd[17563]: a-daemon.service: Failed to execute command: Argument list too long
systemd[17563]: a-daemon.service: Failed at step EXEC spawning /usr/local/sbin/a-daemon: Argument list too long

據我了解,這實際上不是參數 list的問題,因為 systemd 不會將套接字 fd 編號放在守護程序的命令行或類似的東西上。我猜這是同時打開文件數量限制的問題,所以我設置DefaultLimitNOFILE=32768/etc/systemd/system.conf一個等效設置/etc/security/limits.conf並重新啟動。不用找了。然後我把ExecStartPre=/usr/sbin/prlimit -n.service文件放進去,嘗試重啟,確認增加的限制已經生效:

prlimit[18134]: RESOURCE   DESCRIPTION                             SOFT      HARD UNITS
prlimit[18134]: NOFILE     max number of open files               32768     32768 files

但是服務仍然失敗,同樣的方式。現在我沒有主意了。你能建議我可以嘗試做些什麼來完成這項工作嗎?

(我知道監聽 8,192 個連續的 TCP 埠是一件很奇怪的事情。請相信我,我有一個很好的理由,我不能分享。)

再看一下 systemd 聯機幫助頁後,我意識到systemd 在該區域中放置了一些東西,argv大小與偵聽套接字的數量成正比:

sd_listen_fds_with_names()類似於sd_listen_fds(),但也可以選擇返回一個字元串數組,其中包含傳遞的文件描述符的標識名稱,如果可用且 names 參數為非 NULL 的話。**此資訊是從$LISTEN_FDNAMES $$ environment $$變數,它可能包含一個以冒號分隔的名稱列表。**對於套接字啟動的服務,這些名稱可以使用FileDescriptorName= 套接字單元文件中的設置進行配置,詳情請參閱systemd.socket(5)

(粗體 - 我的重點)這意味著,如果您ListenStream在套接字單元文件中有 8192 個條目,systemd 將嘗試將LISTEN_FDNAMES=[name]:[name]:...8192 重複(設置在哪裡nameFileDescriptorName放入服務環境中。FileDescriptorName預設為套接字單元文件的完整基本名稱。這很容易溢出 Linux 對單個環境變數名稱+值(通常為 128k)長度的相當低的固定限制MAX_ARG_STRLEN,從而execve(2)導致E2BIG.

對於一個不關心名字的守護程序,解決方法是把

UnsetEnvironment=LISTEN_FDNAMES

服務文件([Service]部分)中。這消除了問題環境變數並使核心滿意。

如果您確實需要某些 fd 名稱並且您達到了此限制,我不知道您會做什麼。

引用自:https://serverfault.com/questions/1036195