Suppose, not hypothetically, that your system is running some systemd based service or daemon that resets or erase your carefully cultivated state when it restarts. One example is systemd-networkd , although you can turn that off (or parts of it off, at least), but there are likely others. To clean up after this happens, you'd like to automatically restart or redo something after a systemd unit is restarted. Systemd supports this, but I found it slightly unclear how you want to do this and today I poked at it, so it's time for notes.
(This is somewhat different from triggering one unit when another unit becomes active , which I think is still not possible in general.)
First, you need to put whatever you want to do into a script and a .service unit that will run the script. The traditional way to run a script through a .service unit is:
[Unit] .... [Service] Type=oneshot RemainAfterExit=True ExecStart=/your/script/here [Install] WantedBy=multi-user.target
( The 'RemainAfterExit' is load-bearing , also .)
To get this unit to run after another unit is started or restarted, what you need is
PartOf=
, which causes your unit to be stopped and started when the other unit is, along with '
After=
' so that your unit starts after the other unit instead of racing it (which could be counterproductive when what you want to do is fix up something from the other unit). So you add:
[Unit] ... PartOf=systemd-networkd.service After=systemd-networkd.service
(This is what works for me in light testing. This assumes that the unit you want to re-run after is normally always running, as systemd-networkd is.)
In testing, you don't need to have your unit specifically enabled by itself, although you may want it to be for clarity and other reasons. Even if your unit isn't specifically enabled, systemd will start it after the other unit because of the PartOf=. If the other unit is started all of the time (as is usually the case for systemd-networkd), this effectively makes your unit enabled, although not in an obvious way (which is why I think you should specifically 'systemctl enable' it, to make it obvious). I think you can have your .service unit enabled and active without having the other unit enabled, or even present.
You can declare yourself PartOf a .target unit, and some stock package systemd units do for various services. And a .target unit can be PartOf a .service; on Fedora, 'sshd-keygen.target' is PartOf sshd.service in a surprisingly clever little arrangement to generate only the necessary keys through a templated 'sshd-keygen@.service' unit.
I admit that the whole collection of Wants=, Requires=, Requisite=, BindsTo= , PartOf=, Upholds=, and so on are somewhat confusing to me. In the past, I've used the wrong version and suffered the consequences , and I'm not sure I have them entirely right in this entry.
Note that as far as I know, PartOf= has those Requires= consequences , where if the other unit is stopped, yours will be too. In a simple 'run a script after the other unit starts' situation, stopping your unit does nothing and can be ignored.
(If this seems complicated, well, I think it is, and I think one part of the complication is that we're trying to use systemd as an event-based system when it isn't one.)