dracutdevs / dracut

dracut the event driven initramfs infrastructure
https://github.com/dracutdevs/dracut/wiki
GNU General Public License v2.0
604 stars 400 forks source link

/boot/efi added as a hard dependency in hostonly mode #2044

Open aafeijoo-suse opened 2 years ago

aafeijoo-suse commented 2 years ago

Since https://github.com/dracutdevs/dracut/commit/a956a464 (year 2014), when running dracut in hostonly mode, if /boot/efi is mounted (it does not check /efi), the initrd will contain a new device unit for /boot/efi with Wants=initrd.target.

# lsblk -o UUID,MOUNTPOINT /dev/vda1
UUID                                 MOUNTPOINT
7DEE-9CC9                            /boot/efi
# lsinitrd | grep "\.device"
drwxr-xr-x   1 root     root            0 Nov  8 09:51 etc/systemd/system/dev-disk-by\x2duuid-7DEE\x2d9CC9.device.d
-rw-r--r--   1 root     root           46 Nov  8 09:51 etc/systemd/system/dev-disk-by\x2duuid-7DEE\x2d9CC9.device.d/timeout.conf
lrwxrwxrwx   1 root     root           42 Nov  8 09:51 etc/systemd/system/initrd.target.wants/dev-disk-by\x2duuid-7DEE\x2d9CC9.device -> ../dev-disk-by\x2duuid-7DEE\x2d9CC9.device

The commit message says "Add /boot/efi to device paths, so the filesystem driver is included and it can be repaired in the initramfs.". If so, to include just the driver, we are adding a a hard dependency to a .device unit that should not be needed at this point in the boot process. Do we really need this for any reason that maybe I'm missing (UEFI mode?) or can we revert https://github.com/dracutdevs/dracut/commit/a956a464 to speed up the boot process?

What I also found strange is the way to disable this, which is by using the --no-hostonly-cmdline option (https://github.com/dracutdevs/dracut/commit/ee4b74fb), which by definition is only intended to "Do not store kernel command line arguments needed in the initramfs.". I think we should add a new option with a proper name (--no-hostonly-devices?) to disable this addition.

Any thoughts on this?

johannbg commented 1 year ago

Some points to consider here... How changing this might affect none systemd based system since those distro's are also our target audience. How changes this might affect bootloaders ( such as grub2 which for example is the reason why we hardcode /boot in dracut.install ) How changing this might affect rescue ( rd.break ... mount --type vfat /dev/$foo /boot/efi ) ...

mrmazda commented 1 year ago

What possible reason could there be to include /boot/efi in initrd when /boot/efi does not exist in /etc/fstab? And what about when /boot/efi is an immutable regular file instead of a directory (to protect against freespace wasted by placement of files not relevant to an installation with discrete /boot filesystem containing kernel and initrd, but no type of bootloader).

aafeijoo-suse commented 1 year ago

Some points to consider here... How changing this might affect none systemd based system since those distro's are also our target audience.

Why would non-systemd distros need to mount /boot/efi during the initrd phase at boot?

How changes this might affect bootloaders ( such as grub2 which for example is the reason why we hardcode /boot in dracut.install )

But... the initrd starts after the bootloader ends...

How changing this might affect rescue ( rd.break ... mount --type vfat /dev/$foo /boot/efi ) ...

If we only need the drivers to mount /boot/efi in the emergency shell, we could add them to host_fs_types, but exclude the device from host_devs, so there is no dependency at boot:

diff --git a/dracut.sh b/dracut.sh
index 1f6f0aee..699280d1 100755
--- a/dracut.sh
+++ b/dracut.sh
@@ -1662,7 +1662,15 @@ if [[ $hostonly ]] && [[ $hostonly_default_device != "no" ]]; then
         _dev=$(find_block_device "$mp")
         _bdev=$(readlink -f "/dev/block/$_dev")
         [[ -b $_bdev ]] && _dev=$_bdev
-        [[ $mp == "/" ]] && root_devs+=("$_dev")
+        case "$mp" in
+            "/")
+                root_devs+=("$_dev")
+                ;;
+            "/boot/efi")
+                _get_fs_type "$dev"
+                continue
+                ;;
+        esac
         push_host_devs "$_dev"
         if [[ $(find_mp_fstype "$mp") == btrfs ]]; then
             for i in $(btrfs_devs "$mp"); do