7

I'm trying to write a systemd service which should expose the options start|stop|status|restart.

This is the current script:

[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

I can't find any way to specify a custom status command.
Is there a way I think, but how?

5

Systemd support custom status message, but here are some prerequsites that must be met:

  • type of service should be notify
  • your service must update systemd with your current service status either via /run/systemd/notify socket or by calling systemd-notify

As a reference you can check Apache HTTPD on Fedora (maybe same in other distros, don't know):

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"

You can see that Apache is reporting status as Total requests: 8; Idle/Busy workers 100/0

So when I attached strace on pid 4105, we can see that it is periodicaly sending status updates to 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

You can see that it is sending READY=1\nSTATUS=Total requests: 8... into socket /run/systemd/notify

Recommended reading

man systemd-notify

or official documentation.

Example : Service startup in Systemd

8

I'm trying to write a systemd service which should expose the options start|stop|status|restart.

Your first mistake. Service units are not scripts. They don't have options. The options are to the systemctl command, and they are uniform across all units.

I realize using centos seems to be non-standard,

Your second mistake, related to your third mistake:

I'm going to merge a PR to fix the lot of stuff in debian/ubuntu. then we'll have to write an alternative daemon for centos, because it uses a different init method.

CentOS is not the odd one out. Ubuntu version 15, Debian 8, and CentOS 7 all use systemd and all need a proper systemd service unit.

ExecStart=/etc/init.d/arkdaemon start
ExecStop=/etc/init.d/arkdaemon stop

Your fourth mistake. You don't write service units by punting everything over to a System 5 rc script. Aside from the fact that that won't work on Debian and Ubuntu, because they try to punt everything back to the service unit; it's a horror of a concept, worthy of an entry in the systemd house of horror. Looking at the System 5 rc script, it puts back in all of the wrongheaded nonsense — racy grepping the output of ps, wrongheaded use of sudo to drop privileges (rather than acquire them) — that switching to a proper service manager gets rid of.

Don't muddle around at random. Understand how your dæmon is actually run, and then write a service unit that describes that.

Your System 5 rc script calls a program named arkmanager with start and stop verbs. So at first blush one might think that a systemd service unit should too. But it turns out that arkmanager itself is yet another Poor Man's Dæmon Supervisor written (badly, as they always are) in shell script, that does all of the same nonsense and much more — grepping the output of ps, using screen (sic!) as a way to fork off a process and later send a SIGINT to it, maintaining its own (non-rotated) log file, and using hardwired CSI sequences (sic!) in a program that when managing a dæmon isn't being run connected to a terminal in the first place.

You are busily constructing another horror. Stop.

Stripping away the horrendous tottering edifice that has one Poor Man's Dæmon Supervisor supervising another, which is in turn abusing screen as a third ad hoc supervisor, one finds that the underlying service management actually looks something like this:

[Unit]
Description=ARK server
Documentation=https://unix.stackexchange.com/questions/212059/
After=network.target

[Service]
User=steam
Environment=SESSION=YourLinuxSessionName
Environment=QUERYPORT=27016
Environment=PASS=password
Environment=ADMINPASS=adminpassword
ExecStart=/home/steam/ARK/ShooterGame/Binaries/Linux/ShooterGameServer TheIsland?SessionName=${SESSION}?QueryPort=${QUERYPORT}?ServerPassword=${PASS}?ServerAdminPassword=${ADMINPASS}?listen
LimitNOFILE=100000
Restart=always

[Install]
WantedBy=multi-user.target

And what's the first rule of migrating to systemd? That's right. It's now 2015, and someone has most likely already done it. And indeed here, someone already has, beating me by 4 days. They didn't construct a horror either.

Further reading

  • well actually you have looked at the master branch, we have improved it quite a bit in the 1.1 branch – Fez Vrasta Jun 25 '15 at 15:38
  • "I realize using centos seems to be non-standard," is related to the fact that ARK developers suggest to use Ubuntu 14.04. You talk without knowing the context here. – Fez Vrasta Jun 25 '15 at 15:46
  • "I'm going to merge a PR to fix the lot of stuff in debian/ubuntu. then we'll have to write an alternative daemon for centos, because it uses a different init method." here, I was talking about Ubuntu 14.04 and CentOS 6.6, and yes, Ubuntu 14.40 uses a different init script then the one of CentOS 6.6 – Fez Vrasta Jun 25 '15 at 15:47
  • 2
    @JdeBP I do not really like your answer, seems to me quite offensive without a proper answer, which would be in one sentence, that one can call systemctl status ... to get the status... – Betlista Sep 20 '17 at 10:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.