[systemd-devel] Starting services enabled by filesystem overlay over /etc/

Jonathon Kowalski bl0pbl33p at gmail.com
Mon Feb 11 15:56:56 UTC 2019


On Sunday, February 10, 2019, Andrei Borzenkov <arvidjaar at gmail.com> wrote:

> 09.02.2019 21:45, Matt Schuckmann пишет:
> > I have an embedded system with a readonly rootfs.
> >
> > I've setup a very early service that mounts a writable aufs overlay over
> /etc/.
> >
> >
> > The problem I'm having is systemd is not starting any services that I
> have enabled in that overlay that were not initially enabled in the
> readonly rootfs.
> >
> > ?I've tried placing a calls to systemctl daemon-reload or systemctl
> daemon-reexec just after mounting the overlay but the services are not
> started, after the fact systemctl will report that the services are enabled
> but inactive.
> >
>
> If you are doing it as part of normal startup, then systemd has already
> computed initial "transaction". While daemon-reload makes it rescan for
> and see additional unit definitions, it does not change currently
> running "transaction".
>
> >
> > What do I need to do to get systemd to automatically start the services
> that are marked enabled in that overlay?
> >
>
> I am not aware of any clean way to do it. Attempting to re-queue start
> of default.target will likely be noop as this request is already queued.


Unless I am misunderstanding something (in the code), it wouldn't be a
noop. After the reload/reexec, systemd should have updated the
Wants=/Requires= property of target. Now, the transaction that was
activated previously will not change based on this (because it was computed
in the past, checked for consistency, minimised for impact, jobs
merged/collapsed and then activated). At this point, there isn't even a
transaction, it's just a set of jobs installed on units waiting on each
other in run queue.

However, systemd, if you happen to trigger a start job on default.target
replacing the installed job now, will compute a transaction again, and
trigger jobs for everything again. Since this is all across transactions,
this will result in another transaction being applied, duplicate jobs
produced in both getting merged in installed one, but also the enabled
units starting up, with new jobs installed for those.

So invoking a 'systemctl start default.target --job-mode replace' again
will make the enabled units start up.

However, this has one disadvantage: You may end up having start jobs
triggered for already started->inactive units again (think oneshots)
(because there jobs slots are free after it finishing, so nothing to
coalesce, hence a trigger again). For running units, state change is noop
so it installs and finishes immediately. Where this can be surprising is
later activation triggers a stop job for some unit enabled on boot (through
Conflicts=, PartOf=), and then you end up trigger a start for it again,
producing incorrect results.

Still, all this said, it would be more correct to do it from initramfs as
grawity suggests, and then have all of this computed as part of initial
transaction at boot.

>
> The only workaround I can think of is to make initial boot into target
> that mounts overlay and then triggers start of actual default target.
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/systemd-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20190211/b104f00e/attachment.html>


More information about the systemd-devel mailing list