[systemd-devel] Intercepting/Delaying the boot process

Mantas Mikulėnas grawity at gmail.com
Fri Apr 8 09:07:45 UTC 2022


On Fri, Apr 8, 2022 at 10:08 AM Andreas Hartmann <hartan at 7x.de> wrote:

> Hi,
>
>
> I've been owning a Pinephone for a while now and one thing that I find
> rather
> annoying is that whenever I plug the charger in, the thing will perform a
> full
> boot. I often find myself just wanting to plug it in without performing a
> full
> boot, i.e. only to have it charge and maybe see how far it has charged
> already.
>
> To this end I was wondering whether it would be feasible to "hook" into
> the boot
> process, somewhere before the disks are decrypted, to only have it charge
> (or
> continue to boot when I press some magic button maybe). Looking at the
> order of
> service startup I was thinking about maybe intercepting the boot between
> "local-
> fs-pre.target" and "machines.target" because nothing happens there on my
> setup.
>

That "between" doesn't make sense, because the boot process waits for
machines.target *in parallel* with waiting for all other services that are
started via multi-user. The systemd boot process is non-linear and doesn't
have a fixed order, it's a dependency graph.

According to bootup(7), there are two main synchronization points,
sysinit.target and basic.target, which all non-"early" services will wait
for. So if you have a service with Before=basic.target, it'll delay startup
of all normal services. (It would then need to explicitly specify After=
for things it needs, like specific devices or sockets.)

If the device was using an initramfs (which has a fully separate boot
process, its own udevd, etc.) then you could make the initramfs decide
between starting a normal boot vs minimal boot depending on charger status.
If it doesn't have an initramfs, then systemd *generators* could also be
used to dynamically swap default.target (or alter units in general)
depending on some condition, as they also run after /sys is mounted but
before any units at all are started... though this would only work if your
wanted sysfs entries appear without needing udev.


> For this to work ideally I would like to have the sysfs available so I
> don't have
> to interact with the kernel directly. So here are my questions:


> - After which stage in the boot process is the sysfs available?
>

It is mounted by init before any units are started. (sysfs *is* how you
interact with the kernel though...)

But that doesn't mean all *devices* are available in it – many things could
take some time to appear, and devices requiring drivers to be loaded as
modules would only become available some unspecified time after
systemd-udevd.service is started.

If you need a specific /sys or /dev device that's not guaranteed to be
available statically, the correct way would be to use an After= dependency
on that specific device (like After=dev-sda.device). Systemd relies on udev
events for this.


> - Can I delay the boot for an indefinite amount of time, or will this
> cause some
> services later on in the process to timeout and fail?
>

In theory you could, similar to how systemd-fsck works, but I'm not sure if
that's the right way to do what you want.


> - Is it possible for a service during early boot to command a system
> shutdown
> instead of continuing to boot?
> - May I simply take control of the TTY and clear/rewrite it as I like, or
> does
> systemd use some magic for this?
>
> Thank you in advance!
>
>
> hartan
>
>
>

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


More information about the systemd-devel mailing list