Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/snap-bootstrap: mount base directly on /sysroot #14537

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 102 additions & 9 deletions cmd/snap-bootstrap/cmd_initramfs_mounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"github.com/snapcore/snapd/osutil/disks"
"github.com/snapcore/snapd/osutil/kcmdline"
"github.com/snapcore/snapd/snapdtool"
"github.com/snapcore/snapd/systemd"

// to set sysconfig.ApplyFilesystemOnlyDefaultsImpl
_ "github.com/snapcore/snapd/overlord/configstate/configcore"
Expand All @@ -58,6 +59,7 @@
"github.com/snapcore/snapd/snap"
"github.com/snapcore/snapd/snap/naming"
"github.com/snapcore/snapd/snap/snapdir"
"github.com/snapcore/snapd/snap/snapfile"
"github.com/snapcore/snapd/snap/squashfs"
"github.com/snapcore/snapd/sysconfig"
"github.com/snapcore/snapd/timings"
Expand Down Expand Up @@ -264,7 +266,6 @@
info.Revision = snap.R(-1)
}
return info, nil

}

func readComponentInfo(seedComp *seed.Component, mntPt string, snapInfo *snap.Info, csi *snap.ComponentSideInfo) (*snap.ComponentInfo, error) {
Expand Down Expand Up @@ -299,12 +300,36 @@
return ok, nil
}

func readSnapInfoFromPath(path string) (*snap.Info, error) {
snapf, err := snapfile.Open(path)
if err != nil {
return nil, err
}

Check warning on line 307 in cmd/snap-bootstrap/cmd_initramfs_mounts.go

View check run for this annotation

Codecov / codecov/patch

cmd/snap-bootstrap/cmd_initramfs_mounts.go#L306-L307

Added lines #L306 - L307 were not covered by tests
info, err := snap.ReadInfoFromSnapFile(snapf, nil)
if err != nil {
return nil, err

}

Check warning on line 312 in cmd/snap-bootstrap/cmd_initramfs_mounts.go

View check run for this annotation

Codecov / codecov/patch

cmd/snap-bootstrap/cmd_initramfs_mounts.go#L310-L312

Added lines #L310 - L312 were not covered by tests

// Comes from the seed and it might be unasserted, set revision in that case
if info.Revision.Unset() {
info.Revision = snap.R(-1)
}
return info, nil
}

