From c9c9edb2613f6750f8f590b012dd83a9f6c682e1 Mon Sep 17 00:00:00 2001 From: Itxaka Date: Sun, 11 Feb 2024 18:37:24 +0100 Subject: [PATCH] Mount cdrom efiboot contents under /run/rootfsbase (#224) Signed-off-by: Itxaka --- internal/constants/constants.go | 72 +++++++++++++++++---------------- pkg/mount/dag_steps.go | 52 +++++++++++++++++++----- pkg/mount/dag_uki_boot.go | 4 +- 3 files changed, 80 insertions(+), 48 deletions(-) diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 0b7ad06..924e571 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -11,46 +11,48 @@ func GetCloudInitPaths() []string { return []string{"/system/oem", "/oem/", "/usr/local/cloud-config/"} } -// GenericKernelDrivers retusn a list of generic kernel drivers to insmod during uki mode +// GenericKernelDrivers returns a list of generic kernel drivers to insmod during uki mode // as they could be useful for a lot of situations. func GenericKernelDrivers() []string { - return []string{"virtio", "ata_piix", "cdrom", "ext4", "iso9660", "usb_storage", "ahci", - "virtio_blk", "virtio_scsi", "virtio_net", "nvme", "overlay", "libata", "sr_mod", "simpledrm"} + return []string{"virtio", "ata_piix", "cdrom", "ext4", "iso9660", "usb_storage", "ahci", "fat", "vfat", + "virtio_blk", "virtio_scsi", "virtio_net", "nvme", "overlay", "libata", "sr_mod", "simpledrm", "loop"} } var ErrAlreadyMounted = errors.New("already mounted") const ( - OpCustomMounts = "custom-mount" - OpDiscoverState = "discover-state" - OpMountState = "mount-state" - OpMountBind = "mount-bind" - OpMountRoot = "mount-root" - OpOverlayMount = "overlay-mount" - OpWriteFstab = "write-fstab" - OpMountBaseOverlay = "mount-base-overlay" - OpMountOEM = "mount-oem" - OpRootfsHook = "rootfs-hook" - OpInitramfsHook = "initramfs-hook" - OpLoadConfig = "load-config" - OpMountTmpfs = "mount-tmpfs" - OpRemountRootRO = "remount-ro" - OpUkiInit = "uki-init" - OpSentinel = "create-sentinel" - OpUkiUdev = "uki-udev" - OpUkiBaseMounts = "uki-base-mounts" - OpUkiKernelModules = "uki-kernel-modules" - OpWaitForSysroot = "wait-for-sysroot" - OpLvmActivate = "lvm-activation" - OpKcryptUnlock = "unlock-all" - OpKcryptUpgrade = "upgrade-kcrypt" - OpUkiKcrypt = "uki-unlock" - OpUkiMountLivecd = "mount-livecd" - UkiLivecdMountPoint = "/run/initramfs/live" - UkiLivecdPath = "/dev/disk/by-label/UKI_ISO_INSTALL" - UkiDefaultcdrom = "/dev/sr0" - UkiDefaultcdromFsType = "iso9660" - PersistentStateTarget = "/usr/local/.state" - LogDir = "/run/immucore" - LinuxFs = "ext4" + OpCustomMounts = "custom-mount" + OpDiscoverState = "discover-state" + OpMountState = "mount-state" + OpMountBind = "mount-bind" + OpMountRoot = "mount-root" + OpOverlayMount = "overlay-mount" + OpWriteFstab = "write-fstab" + OpMountBaseOverlay = "mount-base-overlay" + OpMountOEM = "mount-oem" + OpRootfsHook = "rootfs-hook" + OpInitramfsHook = "initramfs-hook" + OpLoadConfig = "load-config" + OpMountTmpfs = "mount-tmpfs" + OpRemountRootRO = "remount-ro" + OpUkiInit = "uki-init" + OpSentinel = "create-sentinel" + OpUkiUdev = "uki-udev" + OpUkiBaseMounts = "uki-base-mounts" + OpUkiKernelModules = "uki-kernel-modules" + OpWaitForSysroot = "wait-for-sysroot" + OpLvmActivate = "lvm-activation" + OpKcryptUnlock = "unlock-all" + OpKcryptUpgrade = "upgrade-kcrypt" + OpUkiKcrypt = "uki-unlock" + OpUkiMountLivecd = "mount-livecd" + UkiLivecdMountPoint = "/run/initramfs/live" + UkiIsoBaseTree = "/run/rootfsbase" + UkiIsoBootImage = "efiboot.img" + UkiLivecdPath = "/dev/disk/by-label/UKI_ISO_INSTALL" + UkiDefaultcdrom = "/dev/sr0" + UkiDefaultcdromFsType = "iso9660" + UkiDefaultEfiimgFsType = "vfat" + PersistentStateTarget = "/usr/local/.state" + LogDir = "/run/immucore" ) diff --git a/pkg/mount/dag_steps.go b/pkg/mount/dag_steps.go index 9e59613..093bbaa 100644 --- a/pkg/mount/dag_steps.go +++ b/pkg/mount/dag_steps.go @@ -720,6 +720,8 @@ func (s *State) UKIUnlock(g *herd.Graph, opts ...herd.OpOption) error { // to mimic the same behavior as the livecd on non-uki boot. func (s *State) MountLiveCd(g *herd.Graph, opts ...herd.OpOption) error { return g.Add(cnst.OpUkiMountLivecd, append(opts, herd.WithCallback(func(ctx context.Context) error { + internalUtils.CloseLogFiles() + // If we are booting from Install Media if internalUtils.EfiBootFromInstall() { internalUtils.Log.Debug().Msg("Not mounting livecd as we think we are booting from removable media") @@ -729,30 +731,58 @@ func (s *State) MountLiveCd(g *herd.Graph, opts ...herd.OpOption) error { err := os.MkdirAll(s.path(cnst.UkiLivecdMountPoint), 0755) if err != nil { internalUtils.Log.Err(err).Msg(fmt.Sprintf("Creating %s", cnst.UkiLivecdMountPoint)) + return err + } + err = os.MkdirAll(s.path(cnst.UkiIsoBaseTree), 0755) + if err != nil { + internalUtils.Log.Err(err).Msg(fmt.Sprintf("Creating %s", cnst.UkiIsoBaseTree)) return nil } + + // Select the correct device to mount // Try to find the CDROM device by label /dev/disk/by-label/UKI_ISO_INSTALL _, err = os.Stat(cnst.UkiLivecdPath) + var cdrom string // if found, mount it if err == nil { - err = syscall.Mount(cnst.UkiLivecdPath, s.path(cnst.UkiLivecdMountPoint), cnst.UkiDefaultcdromFsType, syscall.MS_RDONLY, "") - if err != nil { - internalUtils.Log.Err(err).Msg(fmt.Sprintf("Mounting %s", cnst.UkiLivecdPath)) - } + cdrom = cnst.UkiLivecdPath } else { - internalUtils.Log.Debug().Msg(fmt.Sprintf("No %s device found", cnst.UkiLivecdPath)) // Try to find if /dev/sr0 exists and mount it _, err = os.Stat(cnst.UkiDefaultcdrom) if err == nil { - err = syscall.Mount(cnst.UkiDefaultcdrom, s.path(cnst.UkiLivecdMountPoint), cnst.UkiDefaultcdromFsType, syscall.MS_RDONLY, "") - if err != nil { - internalUtils.Log.Err(err).Msg(fmt.Sprintf("Mounting %s", cnst.UkiDefaultcdrom)) - } - } else { - internalUtils.Log.Debug().Msg(fmt.Sprintf("No %s found", cnst.UkiDefaultcdrom)) + cdrom = cnst.UkiDefaultcdrom } } + // Mount it + if cdrom != "" { + err = syscall.Mount(cdrom, s.path(cnst.UkiLivecdMountPoint), cnst.UkiDefaultcdromFsType, syscall.MS_RDONLY, "") + if err != nil { + internalUtils.Log.Err(err).Msg(fmt.Sprintf("Mounting %s", cdrom)) + return err + } + internalUtils.Log.Debug().Msg(fmt.Sprintf("Mounted %s", cdrom)) + syscall.Sync() + + // This needs the loop module to be inserted in the kernel! + cmd := fmt.Sprintf("losetup --show -f %s", s.path(filepath.Join(cnst.UkiLivecdMountPoint, cnst.UkiIsoBootImage))) + out, err := internalUtils.CommandWithPath(cmd) + loop := strings.TrimSpace(out) + + if err != nil || loop == "" { + internalUtils.Log.Err(err).Str("out", out).Msg(cmd) + return err + } + syscall.Sync() + err = syscall.Mount(loop, s.path(cnst.UkiIsoBaseTree), cnst.UkiDefaultEfiimgFsType, syscall.MS_RDONLY, "") + if err != nil { + internalUtils.Log.Err(err).Msg(fmt.Sprintf("Mounting %s into %s", loop, s.path(cnst.UkiIsoBaseTree))) + return err + } + syscall.Sync() + return nil + } + return nil }))...) } diff --git a/pkg/mount/dag_uki_boot.go b/pkg/mount/dag_uki_boot.go index 546edae..9f4c6c9 100644 --- a/pkg/mount/dag_uki_boot.go +++ b/pkg/mount/dag_uki_boot.go @@ -24,11 +24,11 @@ func (s *State) RegisterUKI(g *herd.Graph) error { // Mount ESP partition under efi if it exists s.LogIfError(s.MountESPPartition(g, herd.WithDeps(cnst.OpSentinel, cnst.OpUkiUdev)), "mount ESP partition") - // Mount cdrom under /run/initramfs/livecd if it exists + // Mount cdrom under /run/initramfs/livecd and /run/rootfsbase for the efiboot.img contents s.LogIfError(s.MountLiveCd(g, herd.WithDeps(cnst.OpSentinel, cnst.OpUkiUdev)), "Mount LiveCD") // Run rootfs stage (doesnt this need to be run after mounting OEM??? - s.LogIfError(s.RootfsStageDagStep(g, herd.WithDeps(cnst.OpSentinel, cnst.OpUkiUdev)), "uki rootfs") + s.LogIfError(s.RootfsStageDagStep(g, herd.WithDeps(cnst.OpSentinel, cnst.OpUkiUdev), herd.WithWeakDeps(cnst.OpUkiMountLivecd)), "uki rootfs") // Remount root RO s.LogIfError(s.UKIRemountRootRODagStep(g), "remount root")