[arch-general] Systemd boot
I2'm trying to fully make sense of the boot process with systemd. I've read various pages from the manual, including bootup(7). There are two points I don't fully understand. * Filesystem mounts during initrd The man page, under the initrd section, says: "systemd detects that it is run within an initrd [...]. The bootup process begins identical to the system manager bootup (see above) until it reaches basic.target. [...] Before any file systems are mounted, it must be determined whether the system will resume from hibernation or proceed with normal boot." In my mind, that part self-contradicts when both saying that 1) the bootup proceeds identical to the system manager bootup and 2) a determination on whether to mount file systems is made /after/ basic.target. This is because some file systems (including, in most cases, the root file systems) would have been mounted before local-fs.target, which is ordered before basic.target. So either the process is not really identical until basic.target, or I'm getting something wrong. * Instances I gather that the systemd which runs inside the initrd is a completely separate instance from the one which then runs in the booted system. Which implies - as discussed above - that the system initialization sequence from beginning to basic.target actually happens twice. Does this means than any initialization units which could potentially be run twice - once in the initrd and once in the booted system - should be instrumented to avoid running their logic twice (in the cases where that's not needed or even harmful)? Let's consider for example an hypothetical service with "WantedBy=cryptsetup-pre.target", which decrypts a keyfile using an hardware token. This keyfile is then consumed by systemd-cryptsetup-generator with keyfile-erase=on. What happens if the service is run twice, but the key is consumed only the first time? A decrypted keyfile remains in the system. What's the correct approach to avoid such a scenario? Riccardo
On 28-11-2020 10:22, Riccardo Paolo Bestetti wrote:
I2'm trying to fully make sense of the boot process with systemd.
I've read various pages from the manual, including bootup(7). There are two points I don't fully understand.
* Filesystem mounts during initrd The man page, under the initrd section, says: "systemd detects that it is run within an initrd [...]. The bootup process begins identical to the system manager bootup (see above) until it reaches basic.target. [...] Before any file systems are mounted, it must be determined whether the system will resume from hibernation or proceed with normal boot."
In my mind, that part self-contradicts when both saying that 1) the bootup proceeds identical to the system manager bootup and 2) a determination on whether to mount file systems is made /after/ basic.target. This is because some file systems (including, in most cases, the root file systems) would have been mounted before local-fs.target, which is ordered before basic.target.
So either the process is not really identical until basic.target, or I'm getting something wrong.
* Instances I gather that the systemd which runs inside the initrd is a completely separate instance from the one which then runs in the booted system. Which implies - as discussed above - that the system initialization sequence from beginning to basic.target actually happens twice.
Does this means than any initialization units which could potentially be run twice - once in the initrd and once in the booted system - should be instrumented to avoid running their logic twice (in the cases where that's not needed or even harmful)?
Let's consider for example an hypothetical service with "WantedBy=cryptsetup-pre.target", which decrypts a keyfile using an hardware token. This keyfile is then consumed by systemd-cryptsetup-generator with keyfile-erase=on. What happens if the service is run twice, but the key is consumed only the first time? A decrypted keyfile remains in the system.
What's the correct approach to avoid such a scenario?
Riccardo
Archlinux has its own boot process, described at [1] Check the initramfs section and you'll see a reference to mkinitcpio [2] . On the mkinitcpio page look at the Common Hooks section. Basically there are 2 systems that archlinux can use in initramfs : busybox and systemd . Check the hooks in your mkinitcpio.conf : are you using the systemd hook or any of the sd-* hooks ? If yes, mkinitpio sd-encrypt hook is what handles your encrypted drives. see [3] for details If no, busybox encrypt hook is responsible, see [4]. Lone_Wolf [1] https://wiki.archlinux.org/index.php/Arch_boot_process [2] https://wiki.archlinux.org/index.php/Mkinitcpio [3] https://wiki.archlinux.org/index.php/Dm-crypt/System_configuration#Using_sd-... [4] https://wiki.archlinux.org/index.php/Mkinitcpio#Runtime_customization
On Sat Nov 28, 2020 at 1:58 PM CET, Lone_Wolf wrote:
Archlinux has its own boot process, described at [1]
Check the initramfs section and you'll see a reference to mkinitcpio [2] .
On the mkinitcpio page look at the Common Hooks section.
Basically there are 2 systems that archlinux can use in initramfs : busybox and systemd .
Check the hooks in your mkinitcpio.conf : are you using the systemd hook or any of the sd-* hooks ?
If yes, mkinitpio sd-encrypt hook is what handles your encrypted drives. see [3] for details
If no, busybox encrypt hook is responsible, see [4]. I'm informed on what the supported boot processed for Arch are, and I very well known which one I'm running, as I configured it. :)
I'm grateful for your help, but you didn't really answer any of my questions, which are about some specifics of the systemd boot process that I'd like to better understand. Riccardo
On 28-11-2020 19:24, Riccardo Paolo Bestetti wrote:
I'm informed on what the supported boot processed for Arch are, and I very well known which one I'm running, as I configured it. :)
I'm grateful for your help, but you didn't really answer any of my questions, which are about some specifics of the systemd boot process that I'd like to better understand.
Riccardo
It wasn't clear to me (and still is not) what initramfs environment your questions were about. Do you want answers based on systemd manpages OR on a systemd initramfs as setup by mkinitcpio on archlinux ? If the former I can't help further . If the latter : In folder /usr/lib/initcpio/install/ you'll find the systemd , sd-encrypt , sd-lvm2 , sd-shutdown and sd-vconsole hook scripts . Look at their contents and notice they add specific services and targets. Basic.target is NOT one of them, which suggests that it doesn't matter in the initramfs stage of a systemd initramfs boot on archlinux. Since absence / presence of hooks in mkinitcpio.conf changes what happens in the initramfs stage, you may want to use the lsinitcpio command to look directly in your mkinitcpio initramfs image(s). LW
On Sun Nov 29, 2020 at 1:14 PM CET, Lone_Wolf wrote:
It wasn't clear to me (and still is not) what initramfs environment your questions were about.
Do you want answers based on systemd manpages OR on a systemd initramfs as setup by mkinitcpio on archlinux ? As I conjecture below, I don't think there is any difference between the two.
In folder /usr/lib/initcpio/install/ you'll find the systemd , sd-encrypt , sd-lvm2 , sd-shutdown and sd-vconsole hook scripts .
Look at their contents and notice they add specific services and targets.
Basic.target is NOT one of them, which suggests that it doesn't matter in the initramfs stage of a systemd initramfs boot on archlinux.
This is /not/ correct. Please verify your information more carefully before asserting on a public mailing list as to avoid creating confusion for future readers who may stumble upon the archives. basic.target is part of Arch's (and most other distro's) systemd initrd, as you will find /easily/ out by examining the output of `journalctl -b -g "Basic System"`. Although as you correctly observe, it is not explicitly pulled in, so let's take a look at how the systemd install hook works: add_systemd_unit() { # Add a systemd unit file to the initcpio image. Hard dependencies # on binaries and other unit files will be discovered and added. # $1: path to rules file (or name of rules file) (slightly reformatted to better fit the email line limit) I.e. (way) more units are pulled in w.r.t. the ones which are explicitly added. basic.target, in particular, gets pulled in as it is an hard dependency (Required-by) initrd.target. You can verify this by extracting your initrd and observing the hard dependency in /lib/systemd/system/initrd.target (which is explicitly pulled in from the systemd install hook). You can also find this out on a running system with the following command: sudo systemctl list-dependencies --reverse basic.target As far as I can tell, Arch's systemd boot process is pretty much the same as the standard one. Please do point out any real, proven differences there might be between Arch's systemd boot process and what's described in bootup(7), if you can identify any. I would be definitely interesting in knowing, as I'm developing a new software package which might be sensible to those. Until then, I will work under the assumption that there's no such difference - as I cannot identify any - so my original questions still stand. For reference, I found the answer of the final question I posed in my original email. An useful approach in the case of the example is to add a drop-in to the templates of interest, to which you can add a (soft or hard, as needed) dependecy to your templates, propagating the parameter as needed. E.g.: /etc/systemd/systemd/systemd-cryptsetup@.service/10-drop-in.conf: [Unit] Wants=whatever-dependency@%i.service After=whatever-dependency@%i.service systemd-cryptsetup-generator will (if configured correctly) only generate the units for the volumes which still need activation, enabling more granularity in key deployment. Riccardo
"Riccardo Paolo Bestetti" <pbl@bestov.io> wrote:
I2'm trying to fully make sense of the boot process with systemd.
I've read various pages from the manual, including bootup(7). There are two points I don't fully understand.
* Filesystem mounts during initrd The man page, under the initrd section, says: "systemd detects that it is run within an initrd [...]. The bootup process begins identical to the system manager bootup (see above) until it reaches basic.target. [...] Before any file systems are mounted, it must be determined whether the system will resume from hibernation or proceed with normal boot."
In my mind, that part self-contradicts when both saying that 1) the bootup proceeds identical to the system manager bootup and 2) a determination on whether to mount file systems is made /after/ basic.target. This is because some file systems (including, in most cases, the root file systems) would have been mounted before local-fs.target, which is ordered before basic.target.
So either the process is not really identical until basic.target, or I'm getting something wrong.
* Instances I gather that the systemd which runs inside the initrd is a completely separate instance from the one which then runs in the booted system. Which implies - as discussed above - that the system initialization sequence from beginning to basic.target actually happens twice.
Does this means than any initialization units which could potentially be run twice - once in the initrd and once in the booted system - should be instrumented to avoid running their logic twice (in the cases where that's not needed or even harmful)?
Let's consider for example an hypothetical service with "WantedBy=cryptsetup-pre.target", which decrypts a keyfile using an hardware token. This keyfile is then consumed by systemd-cryptsetup-generator with keyfile-erase=on. What happens if the service is run twice, but the key is consumed only the first time? A decrypted keyfile remains in the system.
What's the correct approach to avoid such a scenario?
Riccardo
I am confused my self about the exact booting procedures. Yet I do believe that you are missing the important issue of chroot. In a simplistic decription, the system boots into an initrd. Then it shutoff. CHROOT. And now it will reboot into a working system. Do examine the journal of a boot process. In particular, look for the chroot line: systemd[1]: Switching root. And examine carefully what happen before that line. And after it. -- u34
participants (3)
-
Lone_Wolf
-
Riccardo Paolo Bestetti
-
u34@net9.ga