On Fri, Apr 8, 2022, 12:44 Andreas Hartmann <har...@7x.de> wrote: > On Fri, 2022-04-08 at 12:07 +0300, Mantas Mikulėnas wrote: > > On Fri, Apr 8, 2022 at 10:08 AM Andreas Hartmann <har...@7x.de> wrote: > > > > > > > > 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.) > > Good hint, thank you! > > > > > 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. > > Interesting, I wasn't aware such things could be performed. About udev: > The way I > understand it, udev is mostly involved in dynamic device probing or > managing/reacting to device events. Is that correct? >
It doesn't probe devices (the kernel does that), but it does react to the kernel's "device detected" events – loads additional kernel modules (e.g. if a USB device with specific vid:pid was probed, udev loads the corresponding .ko module), forwards events to userspace (e.g. to systemd), etc. > In my particular scenario, I have a complete devicetree that contains the > nodes > for all the hardware I need. So from my understanding that's enough for the > kernel to load the drivers et al, or am I mistaken? > DT tells the kernel what devices exist without it needing to e.g. scan a bus (which the kernel would do on its own anyway – that's not udev's job), but it *doesn't* tell the kernel what .ko modules to load for them (that's udev's job). So if all necessary drivers are built-in, great. But if some of them are modular, udev is usually still needed, whether the device was discovered through DT or ACPI or something else. > > > - 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...) > > That will make my life a lot easier. I really meant I don't want to > program the > syscalls to the kernel myself etc. > There aren't any other syscalls that would do what /sys does, anyway. The file-based interface (i.e. open/read/write syscalls on /sys) is often the *only* interface. > > > > 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. > > But isn't really any device driver a module? No, they can be compiled into the main kernel image as well (and on embedded systems, most likely they all are, but...still). "Module" specifically means a separate .ko file in /lib/modules, as opposed to the driver being literally part of /vmlinuz. Usually the kernel has some mix of built-in and modular drivers. If udev is responsible for loading > the kernel modules (drivers) then that would mean I can't access any > device at > this stage, right? > I thought that statically defining the devices and their drivers in the > devicetree makes them available without ''extra effort''. > The device tree doesn't specify Linux drivers directly, there's still a layer of translating the abstract DT 'compatible' strings (or vendor/product IDs, or ACPI IDs, or whatever) to Linux-specific paths. For built-in drivers, that mapping is indeed also built in to the kernel, but for modular ones it's in /lib/.../modules.alias and has to be read by udev/libkmod, and then the corresponding .ko file has to be given to the kernel. > > > > 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. > > Likely not, but I think it's the most simple to wrap my head around for > starters. > I'll do some more research about generators and when my devices become > available > in the sysfs. > > Thank you very much! > > > hartan > > >