🌱 activate LVM volumes at the start (#113)

This commit is contained in:
Itxaka 2023-04-19 16:23:51 +02:00 committed by GitHub
parent 6bf656cd21
commit f1c3aad0ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 46 additions and 4 deletions

View File

@ -7,7 +7,7 @@ check() {
# called by dracut
depends() {
echo rootfs-block dm fs-lib
echo rootfs-block dm fs-lib lvm
return 0
}
@ -27,9 +27,11 @@ install() {
inst_multiple kcrypt partprobe sync udevadm parted mkfs.ext2 mkfs.ext3 mkfs.ext4 mkfs.vfat mkfs.fat blkid e2fsck resize2fs mount umount sgdisk rsync
# missing mkfs.xfs xfs_growfs in image?
inst_script "${moddir}/generator.sh" "${systemdutildir}/system-generators/immucore-generator"
# SERVICES FOR SYSTEMD-BASED SYSTEMS
inst_simple "${moddir}/immucore.service" "${systemdsystemunitdir}/immucore.service"
mkdir -p "${initdir}/${systemdsystemunitdir}/initrd.target.requires"
ln_r "../immucore.service" "${systemdsystemunitdir}/initrd.target.requires/immucore.service"
# END SYSTEMD SERVICES
dracut_need_initqueue
}

View File

@ -34,6 +34,7 @@ const (
OpUkiBaseMounts = "uki-base-mounts"
OpUkiKernelModules = "uki-kernel-modules"
OpWaitForSysroot = "wait-for-sysroot"
OpLvmActivate = "lvm-activation"
PersistentStateTarget = "/usr/local/.state"
LogDir = "/run/immucore"
LinuxFs = "ext4"

View File

@ -262,3 +262,18 @@ func GetOemLabel() string {
}
return runtime.OEM.FilesystemLabel
}
func ActivateLVM() error {
// Remove the /etc/lvm/lvm.conf file
// Otherwise, it has a default locking setting which activates the volumes on readonly
// This would be the same as passing rd.lvm.conf=0 in cmdline but rather do it here than add an extra option to cmdline
_, _ = CommandWithPath("rm /etc/lvm/lvm.conf")
out, err := CommandWithPath("lvm vgchange --refresh --sysinit")
Log.Debug().Str("out", out).Msg("vgchange")
if err != nil {
Log.Err(err).Msg("vgchange")
}
_, _ = CommandWithPath("udevadm --trigger")
return err
}

View File

@ -12,7 +12,8 @@ import (
func (s *State) RegisterNormalBoot(g *herd.Graph) error {
var err error
// TODO: add hooks, fstab (might have missed some), systemd compat, fsck
s.LogIfError(s.LVMActivation(g), "lvm activation")
// Maybe LogIfErrorAndPanic ? If no sentinel, a lot of config files are not going to run
if err = s.LogIfErrorAndReturn(s.WriteSentinelDagStep(g), "write sentinel"); err != nil {
return err
@ -24,7 +25,7 @@ func (s *State) RegisterNormalBoot(g *herd.Graph) error {
s.LogIfError(s.MountRootDagStep(g), "running mount root stage")
// Mount COS_OEM (After root as it mounts under s.Rootdir/oem)
s.LogIfError(s.MountOemDagStep(g, cnst.OpMountRoot), "oem mount")
s.LogIfError(s.MountOemDagStep(g, cnst.OpMountRoot, cnst.OpLvmActivate), "oem mount")
// Run yip stage rootfs. Requires root+oem+sentinel to be mounted
s.LogIfError(s.RootfsStageDagStep(g, herd.WithDeps(cnst.OpMountRoot, cnst.OpMountOEM, cnst.OpSentinel)), "running rootfs stage")

View File

@ -586,3 +586,10 @@ func (s *State) WaitForSysrootDagStep(g *herd.Graph) error {
}
}))
}
// LvmActivation will try to activate lvm volumes/groups on the system.
func (s *State) LVMActivation(g *herd.Graph) error {
return g.Add(cnst.OpLvmActivate, herd.WithCallback(func(ctx context.Context) error {
return internalUtils.ActivateLVM()
}))
}

View File

@ -121,6 +121,7 @@ func (s *State) RunStageOp(stage string) func(context.Context) error {
// MountOP creates and executes a mount operation.
func (s *State) MountOP(what, where, t string, options []string, timeout time.Duration) func(context.Context) error {
l := internalUtils.Log.With().Str("what", what).Str("where", where).Str("type", t).Strs("options", options).Logger().Level(zerolog.InfoLevel)
// Not sure why this defaults to debuglevel when creating a sublogger, so make sure we set it properly
debug := len(internalUtils.ReadCMDLineArg("rd.immucore.debug")) > 0
@ -133,6 +134,12 @@ func (s *State) MountOP(what, where, t string, options []string, timeout time.Du
for {
select {
default:
// check fs type just-in-time before running the OP
fsType := internalUtils.DiskFSType(what)
// If not empty and it does not match
if fsType != "" && t != fsType {
t = fsType
}
err := internalUtils.CreateIfNotExists(where)
if err != nil {
l.Err(err).Msg("Creating dir")

View File

@ -86,7 +86,7 @@ func checkLiveCDDag(dag [][]herd.GraphEntry, actualDag string) {
func checkDag(dag [][]herd.GraphEntry, actualDag string) {
Expect(len(dag)).To(Equal(12), actualDag)
Expect(len(dag[0])).To(Equal(1), actualDag)
Expect(len(dag[1])).To(Equal(3), actualDag)
Expect(len(dag[1])).To(Equal(4), actualDag)
Expect(len(dag[2])).To(Equal(1), actualDag)
Expect(len(dag[3])).To(Equal(1), actualDag)
Expect(len(dag[4])).To(Equal(1), actualDag)
@ -103,16 +103,25 @@ func checkDag(dag [][]herd.GraphEntry, actualDag string) {
Equal(cnst.OpMountTmpfs),
Equal(cnst.OpSentinel),
Equal(cnst.OpMountState),
Equal(cnst.OpLvmActivate),
), actualDag)
Expect(dag[1][1].Name).To(Or(
Equal(cnst.OpMountTmpfs),
Equal(cnst.OpSentinel),
Equal(cnst.OpMountState),
Equal(cnst.OpLvmActivate),
), actualDag)
Expect(dag[1][2].Name).To(Or(
Equal(cnst.OpMountTmpfs),
Equal(cnst.OpSentinel),
Equal(cnst.OpMountState),
Equal(cnst.OpLvmActivate),
), actualDag)
Expect(dag[1][3].Name).To(Or(
Equal(cnst.OpMountTmpfs),
Equal(cnst.OpSentinel),
Equal(cnst.OpMountState),
Equal(cnst.OpLvmActivate),
), actualDag)
Expect(dag[2][0].Name).To(Equal(cnst.OpDiscoverState), actualDag)
Expect(dag[3][0].Name).To(Equal(cnst.OpMountRoot), actualDag)