mirror of
https://github.com/kairos-io/immucore.git
synced 2025-09-26 15:06:31 +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
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@@ -384,9 +385,19 @@ func (s *State) WriteSentinelDagStep(g *herd.Graph, deps ...string) error {
|
|||||||
// Lets add a uki sentinel as well!
|
// Lets add a uki sentinel as well!
|
||||||
cmdline, _ := os.ReadFile(internalUtils.GetHostProcCmdline())
|
cmdline, _ := os.ReadFile(internalUtils.GetHostProcCmdline())
|
||||||
if strings.Contains(string(cmdline), "rd.immucore.uki") {
|
if strings.Contains(string(cmdline), "rd.immucore.uki") {
|
||||||
err = os.WriteFile("/run/cos/uki_mode", []byte("1"), os.ModePerm)
|
// sentinel for uki mode
|
||||||
if err != nil {
|
if internalUtils.EfiBootFromInstall() {
|
||||||
return err
|
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,
|
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 {
|
for _, m := range mounts {
|
||||||
e := os.MkdirAll(m.where, 0755)
|
e := os.MkdirAll(m.where, 0755)
|
||||||
@@ -545,7 +563,7 @@ func (s *State) LoadKernelModules(g *herd.Graph) error {
|
|||||||
cmd := fmt.Sprintf("modprobe %s", driver)
|
cmd := fmt.Sprintf("modprobe %s", driver)
|
||||||
out, err := internalUtils.CommandWithPath(cmd)
|
out, err := internalUtils.CommandWithPath(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
internalUtils.Log.Err(err).Str("out", out).Msg("modprobe")
|
internalUtils.Log.Debug().Err(err).Str("out", out).Msg("modprobe")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -608,3 +626,59 @@ func (s *State) RunKcryptUpgrade(g *herd.Graph, opts ...herd.OpOption) error {
|
|||||||
return internalUtils.UpgradeKcryptPartitions()
|
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
|
// Udev for devices discovery
|
||||||
s.LogIfError(s.UKIUdevDaemon(g), "udev")
|
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
|
// Run rootfs stage
|
||||||
s.LogIfError(s.RootfsStageDagStep(g, herd.WithDeps(cnst.OpSentinel, cnst.OpUkiUdev)), "uki rootfs")
|
s.LogIfError(s.RootfsStageDagStep(g, herd.WithDeps(cnst.OpSentinel, cnst.OpUkiUdev)), "uki rootfs")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user