systemd 自定义状态消息?

Fez*_*sta 10 systemd

我正在尝试编写一个应该公开 options 的 systemd 服务start|stop|status|restart

这是当前的脚本:

[Unit]
Description=Daemon to start ark server
After=network.target

[Service]
ExecStart=/etc/init.d/arkdaemon start
ExecStop=/etc/init.d/arkdaemon stop
Type=forking

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

我找不到任何方法来指定自定义状态命令。
我有没有办法思考,但是怎么做?

Jde*_*eBP 8

我正在尝试编写一个应该公开 options 的 systemd 服务start|stop|status|restart

你的第一个错误。服务单位不是脚本。他们不具备的选项。选项是systemctl命令的,它们在所有单位中都是统一的。

我意识到使用 centos 似乎是非标准的,

你的第二个错误,与你的第三个错误有关:

我将合并一个 PR 来修复 debian/ubuntu 中的很多东西。那么我们将不得不为 centos 编写一个替代守护进程,因为它使用不同的 init 方法。

CentOS并不奇怪。Ubuntu 15、Debian 8 和 CentOS 7 都使用 systemd,并且都需要一个合适的 systemd 服务单元。

ExecStart=/etc/init.d/arkdaemon start
ExecStop=/etc/init.d/arkdaemon 停止

你的第四个错误。您不会通过将所有内容都转移到 System 5rc脚本来编写服务单元。除了这在 Debian 和 Ubuntu 上不起作用的事实之外,因为他们试图将所有东西都放回服务单元;这是一个概念的恐怖,值得进入系统的恐怖之家。看看 System 5rc脚本,它把所有错误的胡说八道都放回了原处——对 的输出进行了ps粗暴的搜索,错误地使用sudo放弃特权(而不是获取特权)——切换到适当的服务管理器就可以摆脱了。

不要随意乱来。 了解你的守护进程是如何实际运行的,然后编写一个描述它的服务单元。

您的 System 5rc脚本调用名为arkmanagerwithstartstopverbs的程序。因此,乍一看,人们可能会认为 systemd 服务单元也应该如此。但事实证明,arkmanager 它本身另一个用 shell 脚本编写的穷人守护进程监督程序(糟糕,因为它们总是如此),它做了所有相同的废话和更多 - grepping 的输出ps,使用screen(原文如此!)作为一种方式分叉一个进程,然后向SIGINT它发送一个进程,维护它自己的(非旋转的)日志文件,并在一个程序中使用硬连线的 CSI 序列(原文如此!)第一名。

你正忙着建造另一个恐怖。停止。

剥离可怕的摇摇欲坠的大厦,有一个穷人的守护者监督另一个,反过来又被滥用screen为第三个临时监督者,人们发现底层服务管理实际上是这样的:

[单元]
说明=方舟服务器
文档=https://unix.stackexchange.com/questions/212059/
之后=网络.目标

[服务]
用户=蒸汽
环境=会话=您的Linux会话名称
环境=QUERYPORT=27016
环境=PASS=密码
环境=ADMINPASS=adminpassword
ExecStart=/home/steam/ARK/ShooterGame/Binaries/Linux/ShooterGameServer TheIsland?SessionName=${SESSION}?QueryPort=${QUERYPORT}?ServerPassword=${PASS}?ServerAdminPassword=${ADMINPASS}?listen
限制NOFILE=100000
重启=总是

[安装]
WantedBy=multi-user.target

迁移到 systemd 的第一条规则是什么?这是正确的。现在是 2015 年,很可能有人已经做到了。确实在这里,有人已经做到了,比我快 4 天。他们也没有制造恐怖。

进一步阅读

  • @JdeBP我真的不喜欢你的回答,在我看来,如果没有正确的答案,我觉得很冒犯,这就是一句话,可以调用`systemctl status ...`来获取状态... (2认同)

rko*_*egi 8

Systemd 支持自定义状态消息,但这里有一些必须满足的先决条件:

  • 服务类型应该是 notify
  • 您的服务必须通过/run/systemd/notify套接字或通过调用 systemd-notify使用您当前的服务状态更新 systemd

作为参考,您可以在 Fedora 上检查 Apache HTTPD(在其他发行版中可能相同,不知道):

systemctl status httpd.service


? httpd.service - The Apache HTTP Server    
  Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
  Active: active (running) since Fri 2017-10-06 15:21:07 CEST; 18h ago
  Docs: man:httpd.service(8)
  Process: 14424 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=0/SUCCESS)  
  Main PID: 4105 (httpd)
  Status: "Total requests: 8; Idle/Busy workers 100/0;Requests/sec: 0.000118; Bytes served/sec:   0 B/sec"
Run Code Online (Sandbox Code Playgroud)

您可以看到 Apache 将状态报告为Total requests: 8; 空闲/忙碌的工人 100/0

因此,当我附加stracepid 4105 时,我们可以看到它定期将状态更新发送到systemd

sudo strace -f -p 4105

wait4(-1, 0x7ffcfab4a25c, WNOHANG|WSTOPPED, NULL) = 0
select(0, NULL, NULL, NULL, {tv_sec=1, tv_usec=0}) = 0 (Timeout)
socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 8
getsockopt(8, SOL_SOCKET, SO_SNDBUF, [212992], [4]) = 0
setsockopt(8, SOL_SOCKET, SO_SNDBUFFORCE, [8388608], 4) = 0
sendmsg(8, {msg_name={sa_family=AF_UNIX, sun_path="/run/systemd/notify"}, msg_namelen=21, msg_iov=[{iov_base="READY=1\nSTATUS=Total requests: 8"..., iov_len=110}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, MSG_NOSIGNAL) = 110
close(8)                                = 0
wait4(-1, 0x7ffcfab4a25c, WNOHANG|WSTOPPED, NULL) = 0
Run Code Online (Sandbox Code Playgroud)

你可以看到它正在发送READY=1\nSTATUS=Total requests: 8... into socket/run/systemd/notify

推荐阅读

man systemd-notify

官方文档

示例:Systemd 中的服务启动