Uki changes for iso/install (#156)

This commit is contained in:
Itxaka 2023-09-22 14:56:26 +02:00 committed by GitHub
parent a1710b8589
commit 5412c76ebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 187 additions and 166 deletions

View File

@ -11,6 +11,13 @@ func GetCloudInitPaths() []string {
return []string{"/system/oem", "/oem/", "/usr/local/cloud-config/"} return []string{"/system/oem", "/oem/", "/usr/local/cloud-config/"}
} }
// GenericKernelDrivers retusn 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"}
}
var ErrAlreadyMounted = errors.New("already mounted") var ErrAlreadyMounted = errors.New("already mounted")
const ( const (

View File

@ -17,7 +17,7 @@ func (s *State) RegisterLiveMedia(g *herd.Graph) error {
// Try to mount oem ONLY if we are on recovery squash // Try to mount oem ONLY if we are on recovery squash
// The check to see if its enabled its on the DAG step itself // The check to see if its enabled its on the DAG step itself
s.LogIfError(s.MountOemDagStep(g, cnst.OpWaitForSysroot), "oem mount") s.LogIfError(s.MountOemDagStep(g, herd.WithDeps(cnst.OpWaitForSysroot)), "oem mount")
s.LogIfError(s.RootfsStageDagStep(g, herd.WithDeps(cnst.OpSentinel, cnst.OpWaitForSysroot), herd.WithWeakDeps(cnst.OpMountOEM)), "rootfs stage") s.LogIfError(s.RootfsStageDagStep(g, herd.WithDeps(cnst.OpSentinel, cnst.OpWaitForSysroot), herd.WithWeakDeps(cnst.OpMountOEM)), "rootfs stage")
// Run initramfs inside the /sysroot chroot! // Run initramfs inside the /sysroot chroot!

View File

@ -29,7 +29,7 @@ func (s *State) RegisterNormalBoot(g *herd.Graph) error {
s.LogIfError(s.RunKcryptUpgrade(g, herd.WithDeps(cnst.OpLvmActivate)), "upgrade kcrypt partitions") s.LogIfError(s.RunKcryptUpgrade(g, herd.WithDeps(cnst.OpLvmActivate)), "upgrade kcrypt partitions")
// Mount COS_OEM (After root as it mounts under s.Rootdir/oem) // Mount COS_OEM (After root as it mounts under s.Rootdir/oem)
s.LogIfError(s.MountOemDagStep(g, cnst.OpMountRoot, cnst.OpLvmActivate), "oem mount") s.LogIfError(s.MountOemDagStep(g, herd.WithDeps(cnst.OpMountRoot, cnst.OpLvmActivate)), "oem mount")
// Run unlock. // Run unlock.
// Depends on mount root because it needs the kcrypt-discovery-challenger available under /sysroot // Depends on mount root because it needs the kcrypt-discovery-challenger available under /sysroot
@ -42,7 +42,7 @@ func (s *State) RegisterNormalBoot(g *herd.Graph) error {
// Populate state bind mounts, overlay mounts, custom-mounts from /run/cos/cos-layout.env // Populate state bind mounts, overlay mounts, custom-mounts from /run/cos/cos-layout.env
// Requires stage rootfs to have run, which usually creates the cos-layout.env file // Requires stage rootfs to have run, which usually creates the cos-layout.env file
s.LogIfError(s.LoadEnvLayoutDagStep(g, cnst.OpRootfsHook), "loading cos-layout.env") s.LogIfError(s.LoadEnvLayoutDagStep(g), "loading cos-layout.env")
// Mount base overlay under /run/overlay // Mount base overlay under /run/overlay
s.LogIfError(s.MountBaseOverlayDagStep(g), "base overlay mount") s.LogIfError(s.MountBaseOverlayDagStep(g), "base overlay mount")

View File

@ -111,158 +111,164 @@ func (s *State) InitramfsStageDagStep(g *herd.Graph, opts ...herd.OpOption) erro
} }
// LoadEnvLayoutDagStep will add the stage to load from cos-layout.env and fill the proper CustomMounts, OverlayDirs and BindMounts. // LoadEnvLayoutDagStep will add the stage to load from cos-layout.env and fill the proper CustomMounts, OverlayDirs and BindMounts.
func (s *State) LoadEnvLayoutDagStep(g *herd.Graph, deps ...string) error { func (s *State) LoadEnvLayoutDagStep(g *herd.Graph, opts ...herd.OpOption) error {
return g.Add(cnst.OpLoadConfig, return g.Add(cnst.OpLoadConfig,
herd.WithDeps(deps...), append(opts, herd.WithDeps(cnst.OpRootfsHook),
herd.WithCallback(func(ctx context.Context) error { herd.WithCallback(func(ctx context.Context) error {
if s.CustomMounts == nil { if s.CustomMounts == nil {
s.CustomMounts = map[string]string{} s.CustomMounts = map[string]string{}
}
env, err := internalUtils.ReadEnv("/run/cos/cos-layout.env")
if err != nil {
internalUtils.Log.Err(err).Msg("Reading env")
return err
}
// populate from env here
s.OverlayDirs = internalUtils.CleanupSlice(strings.Split(env["RW_PATHS"], " "))
// Append default RW_Paths if list is empty, otherwise we won't boot properly
if len(s.OverlayDirs) == 0 {
s.OverlayDirs = cnst.DefaultRWPaths()
}
// Remove any duplicates
s.OverlayDirs = internalUtils.UniqueSlice(internalUtils.CleanupSlice(s.OverlayDirs))
s.BindMounts = strings.Split(env["PERSISTENT_STATE_PATHS"], " ")
// Add custom bind mounts
s.BindMounts = append(s.BindMounts, strings.Split(env["CUSTOM_BIND_MOUNTS"], " ")...)
// Remove any duplicates
s.BindMounts = internalUtils.UniqueSlice(internalUtils.CleanupSlice(s.BindMounts))
// Load Overlay config
overlayConfig := env["OVERLAY"]
if overlayConfig != "" {
s.OverlayBase = overlayConfig
}
s.StateDir = env["PERSISTENT_STATE_TARGET"]
if s.StateDir == "" {
s.StateDir = cnst.PersistentStateTarget
}
addLine := func(d string) {
dat := strings.Split(d, ":")
if len(dat) == 2 {
disk := dat[0]
path := dat[1]
s.CustomMounts[disk] = path
} }
}
// Parse custom mounts also from cmdline (rd.cos.mount=)
// Parse custom mounts also from cmdline (rd.immucore.mount=)
// Parse custom mounts also from env file (VOLUMES)
for _, v := range append(append(internalUtils.ReadCMDLineArg("rd.cos.mount="), internalUtils.ReadCMDLineArg("rd.immucore.mount=")...), strings.Split(env["VOLUMES"], " ")...) { env, err := internalUtils.ReadEnv("/run/cos/cos-layout.env")
addLine(internalUtils.ParseMount(v)) if err != nil {
} internalUtils.Log.Err(err).Msg("Reading env")
return err
}
// populate from env here
s.OverlayDirs = internalUtils.CleanupSlice(strings.Split(env["RW_PATHS"], " "))
// Append default RW_Paths if list is empty, otherwise we won't boot properly
if len(s.OverlayDirs) == 0 {
s.OverlayDirs = cnst.DefaultRWPaths()
}
return nil // Remove any duplicates
})) s.OverlayDirs = internalUtils.UniqueSlice(internalUtils.CleanupSlice(s.OverlayDirs))
s.BindMounts = strings.Split(env["PERSISTENT_STATE_PATHS"], " ")
// Add custom bind mounts
s.BindMounts = append(s.BindMounts, strings.Split(env["CUSTOM_BIND_MOUNTS"], " ")...)
// Remove any duplicates
s.BindMounts = internalUtils.UniqueSlice(internalUtils.CleanupSlice(s.BindMounts))
// Load Overlay config
overlayConfig := env["OVERLAY"]
if overlayConfig != "" {
s.OverlayBase = overlayConfig
}
s.StateDir = env["PERSISTENT_STATE_TARGET"]
if s.StateDir == "" {
s.StateDir = cnst.PersistentStateTarget
}
addLine := func(d string) {
dat := strings.Split(d, ":")
if len(dat) == 2 {
disk := dat[0]
path := dat[1]
s.CustomMounts[disk] = path
}
}
// Parse custom mounts also from cmdline (rd.cos.mount=)
// Parse custom mounts also from cmdline (rd.immucore.mount=)
// Parse custom mounts also from env file (VOLUMES)
for _, v := range append(append(internalUtils.ReadCMDLineArg("rd.cos.mount="), internalUtils.ReadCMDLineArg("rd.immucore.mount=")...), strings.Split(env["VOLUMES"], " ")...) {
addLine(internalUtils.ParseMount(v))
}
return nil
}))...)
} }
// MountOemDagStep will add mounting COS_OEM partition under s.Rootdir + /oem . // MountOemDagStep will add mounting COS_OEM partition under s.Rootdir + /oem .
func (s *State) MountOemDagStep(g *herd.Graph, deps ...string) error { func (s *State) MountOemDagStep(g *herd.Graph, opts ...herd.OpOption) error {
return g.Add(cnst.OpMountOEM, return g.Add(cnst.OpMountOEM,
herd.WithDeps(deps...), append(opts,
herd.EnableIf(func() bool { herd.EnableIf(func() bool {
runtime, _ := state.NewRuntime() runtime, _ := state.NewRuntime()
switch runtime.BootState { switch runtime.BootState {
// Don't run this on LiveCD/Netboot // Don't run this on LiveCD/Netboot
case state.LiveCD: case state.LiveCD:
return false return false
default: default:
return internalUtils.GetOemLabel() != "" return internalUtils.GetOemLabel() != ""
} }
}), }),
herd.WithCallback( herd.WithCallback(func(ctx context.Context) error {
s.MountOP( if internalUtils.IsUKI() {
fmt.Sprintf("/dev/disk/by-label/%s", internalUtils.GetOemLabel()), _, err := os.Stat("/dev/disk/by-label/UKI_ISO_INSTALL")
s.path("/oem"), if err == nil {
internalUtils.DiskFSType(fmt.Sprintf("/dev/disk/by-label/%s", internalUtils.GetOemLabel())), // Do nothing during uki install
[]string{ return nil
"rw", }
"suid", }
"dev", op := s.MountOP(
"exec", fmt.Sprintf("/dev/disk/by-label/%s", internalUtils.GetOemLabel()),
"async", s.path("/oem"),
}, time.Duration(internalUtils.GetOemTimeout())*time.Second), internalUtils.DiskFSType(fmt.Sprintf("/dev/disk/by-label/%s", internalUtils.GetOemLabel())),
), []string{
) "rw",
"suid",
"dev",
"exec",
"async",
}, time.Duration(internalUtils.GetOemTimeout())*time.Second)
return op(ctx)
}))...)
} }
// MountBaseOverlayDagStep will add mounting /run/overlay as an overlay dir // MountBaseOverlayDagStep will add mounting /run/overlay as an overlay dir
// Requires the config-load step because some parameters can come from there. // Requires the config-load step because some parameters can come from there.
func (s *State) MountBaseOverlayDagStep(g *herd.Graph) error { func (s *State) MountBaseOverlayDagStep(g *herd.Graph, opts ...herd.OpOption) error {
return g.Add(cnst.OpMountBaseOverlay, return g.Add(cnst.OpMountBaseOverlay,
herd.WithDeps(cnst.OpLoadConfig), append(opts, herd.WithDeps(cnst.OpLoadConfig),
herd.WithCallback( herd.WithCallback(
func(ctx context.Context) error { func(ctx context.Context) error {
op, err := baseOverlay(Overlay{ op, err := baseOverlay(Overlay{
Base: "/run/overlay", Base: "/run/overlay",
BackingBase: s.OverlayBase, BackingBase: s.OverlayBase,
}) })
if err != nil { if err != nil {
return err return err
} }
err2 := op.run() err2 := op.run()
// No error, add fstab // No error, add fstab
if err2 == nil { if err2 == nil {
s.fstabs = append(s.fstabs, &op.FstabEntry) s.fstabs = append(s.fstabs, &op.FstabEntry)
return nil return nil
} }
// Error but its already mounted error, dont add fstab but dont return error // Error but its already mounted error, dont add fstab but dont return error
if err2 != nil && errors.Is(err2, cnst.ErrAlreadyMounted) { if err2 != nil && errors.Is(err2, cnst.ErrAlreadyMounted) {
return nil return nil
} }
return err2 return err2
}, },
), ),
) )...)
} }
// MountCustomOverlayDagStep will add mounting s.OverlayDirs under /run/overlay . // MountCustomOverlayDagStep will add mounting s.OverlayDirs under /run/overlay .
func (s *State) MountCustomOverlayDagStep(g *herd.Graph) error { func (s *State) MountCustomOverlayDagStep(g *herd.Graph, opts ...herd.OpOption) error {
return g.Add(cnst.OpOverlayMount, return g.Add(cnst.OpOverlayMount,
herd.WithDeps(cnst.OpLoadConfig, cnst.OpMountBaseOverlay), append(opts, herd.WithDeps(cnst.OpLoadConfig, cnst.OpMountBaseOverlay),
herd.WithCallback( herd.WithCallback(
func(ctx context.Context) error { func(ctx context.Context) error {
var multierr *multierror.Error var multierr *multierror.Error
internalUtils.Log.Debug().Strs("dirs", s.OverlayDirs).Msg("Mounting overlays") internalUtils.Log.Debug().Strs("dirs", s.OverlayDirs).Msg("Mounting overlays")
for _, p := range s.OverlayDirs { for _, p := range s.OverlayDirs {
internalUtils.Log.Debug().Str("what", p).Msg("Overlay mount start") internalUtils.Log.Debug().Str("what", p).Msg("Overlay mount start")
op := mountWithBaseOverlay(p, s.Rootdir, "/run/overlay") op := mountWithBaseOverlay(p, s.Rootdir, "/run/overlay")
err := op.run() err := op.run()
// Append to errors only if it's not an already mounted error // Append to errors only if it's not an already mounted error
if err != nil && !errors.Is(err, cnst.ErrAlreadyMounted) { if err != nil && !errors.Is(err, cnst.ErrAlreadyMounted) {
internalUtils.Log.Err(err).Msg("overlay mount") internalUtils.Log.Err(err).Msg("overlay mount")
multierr = multierror.Append(multierr, err) multierr = multierror.Append(multierr, err)
continue continue
}
s.fstabs = append(s.fstabs, &op.FstabEntry)
internalUtils.Log.Debug().Str("what", p).Msg("Overlay mount done")
} }
s.fstabs = append(s.fstabs, &op.FstabEntry) return multierr.ErrorOrNil()
internalUtils.Log.Debug().Str("what", p).Msg("Overlay mount done") },
} ),
return multierr.ErrorOrNil() )...)
},
),
)
} }
// MountCustomMountsDagStep will add mounting s.CustomMounts . // MountCustomMountsDagStep will add mounting s.CustomMounts .
func (s *State) MountCustomMountsDagStep(g *herd.Graph) error { func (s *State) MountCustomMountsDagStep(g *herd.Graph, opts ...herd.OpOption) error {
return g.Add(cnst.OpCustomMounts, return g.Add(cnst.OpCustomMounts, append(opts, herd.WithDeps(cnst.OpLoadConfig),
herd.WithDeps(cnst.OpLoadConfig),
herd.WithCallback(func(ctx context.Context) error { herd.WithCallback(func(ctx context.Context) error {
var err *multierror.Error var err *multierror.Error
internalUtils.Log.Debug().Interface("mounts", s.CustomMounts).Msg("Mounting custom mounts") internalUtils.Log.Debug().Interface("mounts", s.CustomMounts).Msg("Mounting custom mounts")
@ -295,39 +301,39 @@ func (s *State) MountCustomMountsDagStep(g *herd.Graph) error {
return err.ErrorOrNil() return err.ErrorOrNil()
}), }),
) )...)
} }
// MountCustomBindsDagStep will add mounting s.BindMounts // MountCustomBindsDagStep will add mounting s.BindMounts
// mount state is defined over a custom mount (/usr/local/.state for instance, needs to be mounted over a device). // mount state is defined over a custom mount (/usr/local/.state for instance, needs to be mounted over a device).
func (s *State) MountCustomBindsDagStep(g *herd.Graph) error { func (s *State) MountCustomBindsDagStep(g *herd.Graph, opts ...herd.OpOption) error {
return g.Add(cnst.OpMountBind, return g.Add(cnst.OpMountBind,
herd.WithDeps(cnst.OpOverlayMount, cnst.OpCustomMounts, cnst.OpLoadConfig), append(opts, herd.WithDeps(cnst.OpOverlayMount, cnst.OpCustomMounts, cnst.OpLoadConfig),
herd.WithCallback( herd.WithCallback(
func(ctx context.Context) error { func(ctx context.Context) error {
var err *multierror.Error var err *multierror.Error
internalUtils.Log.Debug().Strs("mounts", s.BindMounts).Msg("Mounting binds") internalUtils.Log.Debug().Strs("mounts", s.BindMounts).Msg("Mounting binds")
for _, p := range s.SortedBindMounts() { for _, p := range s.SortedBindMounts() {
internalUtils.Log.Debug().Str("what", p).Msg("Bind mount start") internalUtils.Log.Debug().Str("what", p).Msg("Bind mount start")
op := mountBind(p, s.Rootdir, s.StateDir) op := mountBind(p, s.Rootdir, s.StateDir)
err2 := op.run() err2 := op.run()
if err2 == nil { if err2 == nil {
// Only append to fstabs if there was no error, otherwise we will try to mount it after switch_root // Only append to fstabs if there was no error, otherwise we will try to mount it after switch_root
s.fstabs = append(s.fstabs, &op.FstabEntry) s.fstabs = append(s.fstabs, &op.FstabEntry)
}
// Append to errors only if it's not an already mounted error
if err2 != nil && !errors.Is(err2, cnst.ErrAlreadyMounted) {
internalUtils.Log.Err(err2).Send()
err = multierror.Append(err, err2)
}
internalUtils.Log.Debug().Str("what", p).Msg("Bind mount end")
} }
// Append to errors only if it's not an already mounted error internalUtils.Log.Warn().Err(err.ErrorOrNil()).Send()
if err2 != nil && !errors.Is(err2, cnst.ErrAlreadyMounted) { return err.ErrorOrNil()
internalUtils.Log.Err(err2).Send() },
err = multierror.Append(err, err2) ),
} )...)
internalUtils.Log.Debug().Str("what", p).Msg("Bind mount end")
}
internalUtils.Log.Warn().Err(err.ErrorOrNil()).Send()
return err.ErrorOrNil()
},
),
)
} }
// WriteFstabDagStep will add writing the final fstab file with all the mounts // WriteFstabDagStep will add writing the final fstab file with all the mounts
@ -449,7 +455,7 @@ func (s *State) UKIMountBaseSystem(g *herd.Graph) error {
// Drops to emergency if not able to. Panic if it cant even launch emergency. // Drops to emergency if not able to. Panic if it cant even launch emergency.
func (s *State) UKIBootInitDagStep(g *herd.Graph) error { func (s *State) UKIBootInitDagStep(g *herd.Graph) error {
return g.Add(cnst.OpUkiInit, return g.Add(cnst.OpUkiInit,
herd.WithDeps(), herd.WeakDeps,
herd.WithWeakDeps(cnst.OpRemountRootRO, cnst.OpRootfsHook, cnst.OpInitramfsHook, cnst.OpWriteFstab), herd.WithWeakDeps(cnst.OpRemountRootRO, cnst.OpRootfsHook, cnst.OpInitramfsHook, cnst.OpWriteFstab),
herd.WithCallback(func(ctx context.Context) error { herd.WithCallback(func(ctx context.Context) error {
// Print dag before exit, otherwise its never printed as we never exit the program // Print dag before exit, otherwise its never printed as we never exit the program
@ -533,6 +539,7 @@ func (s *State) LoadKernelModules(g *herd.Graph) error {
if err != nil { if err != nil {
internalUtils.Log.Err(err).Msg("Detecting needed modules") internalUtils.Log.Err(err).Msg("Detecting needed modules")
} }
drivers = append(drivers, cnst.GenericKernelDrivers()...)
internalUtils.Log.Debug().Strs("drivers", drivers).Msg("Detecting needed modules") internalUtils.Log.Debug().Strs("drivers", drivers).Msg("Detecting needed modules")
for _, driver := range drivers { for _, driver := range drivers {
cmd := fmt.Sprintf("modprobe %s", driver) cmd := fmt.Sprintf("modprobe %s", driver)

View File

@ -14,6 +14,8 @@ func (s *State) RegisterUKI(g *herd.Graph) error {
s.LogIfError(s.WriteSentinelDagStep(g, cnst.OpUkiBaseMounts), "sentinel") s.LogIfError(s.WriteSentinelDagStep(g, cnst.OpUkiBaseMounts), "sentinel")
// Load needed kernel modules // Load needed kernel modules
// TODO: This seems to be wrong as it leans on the udev to infer the modules, but at this point we dont have udev
// So we dont get all the proper modules needed!
s.LogIfError(s.LoadKernelModules(g), "kernel modules") s.LogIfError(s.LoadKernelModules(g), "kernel modules")
// Udev for devices discovery // Udev for devices discovery
@ -25,25 +27,27 @@ func (s *State) RegisterUKI(g *herd.Graph) error {
// Remount root RO // Remount root RO
s.LogIfError(s.UKIRemountRootRODagStep(g), "remount root") s.LogIfError(s.UKIRemountRootRODagStep(g), "remount root")
s.LogIfError(s.MountOemDagStep(g, herd.WithDeps(cnst.OpRemountRootRO), herd.WeakDeps), "oem mount")
// Populate state bind mounts, overlay mounts, custom-mounts from /run/cos/cos-layout.env // Populate state bind mounts, overlay mounts, custom-mounts from /run/cos/cos-layout.env
// Requires stage rootfs to have run, which usually creates the cos-layout.env file // Requires stage rootfs to have run, which usually creates the cos-layout.env file
s.LogIfError(s.LoadEnvLayoutDagStep(g, cnst.OpRootfsHook), "loading cos-layout.env") s.LogIfError(s.LoadEnvLayoutDagStep(g), "loading cos-layout.env")
// Mount base overlay under /run/overlay // Mount base overlay under /run/overlay
s.LogIfError(s.MountBaseOverlayDagStep(g), "base overlay") s.LogIfError(s.MountBaseOverlayDagStep(g), "base overlay")
// Mount custom overlays loaded from the /run/cos/cos-layout.env file // Mount custom overlays loaded from the /run/cos/cos-layout.env file
s.LogIfError(s.MountCustomOverlayDagStep(g), "custom overlays mount") s.LogIfError(s.MountCustomOverlayDagStep(g, herd.WeakDeps), "custom overlays mount")
// Mount custom mounts loaded from the /run/cos/cos-layout.env file // Mount custom mounts loaded from the /run/cos/cos-layout.env file
s.LogIfError(s.MountCustomMountsDagStep(g), "custom mounts mount") s.LogIfError(s.MountCustomMountsDagStep(g, herd.WeakDeps), "custom mounts mount")
// Mount custom binds loaded from the /run/cos/cos-layout.env file // Mount custom binds loaded from the /run/cos/cos-layout.env file
// Depends on mount binds as that usually mounts COS_PERSISTENT // Depends on mount binds as that usually mounts COS_PERSISTENT
s.LogIfError(s.MountCustomBindsDagStep(g), "custom binds mount") s.LogIfError(s.MountCustomBindsDagStep(g, herd.WeakDeps), "custom binds mount")
// run initramfs stage // run initramfs stage
s.LogIfError(s.InitramfsStageDagStep(g, herd.WithDeps(cnst.OpMountBind)), "uki initramfs") s.LogIfError(s.InitramfsStageDagStep(g, herd.WeakDeps, herd.WithDeps(cnst.OpMountBind)), "uki initramfs")
s.LogIfError(g.Add(cnst.OpWriteFstab, s.LogIfError(g.Add(cnst.OpWriteFstab,
herd.WithDeps(cnst.OpLoadConfig, cnst.OpCustomMounts, cnst.OpMountBind, cnst.OpOverlayMount), herd.WithDeps(cnst.OpLoadConfig, cnst.OpCustomMounts, cnst.OpMountBind, cnst.OpOverlayMount),

View File

@ -37,7 +37,10 @@ func (m mountOperation) run() error {
l.Warn().Err(err).Msg("checking mount status") l.Warn().Err(err).Msg("checking mount status")
return err return err
} }
if mounted {
// In UKI mode we need to remount things from ephemeral to persistent if persistent exists so we need to skip the check for mount
// only in UKI (/home basically)
if mounted && !internalUtils.IsUKI() {
l.Debug().Msg("Already mounted") l.Debug().Msg("Already mounted")
return constants.ErrAlreadyMounted return constants.ErrAlreadyMounted
} }