Adding a dependency into upstream-supplied systemd units

I recently restarted all my VMs at once and found that several managed to start services before they finished mounting their NFS shares. These shares back apache virtualhosts, mysql databases, and ultimately left several services in non-functional states. Systemd has the ability to depend on services (Requires=, and others) as well as filesystems (RequiresMountsFor=). However, I don’t want to modify or replace the .service files installed from the package. I’d have to manually reconcile changes during updates, and it just generally isn’t nice.

Turns out systemd took this into account. From man systemd.unit:

Along with a unit file foo.service, a directory foo.service.d/ may exist. All files with the suffix “.conf” from this directory will be parsed after the file itself is parsed. This is useful to alter or add configuration settings to a unit, without having to modify their unit files. Make sure that the file that is included has the appropriate section headers before any directive. Note that for instanced units this logic will first look for the instance “.d/” subdirectory and read its “.conf” files, followed by the template “.d/” subdirectory and reads its “.conf” files.

Great, so to add directives to the httpd.service, make a .d directory to contain your additions:

$ sudo mkdir -p /etc/systemd/system/httpd.service.d

Then populate it. Since I depend on filesystems, I added a RequiresMountsFor:

$ cat /etc/systemd/system/httpd.service.d/fix-nfs.conf
RequiresMountsFor=/var/www/sites /opt/ssl

You’ll have to issue a daemon-reload to systemd for the additions to be detected.

You can test by umounting the directories you indicated, then systemctl start httpd.service. Systemd will note that it requires those directories, and ensure they’re mounted before starting httpd. Nice.