I would like to manage a TeamSpeak 3 server with systemd (systemctl).

When I start / stop / restart the TeamSpeak 3 server using systemctl command, systemctl is returning the correct status:

$ systemctl status ts3server.service
● ts3server.service - TeamSpeak 3 Server
   Loaded: loaded (/etc/systemd/system/ts3server.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-02-12 23:15:18 CET; 1min 11s ago
 Main PID: 842 (ts3server)
   CGroup: /system.slice/ts3server.service
           └─842 ./ts3server inifile=ts3server.ini

Feb 12 23:15:18 hostname.local systemd[1]: Starting TeamSpeak 3 Server...
Feb 12 23:15:18 hostname.local ts3server_startscript.sh[838]: Starting the TeamSpeak 3 server
Feb 12 23:15:18 hostname.local ts3server_startscript.sh[838]: TeamSpeak 3 server started, for details please view the log file
Feb 12 23:15:18 hostname.local systemd[1]: Started TeamSpeak 3 Server.

But when the service is stopped otherwise (eg. through an automated update process) and then started again - without systemctl - the systemctl status command returns an incorrect status:

$ systemctl status ts3server.service
● ts3server.service - TeamSpeak 3 Server
   Loaded: loaded (/etc/systemd/system/ts3server.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Mon 2019-02-11 03:15:16 CET; 1 day 19h ago
Condition: start condition failed at Mon 2019-02-11 03:15:16 CET; 1 day 19h ago
           └─ ConditionPathExists=!/home/teamspeak/.update.lock was not met
  Process: 21740 ExecStop=/home/teamspeak/ts3server_startscript.sh stop (code=exited, status=0/SUCCESS)
  Process: 29220 ExecStart=/home/teamspeak/ts3server_startscript.sh start (code=exited, status=0/SUCCESS)
 Main PID: 29224 (code=exited, status=0/SUCCESS)

Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.

The PID file exists in this moment:

$ stat /home/teamspeak/ts3server.pid
  File: /home/teamspeak/ts3server.pid
  Size: 4              Blocks: 8          EA Block: 4096   regular file
Device: ca01h/51713d     Inode: 534471      Symbolic Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1001/teamspeak)   Gid: ( 1001/teamspeak)
Access    : 2019-02-12 23:15:09.192927211 +0100
Modified: 2019-02-12 23:15:09.188927218 +0100
Changed   : 2019-02-12 23:15:09.188927218 +0100
 Birth    : -

The process with this PID is running and I can connect to this TeamSpeak 3 server.

/home/teamspeak/.update.lock exists while the automated update process is running. After the update, the file is removed / deleted and does NOT exist anymore.

systemctl shows the correct status, when I kill the running service PID as systemctl restarts the service using systemd correct later.

Here is my /etc/systemd/system/ts3server.service file:

Description=TeamSpeak 3 Server
After=network.target mysqld.service


ExecStart=/home/teamspeak/ts3server_startscript.sh start
ExecStop=/home/teamspeak/ts3server_startscript.sh stop
ExecReload=/home/teamspeak/ts3server_startscript.sh restart

Why can systemctl not return the correct status, although the TeamSpeak 3 server is started correct on a different way?

  • What was the running PID then? Feb 13 '19 at 18:57
  • I've just reproduced the issue: su -c "/home/teamspeak/ts3server_startscript.sh status" teamspeak -s /bin/bash returns Server is running, but systemctl status ts3server.service is returning inactive (dead) with start condition failed and Main PID: 19930 (code=exited, status=0/SUCCESS). The PID file /home/teamspeak/ts3server.pid contains this PID: 20064 Feb 13 '19 at 21:32
  • Of course, systemd didn't start it! Please start over and update your question accordingly. Feb 13 '19 at 22:25
  • But shouldn't systemd check the PIDFile and see, that it's up and running? Feb 13 '19 at 23:05
  • 1
    No, systemd does not check the PIDFile. That's not what it's for. Feb 14 '19 at 0:37

You should change the Type to simple in your unit file and it will work. IIRC forking requires an explicit call of fork() method, while you start it from a bash script and there simply is no fork() call.

  • This does unfortunately not solve the issue. It is still the same behaviour. Feb 13 '19 at 21:27

The answer to your "why" question is that systemd is looking for the PID that it knows of (842 in your example output above), it does not track the service's own PID information. If that process is no longer running, systemd has no idea what's going on with the process. Nor can it restart it (since the ports would already be bound to by the new instance).

Probably a cleaner way to do the upgrade is

  1. Use systemctl to stop the service
  2. Perform the update, and then
  3. Use systemctl start the process.

The trick is to specify Type=oneshot and RemainAfterExit=yes and do not specify PIDFile=

Minimal example:

Description=service that is restarted by externalities.



Documentation calls it "Stoppable oneshot service"

Similarly to the oneshot services, there are sometimes units that need to execute a program to set up something and then execute another to shut it down, but no process remains active while they are considered "started".

But they don't consider the use case where the program that is started changes PID values even though it works for that as well.

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.