Merge lp:~mvo/snappy/snappy-bootsuccess-env into lp:~snappy-dev/snappy/snappy-moved-to-github

Proposed by Michael Vogt on 2015-07-16
Status: Merged
Approved by: Michael Vogt on 2015-07-22
Approved revision: 590
Merged at revision: 594
Proposed branch: lp:~mvo/snappy/snappy-bootsuccess-env
Merge into: lp:~snappy-dev/snappy/snappy-moved-to-github
Diff against target: 226 lines (+130/-12)
5 files modified
partition/bootloader.go (+2/-0)
partition/bootloader_grub.go (+6/-9)
partition/bootloader_uboot.go (+69/-3)
partition/bootloader_uboot_test.go (+52/-0)
partition/partition_test.go (+1/-0)
To merge this branch: bzr merge lp:~mvo/snappy/snappy-bootsuccess-env
Reviewer Review Type Date Requested Status
Michael Vogt Approve on 2015-07-22
Sergio Schvezov 2015-07-16 Needs Information on 2015-07-17
Review via email: mp+264981@code.launchpad.net

Commit Message

Change bootsuccessful uboot to use fw_setenv instead of modifying a
text-file.

Description of the Change

Change bootsuccessful uboot to use fw_setenv instead of modifying a
text-file.

This merge should wait until a full end-to-end test was performed.

To post a comment you must log in.
review: Needs Information
Michael Vogt (mvo) wrote :

Thanks for the review, you raised some important points. I addressed them now. Please let me know if there is anything else that should be fixed.

Snappy Tarmac (snappydevtarmac) wrote :

Voting does not meet specified criteria. Required: Approve >= 1, Disapprove == 0. Got: 1 Needs Information.

