[systemd-devel] How to chain services driven by a timer?

Mantas Mikulėnas grawity at gmail.com
Wed Apr 10 15:05:08 UTC 2024


On Wed, Apr 10, 2024 at 5:50 PM Brian Reichert <reichert at numachi.com> wrote:

> My goal is to implement a service that runs after logrotate.service
> completes.
>
> logrotate.service is triggered by a timer logrotate.timer.
>
> I don't want to modify either of logrotate.service or logrotate.timer,
> as they are provided by the OS vendor (SLES 12 SP5, in my case.)
>

In a sense, you're already modifying units provided by the OS vendor –
whenever you use `systemctl enable` to link a service into
multi-user.target.wants/, that "modifies" multi-user.target by adding a
Wants= dependency, just that that happens in a way that does not get reset
during package updates. Systemd has plenty of mechanisms for that; e.g. you
can add additional settings to
`/etc/systemd/system/logrotate.service.d/*.conf` (using systemctl edit) or
you can link some units into logrotate.service.wants/ in the same way as is
done with .targets.

(You need to do this to the .service, as that's what actually gets
activated periodically.)

My current service file:
>
>   [Unit]
>   Description=Activities after logrotation
>
>   Requires=logrotate.service
>   Wants=logrotate.service
>

That seems like the complete opposite of what you're trying to achieve –
this makes *your* unit trigger the start of logrotate, not the other way
around.


>   After=logrotate.service
>

After= does not define a trigger. It only defines the execution order when
multiple units are triggered at once.


>
>   [Service]
>   #Type=oneshot
>   Type=simple
>
>   ExecStart=/usr/bin/logger 'XXX post log rotation'
>
>   [Install]
>   WantedBy=timers.target
>

The WantedBy= (or the .wants/ symlink that results from it) is the only
trigger being defined in your unit. But since the service was set up to be
started by timers.target, and timers.target itself only starts once during
boot (when timers get scheduled), that means your service is also started
once during boot and that's that.

If you want it to be triggered by logrotate.service, then you need
WantedBy=logrotate.service. Then each time logrotate.service is started on
schedule, it'll cause your service to be started as a dependency, and the
After= will actually work to define the order.

-- 
Mantas Mikulėnas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20240410/2c7ca938/attachment-0001.htm>


More information about the systemd-devel mailing list