mirror of
https://github.com/kairos-io/immucore.git
synced 2025-09-26 06:57:41 +00:00
Mount ESP under /efi if possible + identify EFI run source (#158)
This commit is contained in:
@@ -233,3 +233,24 @@ func GetHostProcCmdline() string {
|
||||
}
|
||||
return proc
|
||||
}
|
||||
|
||||
// EfiBootFromInstall will try to check the /sys/firmware/efi/LoaderDevicePartUUID-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
|
||||
// systemd vendor Id is 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f and will never change
|
||||
// LoaderDevicePartUUID contains the partition UUID of the EFI System Partition the boot loader was run from. Set by the boot loader.
|
||||
// This will return true if we are running from a DISK device, which sets the efivar
|
||||
// This wil return false when running from a volatile media, like CD or netboot as it cannot infer where it was booted from
|
||||
// Useful to check if we are on install phase or not
|
||||
// This efi var is VOLATILE so once we reboot is GONE. No way of keeping it across reboots, its set by the bootloader.
|
||||
func EfiBootFromInstall() bool {
|
||||
file := "/sys/firmware/efi/efivars/LoaderDevicePartUUID-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
|
||||
readFile, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
Log.Debug().Err(err).Msg("Error reading LoaderDevicePartUUID file")
|
||||
return false
|
||||
}
|
||||
if len(readFile) == 0 || string(readFile) == "" {
|
||||
Log.Debug().Str("file", string(readFile)).Msg("Error reading LoaderDevicePartUUID file")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package mount
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -384,9 +385,19 @@ func (s *State) WriteSentinelDagStep(g *herd.Graph, deps ...string) error {
|
||||
// Lets add a uki sentinel as well!
|
||||
cmdline, _ := os.ReadFile(internalUtils.GetHostProcCmdline())
|
||||
if strings.Contains(string(cmdline), "rd.immucore.uki") {
|
||||
err = os.WriteFile("/run/cos/uki_mode", []byte("1"), os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
// sentinel for uki mode
|
||||
if internalUtils.EfiBootFromInstall() {
|
||||
internalUtils.Log.Info().Str("to", "uki_boot_mode").Msg("Setting sentinel file")
|
||||
err = os.WriteFile("/run/cos/uki_boot_mode", []byte("1"), os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
internalUtils.Log.Info().Str("to", "uki_install_mode").Msg("Setting sentinel file")
|
||||
err := os.WriteFile("/run/cos/uki_install_mode", []byte("1"), os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,6 +441,13 @@ func (s *State) UKIMountBaseSystem(g *herd.Graph) error {
|
||||
syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"/sys/firmware/efi/efivars",
|
||||
"efivarfs",
|
||||
"efivarfs",
|
||||
syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_NOEXEC | syscall.MS_RELATIME,
|
||||
"",
|
||||
},
|
||||
}
|
||||
for _, m := range mounts {
|
||||
e := os.MkdirAll(m.where, 0755)
|
||||
@@ -545,7 +563,7 @@ func (s *State) LoadKernelModules(g *herd.Graph) error {
|
||||
cmd := fmt.Sprintf("modprobe %s", driver)
|
||||
out, err := internalUtils.CommandWithPath(cmd)
|
||||
if err != nil {
|
||||
internalUtils.Log.Err(err).Str("out", out).Msg("modprobe")
|
||||
internalUtils.Log.Debug().Err(err).Str("out", out).Msg("modprobe")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -608,3 +626,59 @@ func (s *State) RunKcryptUpgrade(g *herd.Graph, opts ...herd.OpOption) error {
|
||||
return internalUtils.UpgradeKcryptPartitions()
|
||||
}))...)
|
||||
}
|
||||
|
||||
type LsblkOutput struct {
|
||||
Blockdevices []struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Parttype interface{} `json:"parttype,omitempty"`
|
||||
Children []struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Parttype string `json:"parttype,omitempty"`
|
||||
} `json:"children,omitempty"`
|
||||
} `json:"blockdevices,omitempty"`
|
||||
}
|
||||
|
||||
// MountESPPartition tries to mount the ESP into /efi
|
||||
// Doesnt matter if it fails, its just for niceness.
|
||||
func (s *State) MountESPPartition(g *herd.Graph, opts ...herd.OpOption) error {
|
||||
return g.Add("mount-esp", append(opts, herd.WithCallback(func(ctx context.Context) error {
|
||||
if !internalUtils.EfiBootFromInstall() {
|
||||
internalUtils.Log.Debug().Msg("Not mounting ESP as we think we are booting from removable media")
|
||||
return nil
|
||||
}
|
||||
cmd := "lsblk -J -o NAME,PARTTYPE"
|
||||
out, err := internalUtils.CommandWithPath(cmd)
|
||||
internalUtils.Log.Debug().Str("out", out).Str("cmd", cmd).Msg("ESP")
|
||||
if err != nil {
|
||||
internalUtils.Log.Err(err).Msg("ESP")
|
||||
return nil
|
||||
}
|
||||
|
||||
lsblk := &LsblkOutput{}
|
||||
err = json.Unmarshal([]byte(out), lsblk)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, bd := range lsblk.Blockdevices {
|
||||
for _, cd := range bd.Children {
|
||||
if strings.TrimSpace(cd.Parttype) == "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" {
|
||||
// This is the ESP device
|
||||
device := filepath.Join("/dev", cd.Name)
|
||||
if !internalUtils.IsMounted(device) {
|
||||
op := s.MountOP(
|
||||
device,
|
||||
s.path("/efi"),
|
||||
"vfat",
|
||||
[]string{
|
||||
"ro",
|
||||
}, 5*time.Second)
|
||||
return op(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}))...)
|
||||
}
|
||||
|
@@ -21,6 +21,9 @@ func (s *State) RegisterUKI(g *herd.Graph) error {
|
||||
// Udev for devices discovery
|
||||
s.LogIfError(s.UKIUdevDaemon(g), "udev")
|
||||
|
||||
// Mount ESP partition under efi if it exists
|
||||
s.LogIfError(s.MountESPPartition(g, herd.WithDeps(cnst.OpSentinel, cnst.OpUkiUdev)), "mount ESP partition")
|
||||
|
||||
// Run rootfs stage
|
||||
s.LogIfError(s.RootfsStageDagStep(g, herd.WithDeps(cnst.OpSentinel, cnst.OpUkiUdev)), "uki rootfs")
|
||||
|
||||
|
Reference in New Issue
Block a user