Michael Vogt (mvo) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'partition/bootloader.go'
2--- partition/bootloader.go 2015-07-01 14:48:33 +0000
3+++ partition/bootloader.go 2015-07-17 18:15:23 +0000
4@@ -37,6 +37,8 @@
5 // that the boot of the new rootfs was successful).
6 bootloaderBootmodeVar = "snappy_mode"
7
8+ bootloaderTrialBootVar = "snappy_trial_boot"
9+
10 // Initial and final values
11 bootloaderBootmodeTry = "try"
12 bootloaderBootmodeSuccess = "regular"
13
14=== modified file 'partition/bootloader_grub.go'
15--- partition/bootloader_grub.go 2015-07-01 14:48:33 +0000
16+++ partition/bootloader_grub.go 2015-07-17 18:15:23 +0000
17@@ -32,16 +32,14 @@
18 bootloaderGrubConfigFileReal = "/boot/grub/grub.cfg"
19 bootloaderGrubEnvFileReal = "/boot/grub/grubenv"
20
21- bootloaderGrubEnvCmdReal = "/usr/bin/grub-editenv"
22- bootloaderGrubTrialBootVarReal = "snappy_trial_boot"
23+ bootloaderGrubEnvCmdReal = "/usr/bin/grub-editenv"
24 )
25
26 // var to make it testable
27 var (
28- bootloaderGrubDir = bootloaderGrubDirReal
29- bootloaderGrubConfigFile = bootloaderGrubConfigFileReal
30- bootloaderGrubTrialBootVar = bootloaderGrubTrialBootVarReal
31- bootloaderGrubEnvFile = bootloaderGrubEnvFileReal
32+ bootloaderGrubDir = bootloaderGrubDirReal
33+ bootloaderGrubConfigFile = bootloaderGrubConfigFileReal
34+ bootloaderGrubEnvFile = bootloaderGrubEnvFileReal
35
36 bootloaderGrubEnvCmd = bootloaderGrubEnvCmdReal
37 )
38@@ -122,9 +120,8 @@
39 }
40
41 func (g *grub) MarkCurrentBootSuccessful(currentRootfs string) (err error) {
42- // Clear the variable set by grub on boot to denote a good
43- // boot.
44- if err := g.unsetBootVar(bootloaderGrubTrialBootVar); err != nil {
45+ // Clear the variable set on boot to denote a good boot.
46+ if err := g.unsetBootVar(bootloaderTrialBootVar); err != nil {
47 return err
48 }
49
50
51=== modified file 'partition/bootloader_uboot.go'
52--- partition/bootloader_uboot.go 2015-07-01 06:27:50 +0000
53+++ partition/bootloader_uboot.go 2015-07-17 18:15:23 +0000
54@@ -41,9 +41,11 @@
55 // this partition is "good".
56 bootloaderUbootStampFileReal = "/boot/uboot/snappy-stamp.txt"
57
58- // the main uEnv.txt u-boot config file sources this snappy
59- // boot-specific config file.
60+ // DEPRECATED:
61 bootloaderUbootEnvFileReal = "/boot/uboot/snappy-system.txt"
62+
63+ // the real uboot env
64+ bootloaderUbootFwEnvFileReal = "/boot/uboot/uboot.env"
65 )
66
67 // var to make it testable
68@@ -52,6 +54,7 @@
69 bootloaderUbootConfigFile = bootloaderUbootConfigFileReal
70 bootloaderUbootStampFile = bootloaderUbootStampFileReal
71 bootloaderUbootEnvFile = bootloaderUbootEnvFileReal
72+ bootloaderUbootFwEnvFile = bootloaderUbootFwEnvFileReal
73 atomicFileUpdate = atomicFileUpdateImpl
74 )
75
76@@ -186,7 +189,7 @@
77 return file.Sync()
78 }
79
80-func (u *uboot) MarkCurrentBootSuccessful(currentRootfs string) (err error) {
81+func (u *uboot) markCurrentBootSuccessfulLegacy(currentRootfs string) error {
82 changes := []configFileChange{
83 configFileChange{Name: bootloaderBootmodeVar,
84 Value: bootloaderBootmodeSuccess,
85@@ -203,6 +206,69 @@
86 return os.RemoveAll(bootloaderUbootStampFile)
87 }
88
89+// fw_setenv gets the location of the configuration to use from the
90+// file /etc/fw_env.config
91+func (u *uboot) unsetBootVar(name string) error {
92+ if u.hasBootVar(name) {
93+ return runCommand("fw_setenv", name)
94+ }
95+
96+ return nil
97+}
98+
99+func (u *uboot) setBootVar(name, value string) error {
100+ // we ignore the error here, the interface of fw_printenv
101+ // is very simplistic, the github.com/mvo5/uboot-go code
102+ // will fix that
103+ curVal, _ := u.getBootVar(name)
104+ if curVal != value {
105+ return runCommand("fw_setenv", name, value)
106+ }
107+
108+ return nil
109+}
110+
111+func (u *uboot) hasBootVar(name string) bool {
112+ // FIXME: too simplistic, this will be replaces with
113+ // github.com/mvo5/uboot-go/
114+ err := runCommand("fw_printenv", name)
115+ return err == nil
116+}
117+
118+func (u *uboot) getBootVar(name string) (string, error) {
119+ output, err := runCommandWithStdout("fw_printenv", "-n", name)
120+ if err != nil {
121+ return "", err
122+ }
123+
124+ return output, nil
125+}
126+
127+// FIXME: this is super similar to grub now, refactor to extract the
128+// common code
129+func (u *uboot) markCurrentBootSuccessfulFwEnv(currentRootfs string) error {
130+ // Clear the variable set on boot to denote a good boot.
131+ if err := u.unsetBootVar(bootloaderTrialBootVar); err != nil {
132+ return err
133+ }
134+
135+ if err := u.setBootVar(bootloaderRootfsVar, currentRootfs); err != nil {
136+ return err
137+ }
138+
139+ return u.setBootVar(bootloaderBootmodeVar, bootloaderBootmodeSuccess)
140+}
141+
142+func (u *uboot) MarkCurrentBootSuccessful(currentRootfs string) error {
143+ // modern system
144+ if helpers.FileExists(bootloaderUbootFwEnvFile) {
145+ return u.markCurrentBootSuccessfulFwEnv(currentRootfs)
146+ }
147+
148+ // legacy
149+ return u.markCurrentBootSuccessfulLegacy(currentRootfs)
150+}
151+
152 // Write lines to file atomically. File does not have to preexist.
153 // FIXME: put into utils package
154 func atomicFileUpdateImpl(file string, lines []string) (err error) {
155
156=== modified file 'partition/bootloader_uboot_test.go'
157--- partition/bootloader_uboot_test.go 2015-06-29 23:15:00 +0000
158+++ partition/bootloader_uboot_test.go 2015-07-17 18:15:23 +0000
159@@ -318,3 +318,55 @@
160 c.Check(strings.Contains(string(bytes), "snappy_mode=regular"), Equals, true)
161 c.Check(strings.Contains(string(bytes), "snappy_ab=a"), Equals, true)
162 }
163+
164+func (s *PartitionTestSuite) TestUbootMarkCurrentBootSuccessfulFwEnv(c *C) {
165+ s.makeFakeUbootEnv(c)
166+
167+ err := ioutil.WriteFile(bootloaderUbootFwEnvFile, []byte(""), 0644)
168+ c.Assert(err, IsNil)
169+
170+ partition := New()
171+ u := newUboot(partition)
172+ c.Assert(u, NotNil)
173+
174+ allCommands = nil
175+ runCommand = mockRunCommandWithCapture
176+ err = u.MarkCurrentBootSuccessful("b")
177+ c.Assert(err, IsNil)
178+ c.Assert(allCommands, HasLen, 4)
179+ c.Assert(allCommands[0], DeepEquals, singleCommand{"fw_printenv", bootloaderTrialBootVar})
180+ c.Assert(allCommands[1], DeepEquals, singleCommand{"fw_setenv", bootloaderTrialBootVar})
181+ c.Assert(allCommands[2], DeepEquals, singleCommand{"fw_setenv", bootloaderRootfsVar, "b"})
182+ c.Assert(allCommands[3], DeepEquals, singleCommand{"fw_setenv", bootloaderBootmodeVar, bootloaderBootmodeSuccess})
183+}
184+
185+func (s *PartitionTestSuite) TestUbootSetEnv(c *C) {
186+ s.makeFakeUbootEnv(c)
187+
188+ err := ioutil.WriteFile(bootloaderUbootFwEnvFile, []byte(""), 0644)
189+ c.Assert(err, IsNil)
190+
191+ partition := New()
192+ u := newUboot(partition)
193+ c.Assert(u, NotNil)
194+
195+ // we simulate here that fw_printenv bootloaderreturns
196+ runCommandWithStdout = func(args ...string) (string, error) {
197+ if args[0] == "fw_printenv" && args[2] == bootloaderRootfsVar {
198+ return "b", nil
199+ }
200+
201+ return "something", nil
202+ }
203+
204+ allCommands = nil
205+ runCommand = mockRunCommandWithCapture
206+ err = u.(*uboot).setBootVar(bootloaderRootfsVar, "b")
207+ c.Assert(err, IsNil)
208+ c.Assert(allCommands, HasLen, 0)
209+
210+ err = u.(*uboot).setBootVar(bootloaderRootfsVar, "a")
211+ c.Assert(err, IsNil)
212+ c.Assert(allCommands, HasLen, 1)
213+ c.Assert(allCommands[0], DeepEquals, singleCommand{"fw_setenv", bootloaderRootfsVar, "a"})
214+}
215
216=== modified file 'partition/partition_test.go'
217--- partition/partition_test.go 2015-07-01 14:48:33 +0000
218+++ partition/partition_test.go 2015-07-17 18:15:23 +0000
219@@ -60,6 +60,7 @@
220 bootloaderUbootDir = filepath.Join(s.tempdir, "boot", "uboot")
221 bootloaderUbootConfigFile = filepath.Join(bootloaderUbootDir, "uEnv.txt")
222 bootloaderUbootEnvFile = filepath.Join(bootloaderUbootDir, "uEnv.txt")
223+ bootloaderUbootFwEnvFile = filepath.Join(bootloaderUbootDir, "uboot.env")
224 bootloaderUbootStampFile = filepath.Join(bootloaderUbootDir, "snappy-stamp.txt")
225
226 c.Assert(mounts, DeepEquals, mountEntryArray(nil))

Subscribers

People subscribed via source and target branches