To my surprise, my contraption from the previous article didn't survive a reboot. WTF?! It turned out that in Fedora 19 the /var/run/ is a symlink into /run/ which has been turned into tmpfs. Goddamnit! It literally means, that it is pointless to create /var/run/<the daemon name here>/ with correct permissions in RPM spec-file. Everything will be wiped clean on next reboot anyway.
So, I just had to study the systemd some more.
This is my version 2 (the Unit and Install -parts are unchanged):
[Service] Type=forking PrivateTmp=yes User=nobody Group=nobody # Run ExecStartPre with root-permissions PermissionsStartOnly=true ExecStartPre=-/usr/bin/mkdir /var/run/dhis ExecStartPre=/usr/bin/chown -R nobody:nobody /var/run/dhis/ # Run ExecStart with User=nobody / Group=nobody ExecStart=/usr/sbin/dhid -P /var/run/dhis/dhid.pid PIDFile=/var/run/dhis/dhid.pid
The solution is two-fold. First an ExecStartPre-directive is required. It allows to run stuff before actually executing the deamon. My first thing to do is create a directory, the minus sign before the command says to ignore any possible errors during creation. The target is mainly to ignore any errors from the fact that creation would fail due to the directory already existing. Anyway, all errors are ignored regardless of the reason.
The second command to run is to make sure that permissions are set correctly for my daemon to create a PID-file into the directory created earlier. That must succeed or there will be no attempt to start the daemon. chowning the directory will fail if the directory does not exist, or any other possible reason.
Sounds nice, huh? Initially I couldn't get that working. It was simply due to reason, that the entire Service-part is run as the user pointed by the User=nobody and Group=nobody -directives. That user was intentionally chosen, because it has very limited permission anywhere or anything. Now it cannot create any new directories into /var/run/. Darn!
This where the solution's 2nd part comes in. Somebody designing the systemd thought about this. Using the PermissionsStartOnly-directive does the security context switch at the last moment before starting the daemon. This effectively changes the default behavior to allow running Service-part as root, except for the daemon. Exactly what I was looking for! Now my daemon starts each and every time. Even during boot.
Another thing which I noticed, is that when I edit a systemd service-file, the changes really don't affect before I do a systemctl --system daemon-reload. It was a big surprise to me, after all in traditional init.d everything was effective immediately.
PS. Why cronie does not create a PID-file? I had an issue in CentOS where I had not one, but two cron-daemons running at the same time. This is yet another reason to go systemd, it simply works better with ill-behaving deamons like cronie.
Thanks for the write up, this helped me find the "real" answer to this issue. I looked in my /var/run and saw that avahi and apache were being created with their own users/groups for their lock and pid files. So I looked at their service scripts to see if they did it similar to your method, they didn't... so I kept digging and found this:
Essentially you can just add an entry to /etc/tmpfiles.d/foo.conf like this:
$ cat /etc/tmpfiles.d/fail2ban.conf
D /var/run/fail2ban 0755 fail2ban fail2ban