[systemd-devel] Starting a service at shutdown time, with requirements

Mantas Mikulėnas grawity at gmail.com
Tue Mar 20 19:16:59 UTC 2018


On Tue, Mar 20, 2018, 21:09 Colin Walters <walters at verbum.org> wrote:

> I'm working on: https://github.com/ostreedev/ostree/issues/545
> TL;DR:
> libostree is an image-like update system, and I want to take some
> actions at system shutdown time, specifically performing a "snapshot+merge"
> of /etc after most other services are shut down.  The way ostree
> handles /etc (IMO a lot more correctly) is a major distinguishing point
> from a lot
> of other image-like systems out there.
>
> What I have so far is this (distilled into a simple easily tested unit not
> tied to ostree):
>
> [Unit]
> Description=cgwalters-shutdown
> DefaultDependencies=no
> After=shutdown.target
> Before=final.target
> # FIXME
> # Before=sysroot.mount
> [Service]
> Type=oneshot
> RemainAfterExit=yes
> ExecStart=/bin/sh -c 'sleep 5 && ls -ald /sysroot/ostree/repo'
> [Install]
> WantedBy=final.target
>
> I modeled this after `halt-local.service`.  But as you
> might infer from the FIXME, the problem I'm hitting is that the /sysroot
> mount is unmounted before this service is started.  I think the problem
> I'm hitting is this bit from `man systemd.unit`:
>
> > Given two units with any ordering dependency between them, if one unit
> is shut down and the other is started up, the shutdown is ordered before
> the start-up.
>
> Which does sort of make sense to me in general; but is problematic for
> this "start service on shutdown" case.   I was looking a bit at the way
> plymouth
> hooks into shutdown, but it seemed complex, and as plymouth doesn't (AFAIK)
> have any real dependencies on the filesystem state I'm not sure it matches
> what I need.
>
> I can think of ways to hack around this, by e.g. having the service start
> up on
> shutdown, take a snapshot of a private mount namespace, have it be excluded
> from the Conflicts=shutdown.target, then have a unit that triggers before
> final.target
> (like the above) that sends an IPC to actually do what I want.  But that
> adds a notable
> amount of complexity, and I'd like to have this process feel as
> obvious/transparent as possible.
>
> Another way I've thought about handling this is to basically invert things
> so that
> we have a "stub" unit that starts on bootup, and its ExecStop does the
> real work:
>
> [Unit]
> Description=cgwalters-startstop
> ConditionPathExists=/run/ostree-booted
> DefaultDependencies=no
> RequiresMountsFor=/sysroot
> After=basic.target
> Before=multi-user.target
> Conflicts=final.target
> Before=final.target
>
> [Service]
> Type=oneshot
> RemainAfterExit=yes
> ExecStart=/usr/bin/true
> ExecStop=/usr/bin/sh -c 'sleep 5 && ls -ald /ostree/repo'
>
> [Install]
> WantedBy=multi-user.target
>
> Which seems to work but feels...a bit ugly?
>

Currently this is the recommended method; it's a little ugly indeed but
fits quite well into the shutdown process. Recent systemd versions should
let you skip the dummy ExecStart.

> --

Mantas Mikulėnas <grawity at gmail.com>
Sent from my phone
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20180320/1cdce9e7/attachment-0001.html>


More information about the systemd-devel mailing list