Skip to content

Commit

Permalink
bootloader/lkenv: specify backup file as arg to NewEnv(), use "" as p…
Browse files Browse the repository at this point in the history
…ath+"bak"

Merge pull request #9729 from anonymouse64/feature/uc20-lk-bootloader-7

To simplify existing code, use "" as the backup file to mean path+"bak".

Also add tests that when specifying a non-empty string as the backup file that
we don't use the legacy backup file handling logic.

This will resolve the issue we have in #9695 around passing in /dev/disk/by-partuuid/1234 as the primary file and then getting /dev/disk/by-partuuid/1234bak as the backup file.
  • Loading branch information
pedronis committed Dec 2, 2020
2 parents f817cbf + 7646ad8 commit fa15410
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 24 deletions.
2 changes: 1 addition & 1 deletion bootloader/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func MockLkFiles(c *C, rootdir string, opts *Options) {
err = ioutil.WriteFile(l.envFile(), buf, 0660)
c.Assert(err, IsNil)
// now write env in it with correct crc
env := lkenv.NewEnv(l.envFile(), lkenv.V1)
env := lkenv.NewEnv(l.envFile(), "", lkenv.V1)
env.InitializeBootPartitions("boot_a", "boot_b")
err = env.Save()
c.Assert(err, IsNil)
Expand Down
8 changes: 4 additions & 4 deletions bootloader/lk.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (l *lk) envFile() string {
func (l *lk) GetBootVars(names ...string) (map[string]string, error) {
out := make(map[string]string)

env := lkenv.NewEnv(l.envFile(), lkenv.V1)
env := lkenv.NewEnv(l.envFile(), "", lkenv.V1)
if err := env.Load(); err != nil {
return nil, err
}
Expand All @@ -104,7 +104,7 @@ func (l *lk) GetBootVars(names ...string) (map[string]string, error) {
}

func (l *lk) SetBootVars(values map[string]string) error {
env := lkenv.NewEnv(l.envFile(), lkenv.V1)
env := lkenv.NewEnv(l.envFile(), "", lkenv.V1)
if err := env.Load(); err != nil && !os.IsNotExist(err) {
return err
}
Expand Down Expand Up @@ -138,7 +138,7 @@ func (l *lk) ExtractKernelAssets(s snap.PlaceInfo, snapf snap.Container) error {

logger.Debugf("ExtractKernelAssets (%s)", blobName)

env := lkenv.NewEnv(l.envFile(), lkenv.V1)
env := lkenv.NewEnv(l.envFile(), "", lkenv.V1)
if err := env.Load(); err != nil && !os.IsNotExist(err) {
return err
}
Expand Down Expand Up @@ -198,7 +198,7 @@ func (l *lk) ExtractKernelAssets(s snap.PlaceInfo, snapf snap.Container) error {
func (l *lk) RemoveKernelAssets(s snap.PlaceInfo) error {
blobName := s.Filename()
logger.Debugf("RemoveKernelAssets (%s)", blobName)
env := lkenv.NewEnv(l.envFile(), lkenv.V1)
env := lkenv.NewEnv(l.envFile(), "", lkenv.V1)
if err := env.Load(); err != nil && !os.IsNotExist(err) {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions bootloader/lk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func (s *lkTestSuite) TestExtractKernelAssetsUnpacksCustomBootimgImageBuilding(c
c.Assert(l, NotNil)

// first configure custom boot image file name
env := lkenv.NewEnv(bootloader.LkConfigFile(l), lkenv.V1)
env := lkenv.NewEnv(bootloader.LkConfigFile(l), "", lkenv.V1)
env.Load()
env.Set("bootimg_file_name", "boot-2.img")
err := env.Save()
Expand Down Expand Up @@ -188,7 +188,7 @@ func (s *lkTestSuite) TestExtractKernelAssetsUnpacksAndRemoveInRuntimeMode(c *C)
}
// ensure we have a valid boot env
bootselPartition := filepath.Join(s.rootdir, "/dev/disk/by-partlabel/snapbootsel")
lkenv := lkenv.NewEnv(bootselPartition, lkenv.V1)
lkenv := lkenv.NewEnv(bootselPartition, "", lkenv.V1)
lkenv.InitializeBootPartitions("boot_a", "boot_b")
err := lkenv.Save()
c.Assert(err, IsNil)
Expand Down
13 changes: 10 additions & 3 deletions bootloader/lkenv/lkenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ type Env struct {
path string
// pathbak is the backup lkenv object file, it too can either be a regular
// file during build time, or a partition device node at run time, and it is
// always given by "<path>" + "bak", i.e. $PWD/lk.conf and $PWD/lk.confbak.
// typically at prepare-image time given by "<path>" + "bak", i.e.
// $PWD/lk.conf and $PWD/lk.confbak but will be different device nodes for
// different partitions at runtime.
pathbak string
// version is the configured version of the lkenv object from NewEnv.
version Version
Expand Down Expand Up @@ -194,10 +196,15 @@ func copyString(b []byte, s string) {
// is expected to be a valid lkenv object, then the object should be loaded with
// the Load() method, otherwise the lkenv object can be manipulated in memory
// and later written to disk with Save().
func NewEnv(path string, version Version) *Env {
func NewEnv(path, backupPath string, version Version) *Env {
if backupPath == "" {
// legacy behavior is for the backup file to be the same name/dir, but
// with "bak" appended to it
backupPath = path + "bak"
}
e := &Env{
path: path,
pathbak: path + "bak",
pathbak: backupPath,
version: version,
}

Expand Down
97 changes: 83 additions & 14 deletions bootloader/lkenv/lkenv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (l *lkenvTestSuite) TestCopyStringNoPanic(c *C) {
func (l *lkenvTestSuite) TestGetBootImageName(c *C) {
for _, version := range lkversions {
for _, setValue := range []bool{true, false} {
env := lkenv.NewEnv(l.envPath, version)
env := lkenv.NewEnv(l.envPath, "", version)
c.Check(env, NotNil)

if setValue {
Expand Down Expand Up @@ -173,7 +173,7 @@ func (l *lkenvTestSuite) TestSet(c *C) {
},
}
for _, t := range tt {
env := lkenv.NewEnv(l.envPath, t.version)
env := lkenv.NewEnv(l.envPath, "", t.version)
c.Check(env, NotNil)
env.Set(t.key, t.val)
c.Check(env.Get(t.key), Equals, t.val)
Expand Down Expand Up @@ -248,7 +248,7 @@ func (l *lkenvTestSuite) TestSave(c *C) {
err := ioutil.WriteFile(testFile, buf, 0644)
c.Assert(err, IsNil, comment)

env := lkenv.NewEnv(testFile, t.version)
env := lkenv.NewEnv(testFile, "", t.version)
c.Check(env, NotNil, comment)

for k, v := range t.keyValuePairs {
Expand All @@ -258,7 +258,7 @@ func (l *lkenvTestSuite) TestSave(c *C) {
err = env.Save()
c.Assert(err, IsNil, comment)

env2 := lkenv.NewEnv(testFile, t.version)
env2 := lkenv.NewEnv(testFile, "", t.version)
err = env2.Load()
c.Assert(err, IsNil, comment)

Expand All @@ -268,7 +268,7 @@ func (l *lkenvTestSuite) TestSave(c *C) {

// check the backup too
if makeBackup {
env3 := lkenv.NewEnv(testFileBackup, t.version)
env3 := lkenv.NewEnv(testFileBackup, "", t.version)
err := env3.Load()
c.Assert(err, IsNil, comment)

Expand All @@ -285,7 +285,7 @@ func (l *lkenvTestSuite) TestSave(c *C) {
_, err = io.Copy(f, bytes.NewBuffer(buf))
c.Assert(err, IsNil, comment)

env4 := lkenv.NewEnv(testFile, t.version)
env4 := lkenv.NewEnv(testFile, "", t.version)
err = env4.Load()
c.Assert(err, IsNil, comment)

Expand Down Expand Up @@ -340,7 +340,7 @@ func (l *lkenvTestSuite) TestLoadValidatesCRC32(c *C) {
c.Assert(err, IsNil)

// now try importing the file with LoadEnv()
env := lkenv.NewEnv(testFile, version)
env := lkenv.NewEnv(testFile, "", version)
c.Assert(env, NotNil)

err = env.LoadEnv(testFile)
Expand All @@ -349,6 +349,75 @@ func (l *lkenvTestSuite) TestLoadValidatesCRC32(c *C) {

}

func (l *lkenvTestSuite) TestNewBackupFileLocation(c *C) {
// creating with the second argument as the empty string falls back to
// the main path + "bak"
for _, version := range lkversions {
logbuf, restore := logger.MockLogger()
defer restore()

testFile := filepath.Join(c.MkDir(), "lk.bin")
c.Assert(testFile, testutil.FileAbsent)
c.Assert(testFile+"bak", testutil.FileAbsent)
// make empty files for Save() to overwrite
err := ioutil.WriteFile(testFile, nil, 0644)
c.Assert(err, IsNil)
err = ioutil.WriteFile(testFile+"bak", nil, 0644)
c.Assert(err, IsNil)
env := lkenv.NewEnv(testFile, "", version)
c.Assert(env, NotNil)
err = env.Save()
c.Assert(err, IsNil)

// make sure both the primary and backup files were written and can be
// successfully loaded
env2 := lkenv.NewEnv(testFile, "", version)
err = env2.Load()
c.Assert(err, IsNil)

env3 := lkenv.NewEnv(testFile+"bak", "", version)
err = env3.Load()
c.Assert(err, IsNil)

// no messages logged
c.Assert(logbuf.String(), Equals, "")
}

// now specify a different backup file location
for _, version := range lkversions {
logbuf, restore := logger.MockLogger()
defer restore()
testFile := filepath.Join(c.MkDir(), "lk.bin")
testFileBackup := filepath.Join(c.MkDir(), "lkbackup.bin")
err := ioutil.WriteFile(testFile, nil, 0644)
c.Assert(err, IsNil)
err = ioutil.WriteFile(testFileBackup, nil, 0644)
c.Assert(err, IsNil)

env := lkenv.NewEnv(testFile, testFileBackup, version)
c.Assert(env, NotNil)
err = env.Save()
c.Assert(err, IsNil)

// make sure both the primary and backup files were written and can be
// successfully loaded
env2 := lkenv.NewEnv(testFile, "", version)
err = env2.Load()
c.Assert(err, IsNil)

env3 := lkenv.NewEnv(testFileBackup, "", version)
err = env3.Load()
c.Assert(err, IsNil)

// no "bak" files present
c.Assert(testFile+"bak", testutil.FileAbsent)
c.Assert(testFileBackup+"bak", testutil.FileAbsent)

// no messages logged
c.Assert(logbuf.String(), Equals, "")
}
}

func (l *lkenvTestSuite) TestLoadValidatesVersionSignatureConsistency(c *C) {

tt := []struct {
Expand Down Expand Up @@ -436,7 +505,7 @@ func (l *lkenvTestSuite) TestLoadValidatesVersionSignatureConsistency(c *C) {
c.Assert(err, IsNil)

// now try importing the file with LoadEnv()
env := lkenv.NewEnv(testFile, t.version)
env := lkenv.NewEnv(testFile, "", t.version)
c.Assert(env, NotNil)

var expNum, gotNum uint32
Expand Down Expand Up @@ -480,7 +549,7 @@ func (l *lkenvTestSuite) TestLoad(c *C) {
c.Assert(err, IsNil)

// create an env for this file and try to load it
env := lkenv.NewEnv(testFile, version)
env := lkenv.NewEnv(testFile, "", version)
c.Check(env, NotNil)

err = env.Load()
Expand Down Expand Up @@ -617,7 +686,7 @@ func (l *lkenvTestSuite) TestGetAndSetAndFindBootPartition(c *C) {
err := ioutil.WriteFile(l.envPath, buf, 0644)
c.Assert(err, IsNil, comment)

env := lkenv.NewEnv(l.envPath, t.version)
env := lkenv.NewEnv(l.envPath, "", t.version)
c.Assert(env, Not(IsNil), comment)

var findFunc func(string) (string, error)
Expand Down Expand Up @@ -724,7 +793,7 @@ func (l *lkenvTestSuite) TestGetAndSetAndFindBootPartition(c *C) {
}

func (l *lkenvTestSuite) TestV1NoRecoverySystemSupport(c *C) {
env := lkenv.NewEnv(l.envPath, lkenv.V1)
env := lkenv.NewEnv(l.envPath, "", lkenv.V1)
c.Assert(env, NotNil)

_, err := env.FindFreeRecoverySystemBootPartition("blah")
Expand All @@ -741,7 +810,7 @@ func (l *lkenvTestSuite) TestV1NoRecoverySystemSupport(c *C) {
}

func (l *lkenvTestSuite) TestV2RunNoRecoverySystemSupport(c *C) {
env := lkenv.NewEnv(l.envPath, lkenv.V2Run)
env := lkenv.NewEnv(l.envPath, "", lkenv.V2Run)
c.Assert(env, NotNil)

_, err := env.FindFreeRecoverySystemBootPartition("blah")
Expand All @@ -758,7 +827,7 @@ func (l *lkenvTestSuite) TestV2RunNoRecoverySystemSupport(c *C) {
}

func (l *lkenvTestSuite) TestV2RecoveryNoKernelSupport(c *C) {
env := lkenv.NewEnv(l.envPath, lkenv.V2Recovery)
env := lkenv.NewEnv(l.envPath, "", lkenv.V2Recovery)
c.Assert(env, NotNil)

_, err := env.FindFreeKernelBootPartition("blah")
Expand Down Expand Up @@ -808,7 +877,7 @@ func (l *lkenvTestSuite) TestZippedDataSample(c *C) {
err = ioutil.WriteFile(l.envPathbak, rawData, 0644)
c.Assert(err, IsNil)

env := lkenv.NewEnv(l.envPath, lkenv.V1)
env := lkenv.NewEnv(l.envPath, "", lkenv.V1)
c.Check(env, NotNil)
err = env.Load()
c.Assert(err, IsNil)
Expand Down

0 comments on commit fa15410

Please sign in to comment.