Skip to content

Commit

Permalink
core-initrd,snap-bootstrap: look at env to mount directly to /sysroot
Browse files Browse the repository at this point in the history
Previously we looked at the model and mounted base/rootfs directly if
it was Ubuntu 24+. Now, we check instead an environment variable that
is set if the initramfs is 24+.

This is done so now the kernels that contain the 24+ initramfs can be
booted in older Ubuntu releases with older bases. This situation is
not something we really support, as the systemd of the initramfs will
not match the one in the system, but it is something that could happen
while remodeling and it seems safer to allow this at least
temporarily.
  • Loading branch information
alfonsosanchezbeato committed Feb 19, 2025
1 parent cccee5f commit 5dfbe1e
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 12 deletions.
27 changes: 15 additions & 12 deletions cmd/snap-bootstrap/cmd_initramfs_mounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func (c *cmdInitramfsMounts) Execute([]string) error {

var (
osutilIsMounted = osutil.IsMounted
osGetenv = os.Getenv

snapTypeToMountDir = map[snap.Type]string{
snap.TypeBase: "base",
Expand Down Expand Up @@ -325,8 +326,8 @@ func doInstall(mst *initramfsMountsState, model *asserts.Model, sysSnaps map[sna
return err
}
var baseSnap *snap.Info
if is24plusSystem(model) {
// On UC24 the base is not mounted yet, peek into the file
if createSysrootMount() {
// On UC24+ the base is not mounted yet, peek into the file
baseSnap, err = readSnapInfoFromPath(sysSnaps[snap.TypeKernel].Path)
} else {
baseSnap, err = readSnapInfo(sysSnaps, snap.TypeBase)
Expand Down Expand Up @@ -1874,13 +1875,15 @@ func mountNonDataPartitionMatchingKernelDisk(dir, fallbacklabel string, opts *sy
return doSystemdMount(partSrc, dir, opts)
}

func is24plusSystem(model *asserts.Model) bool {
switch model.Base() {
case "core20", "core22", "core22-desktop":
return false
default:
return true
}
func createSysrootMount() bool {
// This env var is set by snap-initramfs-mounts.service for 24+ initramfs. We
// prefer this to checking the model so 24+ kernels can run with models using
// older bases. Although this situation is not really supported as the
// initramfs systemd bits would not match those in the base, we allow it as
// it has been something done in the past and updates could break those
// systems.
isCore24plus := osGetenv("CORE24_PLUS_INITRAMFS")
return isCore24plus == "1" || isCore24plus == "true"
}

func generateMountsCommonInstallRecoverStart(mst *initramfsMountsState) (model *asserts.Model, sysSnaps map[snap.Type]*seed.Snap, err error) {
Expand Down Expand Up @@ -1943,7 +1946,7 @@ func generateMountsCommonInstallRecoverStart(mst *initramfsMountsState) (model *

for _, essentialSnap := range essSnaps {
systemSnaps[essentialSnap.EssentialType] = essentialSnap
if essentialSnap.EssentialType == snap.TypeBase && is24plusSystem(model) {
if essentialSnap.EssentialType == snap.TypeBase && createSysrootMount() {
// Create unit to mount directly to /sysroot. We restrict
// this to UC24+ for the moment, until we backport necessary
// changes to the UC20/22 initramfs. Note that a transient
Expand Down Expand Up @@ -2441,7 +2444,7 @@ func generateMountsModeRun(mst *initramfsMountsState) error {
// code actually belongs in the bootloader implementation itself

typesToMount := typs
if is24plusSystem(model) {
if createSysrootMount() {
// Create unit for sysroot (mounts either base or rootfs). We
// restrict this to UC24+ for the moment, until we backport necessary
// changes to the UC20/22 initramfs. Note that a transient unit is
Expand Down Expand Up @@ -2517,7 +2520,7 @@ func generateMountsModeRun(mst *initramfsMountsState) error {
}
}

if is24plusSystem(model) {
if createSysrootMount() {
// Do a daemon reload so systemd knows about the new sysroot mount unit
// (populate-writable.service depends on sysroot.mount, we need to make
// sure systemd knows this unit before snap-initramfs-mounts.service
Expand Down
15 changes: 15 additions & 0 deletions cmd/snap-bootstrap/cmd_initramfs_mounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ func (s *baseInitramfsMountsSuite) SetUpTest(c *C) {

s.tmpDir = c.MkDir()

restore = main.MockOsGetenv(func(envVar string) string { return "" })
s.AddCleanup(restore)

// mock /run/mnt
dirs.SetRootDir(s.tmpDir)
restore = func() { dirs.SetRootDir("") }
Expand Down Expand Up @@ -811,6 +814,12 @@ func (s *initramfsMountsSuite) testInitramfsMountsInstallModeWithCompsHappy(c *C
default:
c.Skip("Unknown EFI arch")
}
defer main.MockOsGetenv(func(envVar string) string {
if envVar == "CORE24_PLUS_INITRAMFS" {
return "1"
}
return ""
})()

var systemctlArgs [][]string
systemctlNumCalls := 0
Expand Down Expand Up @@ -3607,6 +3616,12 @@ func (s *initramfsMountsSuite) TestInitramfsMountsRecoverModeHappy(c *C) {
return nil, nil
})
defer systemctlMock()
defer main.MockOsGetenv(func(envVar string) string {
if envVar == "CORE24_PLUS_INITRAMFS" {
return "1"
}
return ""
})()

// setup a bootloader for setting the bootenv after we are done
bloader := bootloadertest.Mock("mock", c.MkDir())
Expand Down
8 changes: 8 additions & 0 deletions cmd/snap-bootstrap/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,11 @@ func MockBuildInstallObserver(f func(model *asserts.Model, gadgetDir string, use
installBuildInstallObserver = old
}
}

func MockOsGetenv(mock func(string) string) (restore func()) {
old := osGetenv
osGetenv = mock
return func() {
osGetenv = old
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ After=dbus.socket
[Service]
Type=oneshot
RemainAfterExit=true
Environment="CORE24_PLUS_INITRAMFS=1"
ExecStart=/usr/lib/snapd/snap-bootstrap initramfs-mounts
StandardOutput=journal+console
StandardError=journal+console

0 comments on commit 5dfbe1e

Please sign in to comment.