Systemd: How to run a job both periodically and once at system shutdown

systemdsystemd-timer

I want to run a job periodically (e.g., every 5 minutes), and finally once at system shutdown.

Systemd supports timers, which could be used to run a job periodically. It also supports to run a job at system shutdown by using the ExecStop hook like this:

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=<some command to run at system shutdown>

But I struggle to combine both approaches. The only option that I can think of is to write two independent services:

  1. One service which is triggered by a timer task
  2. Another service which uses the ExecStop trick to be executed at system shutdown

I think it should work, but there are two problems with that approach:

  1. There is a lot of code duplication concerning security settings
  2. There is not protection for systemd against running the job in parallel. For instance, if the shutdown is triggered while the periodic job has been just executed, both jobs will run in parallel.

Question:

  • What is the best way to run a job both periodically and once at system shutdown?
  • Is it possible to avoid having two (mostly duplicated) service files?

To get an impression what I mean with code duplication, these are some security settings that I use when running the job:

User=foo
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
NoNewPrivileges=yes
PrivateDevices=yes
PrivateUsers=yes
CapabilityBoundingSet=
AmbientCapabilities=
SystemCallFilter=~@clock @module @mount @obsolete @raw-io ptrace
ReadOnlyPaths=-/some/path

In my sketched approach, I would need to duplicate this code (one copy for each service).

Best Answer

You can solve the duplicate by creating two directories: foo-at-shutdown.service.d and 'foo-periodic.service.d`.

In one folder create a file named foo-shared.conf.
Use a symlink to add it to the second folder.

These are "drop-in" units, which will get pulled into the main config files. They are documented more in man systemd.unit if you search for "drop-in" there.

I think having the two service files, a timer file and the shared drop-in unit files is a reasonable approach here.

Related Question