func doInstall(mst *initramfsMountsState, model *asserts.Model, sysSnaps map[snap.Type]*seed.Snap) error {
kernelSnap, err := readSnapInfo(sysSnaps, snap.TypeKernel)
if err != nil {
return err
}
baseSnap, err := readSnapInfo(sysSnaps, snap.TypeBase)
var baseSnap *snap.Info
if is24plusSystem(model) {
// 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)
}
if err != nil {
return err
}
Expand Down Expand Up @@ -1837,6 +1862,15 @@
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 generateMountsCommonInstallRecoverStart(mst *initramfsMountsState) (model *asserts.Model, sysSnaps map[snap.Type]*seed.Snap, err error) {
seedMountOpts := &systemdMountOptions{
// always fsck the partition when we are mounting it, as this is the
Expand Down Expand Up @@ -1897,10 +1931,45 @@

for _, essentialSnap := range essSnaps {
systemSnaps[essentialSnap.EssentialType] = essentialSnap
dir := snapTypeToMountDir[essentialSnap.EssentialType]
// TODO:UC20: we need to cross-check the kernel path with snapd_recovery_kernel used by grub
if err := doSystemdMount(essentialSnap.Path, filepath.Join(boot.InitramfsRunMntDir, dir), mountReadOnlyOptions); err != nil {
return nil, nil, err
if essentialSnap.EssentialType == snap.TypeBase && is24plusSystem(model) {
// 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.
what := essentialSnap.Path
if err := writeSysrootMountUnit(what, "squashfs"); err != nil {
return nil, nil, fmt.Errorf(
"cannot write sysroot.mount (what: %s): %v", what, err)
}

Check warning on line 1942 in cmd/snap-bootstrap/cmd_initramfs_mounts.go

View check run for this annotation

Codecov / codecov/patch

cmd/snap-bootstrap/cmd_initramfs_mounts.go#L1940-L1942

Added lines #L1940 - L1942 were not covered by tests
// 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
// finishes)
sysd := systemd.New(systemd.SystemMode, nil)
if err := sysd.DaemonReload(); err != nil {
return nil, nil, err
}

Check warning on line 1950 in cmd/snap-bootstrap/cmd_initramfs_mounts.go

View check run for this annotation

Codecov / codecov/patch

cmd/snap-bootstrap/cmd_initramfs_mounts.go#L1949-L1950

Added lines #L1949 - L1950 were not covered by tests
if model.Classic() && model.KernelSnap() != nil {
// Mount ephemerally for recover mode to gain access to /etc data
dir := snapTypeToMountDir[essentialSnap.EssentialType]
if err := doSystemdMount(essentialSnap.Path,
filepath.Join(boot.InitramfsRunMntDir, dir),
&systemdMountOptions{
Ephemeral: true,
ReadOnly: true,
Private: true,
}); err != nil {
return nil, nil, err
}

Check warning on line 1962 in cmd/snap-bootstrap/cmd_initramfs_mounts.go

View check run for this annotation

Codecov / codecov/patch

cmd/snap-bootstrap/cmd_initramfs_mounts.go#L1952-L1962

Added lines #L1952 - L1962 were not covered by tests
}
} else {
dir := snapTypeToMountDir[essentialSnap.EssentialType]
// TODO:UC20: we need to cross-check the kernel path
// with snapd_recovery_kernel used by grub
if err := doSystemdMount(essentialSnap.Path,
filepath.Join(boot.InitramfsRunMntDir, dir),
mountReadOnlyOptions); err != nil {
return nil, nil, err
}

Check warning on line 1972 in cmd/snap-bootstrap/cmd_initramfs_mounts.go

View check run for this annotation

Codecov / codecov/patch

cmd/snap-bootstrap/cmd_initramfs_mounts.go#L1971-L1972

Added lines #L1971 - L1972 were not covered by tests
}
}

Expand Down Expand Up @@ -2356,6 +2425,25 @@
// to the function above to make decisions there, or perhaps this
// code actually belongs in the bootloader implementation itself

typesToMount := typs
if is24plusSystem(model) {
// 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.
typesToMount = []snap.Type{snap.TypeGadget, snap.TypeKernel}
if isClassic {
if err := writeSysrootMountUnit(rootfsDir, ""); err != nil {
return fmt.Errorf("cannot write sysroot.mount (what: %s): %v", rootfsDir, err)
}
} else {
basePlaceInfo := mounts[snap.TypeBase]
what := filepath.Join(dirs.SnapBlobDirUnder(rootfsDir), basePlaceInfo.Filename())
if err := writeSysrootMountUnit(what, "squashfs"); err != nil {
return fmt.Errorf("cannot write sysroot.mount (what: %s): %v", what, err)
}

Check warning on line 2443 in cmd/snap-bootstrap/cmd_initramfs_mounts.go

View check run for this annotation

Codecov / codecov/patch

cmd/snap-bootstrap/cmd_initramfs_mounts.go#L2430-L2443

Added lines #L2430 - L2443 were not covered by tests
}
}

// Create mounts for kernel modules/firmware if we have a drivers tree.
// InitramfsRunModeSelectSnapsToMount guarantees we do have a kernel in the map.
kernPlaceInfo := mounts[snap.TypeKernel]
Expand All @@ -2365,8 +2453,8 @@
return err
}

// 4.3 mount base (if UC), gadget and kernel (if there is no drivers tree) snaps
for _, typ := range typs {
// 4.3 mount the gadget snap and, if there is no drivers tree, the kernel snap
for _, typ := range typesToMount {
if typ == snap.TypeKernel && hasDriversTree {
continue
}
Expand Down Expand Up @@ -2412,7 +2500,12 @@
}
}

return nil
// 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
// finishes)
sysd := systemd.New(systemd.SystemMode, nil)
return sysd.DaemonReload()
}

var tryRecoverySystemHealthCheck = func(model gadget.Model) error {
Expand Down
Loading
Loading