From 1d6746fa2440e1cbfd63d33427b2d19394e97899 Mon Sep 17 00:00:00 2001 From: Valentin David Date: Mon, 18 Nov 2024 12:21:03 +0100 Subject: [PATCH] overlord/fdestate/fdestate.go: fix path to data mount point on hybrid We used a path that is not a mount point on hybrid to discover the data disk. Instead we now use / for hybrid, and /writable on core. --- dirs/dirs.go | 13 ++++++++++ dirs/dirs_test.go | 14 +++++++++++ overlord/fdestate/fdemgr_test.go | 43 ++++++++++++++++++++++++++------ overlord/fdestate/fdestate.go | 2 +- overlord/managers_test.go | 4 ++- 5 files changed, 67 insertions(+), 9 deletions(-) diff --git a/dirs/dirs.go b/dirs/dirs.go index f1d441ee33f..a91109e33dd 100644 --- a/dirs/dirs.go +++ b/dirs/dirs.go @@ -141,6 +141,11 @@ var ( SysfsDir string FeaturesDir string + + // WritableMountPath is a path where writable root data is + // mounted. For Classic it is /, but Ubuntu Core it is + // /writable. + WritableMountPath string ) // User defined home directory variables @@ -635,6 +640,14 @@ func SetRootDir(rootdir string) { c(rootdir) } + if release.OnClassic { + // On Classic, the data disk is mounted as / + WritableMountPath = rootdir + } else { + // If on Core /writable is a bind mount from data dir + WritableMountPath = filepath.Join(rootdir, "writable") + } + } // what inside a (non-classic) snap is /usr/lib/snapd, outside can come from different places diff --git a/dirs/dirs_test.go b/dirs/dirs_test.go index e0aa31489cf..1b05d4a78b1 100644 --- a/dirs/dirs_test.go +++ b/dirs/dirs_test.go @@ -290,3 +290,17 @@ func (s *DirsTestSuite) TestLibexecdirOpenSUSEFlavors(c *C) { dirs.SetRootDir("/") c.Check(dirs.DistroLibExecDir, Equals, "/usr/libexec/snapd") } + +func (s *DirsTestSuite) TestWritableMountPath(c *C) { + release.MockOnClassic(true) + dirs.SetRootDir("/") + + c.Check(dirs.WritableMountPath, Equals, "/") +} + +func (s *DirsTestSuite) TestWritableMountPathCore(c *C) { + release.MockOnClassic(false) + dirs.SetRootDir("/") + + c.Check(dirs.WritableMountPath, Equals, "/writable") +} diff --git a/overlord/fdestate/fdemgr_test.go b/overlord/fdestate/fdemgr_test.go index 6aee7f7496f..860d385e4a7 100644 --- a/overlord/fdestate/fdemgr_test.go +++ b/overlord/fdestate/fdemgr_test.go @@ -24,6 +24,7 @@ import ( "crypto" "fmt" "os" + "path/filepath" "testing" . "gopkg.in/check.v1" @@ -36,6 +37,7 @@ import ( "github.com/snapcore/snapd/overlord/fdestate" "github.com/snapcore/snapd/overlord/fdestate/backend" "github.com/snapcore/snapd/overlord/state" + "github.com/snapcore/snapd/release" "github.com/snapcore/snapd/secboot" "github.com/snapcore/snapd/snapdenv" "github.com/snapcore/snapd/testutil" @@ -56,6 +58,8 @@ var _ = Suite(&fdeMgrSuite{}) func (s *fdeMgrSuite) SetUpTest(c *C) { s.BaseTest.SetUpTest(c) + s.AddCleanup(release.MockOnClassic(true)) + s.rootdir = c.MkDir() dirs.SetRootDir(s.rootdir) s.AddCleanup(func() { dirs.SetRootDir("") }) @@ -101,10 +105,14 @@ func (u *instrumentedUnlocker) Relock() { u.relocked += 1 } -func (s *fdeMgrSuite) startedManager(c *C) *fdestate.FDEManager { +func (s *fdeMgrSuite) startedManager(c *C, onClassic bool) *fdestate.FDEManager { defer fdestate.MockDMCryptUUIDFromMountPoint(func(mountpoint string) (string, error) { switch mountpoint { - case dirs.SnapdStateDir(dirs.GlobalRootDir): + case dirs.GlobalRootDir: + c.Check(onClassic, Equals, true) + return "aaa", nil + case filepath.Join(dirs.GlobalRootDir, "writable"): + c.Check(onClassic, Equals, false) return "aaa", nil case dirs.SnapSaveDir: return "bbb", nil @@ -132,9 +140,12 @@ func (s *fdeMgrSuite) startedManager(c *C) *fdestate.FDEManager { return manager } -func (s *fdeMgrSuite) TestGetManagerFromState(c *C) { +func (s *fdeMgrSuite) testGetManagerFromState(c *C, onClassic bool) { st := s.st - manager := s.startedManager(c) + s.AddCleanup(release.MockOnClassic(onClassic)) + dirs.SetRootDir(s.rootdir) + + manager := s.startedManager(c, onClassic) st.Lock() defer st.Unlock() @@ -151,6 +162,16 @@ func (s *fdeMgrSuite) TestGetManagerFromState(c *C) { c.Check(primaryKey.Digest.Digest, DeepEquals, []byte{5, 6, 7, 8}) } +func (s *fdeMgrSuite) TestGetManagerFromStateClassic(c *C) { + const onClassic = true + s.testGetManagerFromState(c, onClassic) +} + +func (s *fdeMgrSuite) TestGetManagerFromStateCore(c *C) { + const onClassic = false + s.testGetManagerFromState(c, onClassic) +} + type mockModel struct { } @@ -180,7 +201,11 @@ func (m *mockModel) SignKeyID() string { func (s *fdeMgrSuite) TestUpdateState(c *C) { st := s.st - manager := s.startedManager(c) + const onClassic = true + s.AddCleanup(release.MockOnClassic(onClassic)) + dirs.SetRootDir(s.rootdir) + + manager := s.startedManager(c, onClassic) st.Lock() defer st.Unlock() @@ -209,7 +234,11 @@ func (s *fdeMgrSuite) TestUpdateState(c *C) { func (s *fdeMgrSuite) TestUpdateReseal(c *C) { st := s.st - manager := s.startedManager(c) + const onClassic = true + s.AddCleanup(release.MockOnClassic(onClassic)) + dirs.SetRootDir(s.rootdir) + + manager := s.startedManager(c, onClassic) st.Lock() defer st.Unlock() @@ -261,7 +290,7 @@ type mountResolveTestCase struct { func (s *fdeMgrSuite) testMountResolveError(c *C, tc mountResolveTestCase) { defer fdestate.MockDMCryptUUIDFromMountPoint(func(mountpoint string) (string, error) { switch mountpoint { - case dirs.SnapdStateDir(dirs.GlobalRootDir): + case dirs.GlobalRootDir: // ubuntu-data if tc.dataResolveErr != nil { return "", tc.dataResolveErr diff --git a/overlord/fdestate/fdestate.go b/overlord/fdestate/fdestate.go index 5f565314dd2..dea3fa25dac 100644 --- a/overlord/fdestate/fdestate.go +++ b/overlord/fdestate/fdestate.go @@ -218,7 +218,7 @@ func initializeState(st *state.State) error { // FIXME mount points will be different in recovery or factory-reset modes // either inspect degraded.json, or use boot.HostUbuntuDataForMode() - dataUUID, dataErr := disksDMCryptUUIDFromMountPoint(dirs.SnapdStateDir(dirs.GlobalRootDir)) + dataUUID, dataErr := disksDMCryptUUIDFromMountPoint(dirs.WritableMountPath) saveUUID, saveErr := disksDMCryptUUIDFromMountPoint(dirs.SnapSaveDir) if errors.Is(saveErr, disks.ErrMountPointNotFound) { // TODO: do we need to care about old cases where there is no save partition? diff --git a/overlord/managers_test.go b/overlord/managers_test.go index ab59b2aad5d..d5fcacf13bb 100644 --- a/overlord/managers_test.go +++ b/overlord/managers_test.go @@ -7461,7 +7461,9 @@ func (s *mgrsSuiteCore) testRemodelUC20WithRecoverySystem(c *C, encrypted bool) restore = fdestate.MockDMCryptUUIDFromMountPoint(func(mountpoint string) (string, error) { switch mountpoint { - case dirs.SnapdStateDir(dirs.GlobalRootDir): + case filepath.Join(dirs.GlobalRootDir, "writable"): + return "root-uuid", nil + case dirs.GlobalRootDir: return "root-uuid", nil case dirs.SnapSaveDir: return "save-uuid", nil