Trouble creating PID file in systemd service script

35,301

Solution 1

If you're asking if systemd will create a PID file for the daemon, it will not, per:

https://www.freedesktop.org/software/systemd/man/systemd.service.html#PidFile=

PIDFile=

Takes an absolute file name pointing to the PID file of this daemon. Use > of this option is recommended for services where Type= is set to forking. systemd will read the PID of the main process of the daemon after start-up of the service. systemd will not write to the file configured here, although it will remove the file after the service has shut down if it still exists.

It might be better to leave it blank and try using GuessMainPID=.

Solution 2

Regrettably, systemd won't create a PID file for a non-forking service even if you specify a PIDFile= line in the service's unit file. But you may be able to cheat with a ExecStartPost= line, such as:

ExecStartPost=/bin/sh -c 'umask 022; pgrep YOURSERVICE > /var/run/YOURSERVICE.pid'
Share:
35,301

Related videos on Youtube

jia103
Author by

jia103

Updated on September 18, 2022

Comments

  • jia103
    jia103 3 months

    I'm trying to get RipRight installed on Debian, for which there doesn't appear to be any pre-built package. I'm having difficulty getting a systemd script working to start/stop RipRight running as a daemon because it can't write the PID file to /run.

    I went through the usual configure/make/make install. I also created a ripright user/group and added ripright to the cdrom group.

    Here is the systemd script I placed in /etc/systemd/system/ripright.service:

    [Unit]
    Description=RipRight
    [Service]
    Type=forking
    PrivateTmp=yes
    User=ripright
    Group=ripright
    RuntimeDirectory=ripright
    RuntimeDirectoryMode=0750
    ExecStart=/usr/local/bin/ripright \
        --daemon \
        --w32-filenames \
        --require-art \
        --folder-art folder.png \
        --output-file "%B/%D/%C - %N %T.flac" \
        "/opt/ripright/data"
    PIDFile=/var/run/ripright/ripright.pid
    [Install]
    WantedBy=multi-user.target
    

    I used the recently-added RuntimeDirectory directive in the script to create a /run/ripright folder with ripright as the owner. This directory gets created when I run:

    # systemctl daemon-reload
    # systemctl start ripright
    

    In a separate window:

    # ls -lhrt /run
    ...
    drwxr-x---  2 ripright ripright   40 Jan  5 20:52 ripright
    drwxr-xr-x 16 root     root      400 Jan  5 20:52 systemd
    # ls -lahrt /run/ripright
    total 0
    drwxr-xr-x 16 root     root     540 Jan  5 20:52 ..
    drwxr-x---  2 ripright ripright  40 Jan  5 20:52 .
    # su - ripright
    $ cd /run/ripright
    $ pwd
    /run/ripright
    $ echo test > one.txt
    $ cat one.txt
    test
    $ rm one.txt
    $ exit
    

    I believe my systemctl start command does not return due to this and instead hangs. After a minute or so, it times out with:

    # systemctl start ripright
    Job for ripright.service failed. See 'systemctl status ripright.service' and 'journalctl -xn' for details.
    

    Here is the output of the recommended commands:

    # systemctl status ripright.service
    ● ripright.service - RipRight
       Loaded: loaded (/etc/systemd/system/ripright.service; enabled)
       Active: failed (Result: timeout) since Thu 2017-01-05 20:54:40 EST; 55s ago
      Process: 35396 ExecStart=/usr/local/bin/ripright --daemon --w32-filenames --require-art --folder-art folder.png --output-file %B/%D/%C - %N %T.flac /opt/ripright/data (code=exited, status=0/SUCCESS)
     Main PID: 33287 (code=killed, signal=TERM)
    Jan 05 20:53:10 ripperd ripright[35397]: Started daemon mode (v0.11)
    Jan 05 20:53:10 ripperd ripright[35398]: Waiting for a CD (/dev/cdrom)
    Jan 05 20:54:40 ripperd systemd[1]: ripright.service start operation timed out. Terminating.
    Jan 05 20:54:40 ripperd systemd[1]: Failed to start RipRight.
    Jan 05 20:54:40 ripperd systemd[1]: Unit ripright.service entered failed state.
    # journalctl -xn
    -- Logs begin at Thu 2017-01-05 00:30:29 EST, end at Thu 2017-01-05 20:54:40 EST. --
    Jan 05 20:52:00 ripperd ripright[35380]: Waiting for a CD (/dev/cdrom)
    Jan 05 20:52:59 ripperd su[35385]: Successful su for ripright by root
    Jan 05 20:52:59 ripperd su[35385]: + /dev/pts/1 root:ripright
    Jan 05 20:52:59 ripperd su[35385]: pam_unix(su:session): session opened for user ripright by vagrant(uid=0)
    Jan 05 20:53:10 ripperd ripright[35397]: Started daemon mode (v0.11)
    Jan 05 20:53:10 ripperd ripright[35398]: Waiting for a CD (/dev/cdrom)
    Jan 05 20:53:33 ripperd su[35385]: pam_unix(su:session): session closed for user ripright
    Jan 05 20:54:40 ripperd systemd[1]: ripright.service start operation timed out. Terminating.
    Jan 05 20:54:40 ripperd systemd[1]: Failed to start RipRight.
    -- Subject: Unit ripright.service has failed
    -- Defined-By: systemd
    -- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
    -- 
    -- Unit ripright.service has failed.
    -- 
    -- The result is failed.
    Jan 05 20:54:40 ripperd systemd[1]: Unit ripright.service entered failed state.
    

    If I comment out the PIDFile directive in the systemd service script:

    #PIDFile=/var/run/ripright/ripright.pid
    

    Then I have no problems, but also no PID file as recommended for a service type of forking:

    # systemctl daemon-reload
    # systemctl start ripright
    # ps -ef | grep ripright
    ripright  35438      1  0 21:03 ?        00:00:00 /usr/local/bin/ripright --daemon --w32-filenames --require-art --folder-art folder.png --output-file %B/%D/%C - ripright %T.flac /opt/ripright/data
    ripright  35439  35438  0 21:03 ?        00:00:00 /usr/local/bin/ripright --daemon --w32-filenames --require-art --folder-art folder.png --output-file %B/%D/%C - ripright %T.flac /opt/ripright/data
    root      35442  31942  0 21:03 pts/0    00:00:00 grep ripright
    [email protected]:~# systemctl status ripright
    ● ripright.service - A minimal CD ripper for Linux modeled on autorip.
       Loaded: loaded (/etc/systemd/system/ripright.service; enabled)
       Active: active (running) since Thu 2017-01-05 21:03:11 EST; 13s ago
      Process: 35437 ExecStart=/usr/local/bin/ripright --daemon --w32-filenames --require-art --folder-art folder.png --output-file %B/%D/%C - %N %T.flac /opt/ripright/data (code=exited, status=0/SUCCESS)
     Main PID: 35438 (ripright)
       CGroup: /system.slice/ripright.service
               ├─35438 /usr/local/bin/ripright --daemon --w32-filenames --require...
               └─35439 /usr/local/bin/ripright --daemon --w32-filenames --require...
    Jan 05 21:03:11 ripperd ripright[35438]: Started daemon mode (v0.11)
    Jan 05 21:03:11 ripperd ripright[35439]: Waiting for a CD (/dev/cdrom)
    # ls -la /run/ripright
    total 0
    drwxr-x---  2 ripright ripright  40 Jan  5 21:04 .
    drwxr-xr-x 16 root     root     540 Jan  5 21:04 ..
    # systemctl stop ripright
    

    Interestingly enough, when I brought PIDFiles back in and commented out User and Group to run ripright as root, daemon-reloading and then starting the script still hangs:

    #User=ripright
    #Group=ripright
    PIDFile=/var/run/ripright/ripright.pid
    

    The same thing happens if I leave User and Group commented out and set PIDFile to produce the PID file directly in the /run directory (noting /var/run is simply a symlink to /run in Debian Jessie):

    #User=ripright
    #Group=ripright
    #PIDFile=/var/run/ripright/ripright.pid
    PIDFile=/run/ripright.pid
    

    Note in all cases I can press Ctrl+C during the hang and the ripright daemon will continue to run; however, if I let the start time out, it'll stop the daemon before printing the error and returning.

    I also went through this post and its comments. The initial approach of using ExecStartPre had the same results; I did not get far with using tmpfiles.d as I couldn't find any information on how to make the changes take effect without rebooting. I tried mount -a but that didn't seem to work.

    • Admin
      Admin almost 6 years
      How did you configure ripright to create a PID file? I could not find this anywhere in your question.
    • Admin
      Admin almost 6 years
      I didn't. The application needs to create the PID file? I see nothing in ripright's documentation or options, and it doesn't look like the source code is doing this at all. What if the application isn't written to create a PID file? Am I supposed to do so in the systemd service script, or in some wrapper script?
    • Admin
      Admin almost 6 years
      If the ripright program doesn't create a PID file, then you don't need to do anything. See serverfault.com/a/817560/126632
    • Admin
      Admin almost 6 years
      Looks like this will work for me; if you want to formulate this as an answer, I'll accept it.
  • Michael Hampton
    Michael Hampton over 4 years
    systemd doesn't create PID files at all. That's the responsibility of the service. As discussed previously, that's not what PIDFile= is for.
  • John Hascall
    John Hascall over 3 years
    Alas, it's too bad that systemd can't be requested to write/delete pidfiles for Type=simple services as it is most in possession of the info to do so.