~mvo/snappy/15.04-envvar_store_id

« back to all changes in this revision

Viewing changes to partition/bootloader_uboot.go

Backports of the uboot.env changes from trunk. by mvo approved by chipaca

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
        "launchpad.net/snappy/helpers"
29
29
 
30
30
        "github.com/mvo5/goconfigparser"
 
31
        "github.com/mvo5/uboot-go/uenv"
31
32
)
32
33
 
33
34
const (
40
41
        // this partition is "good".
41
42
        bootloaderUbootStampFileReal = "/boot/uboot/snappy-stamp.txt"
42
43
 
43
 
        // the main uEnv.txt u-boot config file sources this snappy
44
 
        // boot-specific config file.
 
44
        // DEPRECATED:
45
45
        bootloaderUbootEnvFileReal = "/boot/uboot/snappy-system.txt"
 
46
 
 
47
        // the real uboot env
 
48
        bootloaderUbootFwEnvFileReal = "/boot/uboot/uboot.env"
46
49
)
47
50
 
48
51
// var to make it testable
51
54
        bootloaderUbootConfigFile = bootloaderUbootConfigFileReal
52
55
        bootloaderUbootStampFile  = bootloaderUbootStampFileReal
53
56
        bootloaderUbootEnvFile    = bootloaderUbootEnvFileReal
 
57
        bootloaderUbootFwEnvFile  = bootloaderUbootFwEnvFileReal
54
58
        atomicFileUpdate          = atomicFileUpdateImpl
55
59
)
56
60
 
199
203
        return file.Sync()
200
204
}
201
205
 
202
 
func (u *uboot) MarkCurrentBootSuccessful() (err error) {
203
 
        changes := []configFileChange{
204
 
                configFileChange{Name: bootloaderBootmodeVar,
205
 
                        Value: bootloaderBootmodeSuccess,
206
 
                },
207
 
                configFileChange{Name: bootloaderRootfsVar,
208
 
                        Value: string(u.currentRootfs),
209
 
                },
210
 
        }
211
 
 
212
 
        if err := modifyNameValueFile(bootloaderUbootEnvFile, changes); err != nil {
213
 
                return err
214
 
        }
215
 
 
216
 
        return os.RemoveAll(bootloaderUbootStampFile)
217
 
}
218
 
 
219
206
func (u *uboot) SyncBootFiles() (err error) {
220
207
        srcDir := u.currentBootPath
221
208
        destDir := u.otherBootPath
317
304
        return err
318
305
}
319
306
 
 
307
func (u *uboot) unsetBootVar(name string) error {
 
308
        hasBootVar, err := u.hasBootVar(name)
 
309
        if err != nil {
 
310
                return err
 
311
        }
 
312
 
 
313
        // already unset, nothing to do
 
314
        if !hasBootVar {
 
315
                return nil
 
316
        }
 
317
 
 
318
        return u.setBootVar(name, "")
 
319
}
 
320
 
 
321
func (u *uboot) setBootVar(name, value string) error {
 
322
        env, err := uenv.Open(bootloaderUbootFwEnvFile)
 
323
        if err != nil {
 
324
                return err
 
325
        }
 
326
 
 
327
        // already set, nothing to do
 
328
        if env.Get(name) == value {
 
329
                return nil
 
330
        }
 
331
 
 
332
        env.Set(name, value)
 
333
        return env.Save()
 
334
}
 
335
 
 
336
func (u *uboot) hasBootVar(name string) (bool, error) {
 
337
        v, err := u.getBootVar(name)
 
338
        return v != "", err
 
339
}
 
340
 
 
341
func (u *uboot) getBootVar(name string) (string, error) {
 
342
        env, err := uenv.Open(bootloaderUbootFwEnvFile)
 
343
        if err != nil {
 
344
                return "", err
 
345
        }
 
346
 
 
347
        return env.Get(name), nil
 
348
}
 
349
 
 
350
// FIXME: this is super similar to grub now, refactor to extract the
 
351
//        common code
 
352
func (u *uboot) markCurrentBootSuccessfulFwEnv(currentRootfs string) error {
 
353
        // Clear the variable set on boot to denote a good boot.
 
354
        if err := u.unsetBootVar(bootloaderTrialBootVar); err != nil {
 
355
                return err
 
356
        }
 
357
 
 
358
        if err := u.setBootVar(bootloaderRootfsVar, currentRootfs); err != nil {
 
359
                return err
 
360
        }
 
361
 
 
362
        return u.setBootVar(bootloaderBootmodeVar, bootloaderBootmodeSuccess)
 
363
}
 
364
 
 
365
func (u *uboot) markCurrentBootSuccessfulLegacy(currentRootfs string) error {
 
366
        changes := []configFileChange{
 
367
                configFileChange{Name: bootloaderBootmodeVar,
 
368
                        Value: bootloaderBootmodeSuccess,
 
369
                },
 
370
                configFileChange{Name: bootloaderRootfsVar,
 
371
                        Value: string(u.currentRootfs),
 
372
                },
 
373
        }
 
374
 
 
375
        if err := modifyNameValueFile(bootloaderUbootEnvFile, changes); err != nil {
 
376
                return err
 
377
        }
 
378
 
 
379
        return os.RemoveAll(bootloaderUbootStampFile)
 
380
}
 
381
 
 
382
func (u *uboot) MarkCurrentBootSuccessful() error {
 
383
        // modern system
 
384
        if helpers.FileExists(bootloaderUbootFwEnvFile) {
 
385
                return u.markCurrentBootSuccessfulFwEnv(u.currentRootfs)
 
386
        }
 
387
 
 
388
        // legacy
 
389
        return u.markCurrentBootSuccessfulLegacy(u.currentRootfs)
 
390
}
 
391
 
320
392
// Write lines to file atomically. File does not have to preexist.
321
393
// FIXME: put into utils package
322
394
func atomicFileUpdateImpl(file string, lines []string) (err error) {