From 7e3b1bb83e03d8aaef8880a3f0a97b355d037337 Mon Sep 17 00:00:00 2001 From: Valentin David Date: Wed, 25 Oct 2023 16:28:59 +0200 Subject: [PATCH] boot: lock the modeenv while reading revisions `ubuntu-core-20-64:tests/core/system-snap-refresh` fails because of this. --- boot/boot.go | 3 +++ boot/boot_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/boot/boot.go b/boot/boot.go index a7fbaa55588..98bbea101fb 100644 --- a/boot/boot.go +++ b/boot/boot.go @@ -275,6 +275,9 @@ func fixedInUse(inUse bool) InUseFunc { // InUse returns a checker for whether a given name/revision is used in the // boot environment for snaps of the relevant snap type. func InUse(typ snap.Type, dev snap.Device) (InUseFunc, error) { + modeenvLock() + defer modeenvUnlock() + if !dev.RunMode() { // ephemeral mode, block manipulations for now return fixedInUse(true), nil diff --git a/boot/boot_test.go b/boot/boot_test.go index c5e8defe3a5..b66d588ff6c 100644 --- a/boot/boot_test.go +++ b/boot/boot_test.go @@ -411,6 +411,47 @@ func (s *bootenvSuite) TestInUse(c *C) { } } +func (s *bootenv20Suite) TestInUseCore20(c *C) { + coreDev := boottest.MockUC20Device("", nil) + c.Assert(coreDev.HasModeenv(), Equals, true) + c.Assert(coreDev.IsCoreBoot(), Equals, true) + + r := setupUC20Bootenv( + c, + s.bootloader, + &bootenv20Setup{ + modeenv: &boot.Modeenv{ + // base is base1 + Base: s.base1.Filename(), + // no try base + TryBase: "", + // gadget is gadget1 + Gadget: s.gadget1.Filename(), + // current kernels is just kern1 + CurrentKernels: []string{s.kern1.Filename()}, + // operating mode is run + Mode: "run", + // RecoverySystem is unset, as it should be during run mode + RecoverySystem: "", + }, + // enabled kernel is kern1 + kern: s.kern1, + // no try kernel enabled + tryKern: nil, + // kernel status is default + kernStatus: boot.DefaultStatus, + }) + defer r() + + inUse, err := boot.InUse(snap.TypeKernel, coreDev) + c.Check(err, IsNil) + c.Check(inUse(s.kern1.SnapName(), s.kern1.SnapRevision()), Equals, true) + c.Check(inUse(s.kern2.SnapName(), s.kern2.SnapRevision()), Equals, false) + + _, err = boot.InUse(snap.TypeBase, coreDev) + c.Check(err, IsNil) +} + func (s *bootenvSuite) TestInUseEphemeral(c *C) { coreDev := boottest.MockDevice("some-snap@install")