2019-09-26 09:27:05 +02:00
|
|
|
// -*- Mode: Go; indent-tabs-mode: t -*-
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2019 Canonical Ltd
|
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License version 3 as
|
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package boot
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
2021-02-19 14:48:39 +01:00
|
|
|
"strings"
|
2019-09-26 09:27:05 +02:00
|
|
|
|
|
|
|
|
"github.com/snapcore/snapd/bootloader"
|
2020-09-22 13:58:17 +02:00
|
|
|
"github.com/snapcore/snapd/dirs"
|
|
|
|
|
"github.com/snapcore/snapd/osutil"
|
2019-09-26 09:27:05 +02:00
|
|
|
)
|
|
|
|
|
|
2021-02-19 14:48:39 +01:00
|
|
|
// DebugDumpBootVars writes a dump of the snapd bootvars to the given writer
|
|
|
|
|
func DebugDumpBootVars(w io.Writer, dir string, uc20 bool) error {
|
2020-09-22 10:37:21 +02:00
|
|
|
opts := &bootloader.Options{
|
|
|
|
|
NoSlashBoot: dir != "" && dir != "/",
|
|
|
|
|
}
|
|
|
|
|
switch dir {
|
|
|
|
|
// is it any of the well-known UC20 boot partition mount locations?
|
|
|
|
|
case InitramfsUbuntuBootDir:
|
|
|
|
|
opts.Role = bootloader.RoleRunMode
|
|
|
|
|
uc20 = true
|
|
|
|
|
case InitramfsUbuntuSeedDir:
|
|
|
|
|
opts.Role = bootloader.RoleRecovery
|
|
|
|
|
uc20 = true
|
|
|
|
|
}
|
2020-09-22 13:58:17 +02:00
|
|
|
if !opts.NoSlashBoot && !uc20 {
|
|
|
|
|
// this may still be a UC20 system
|
|
|
|
|
if osutil.FileExists(dirs.SnapModeenvFile) {
|
|
|
|
|
uc20 = true
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-22 10:37:21 +02:00
|
|
|
allKeys := []string{
|
|
|
|
|
"snap_mode",
|
|
|
|
|
"snap_core",
|
|
|
|
|
"snap_try_core",
|
|
|
|
|
"snap_kernel",
|
|
|
|
|
"snap_try_kernel",
|
|
|
|
|
}
|
|
|
|
|
if uc20 {
|
|
|
|
|
if !opts.NoSlashBoot {
|
2021-02-22 12:35:28 +01:00
|
|
|
// no root directory set, default to run mode
|
2020-09-22 10:37:21 +02:00
|
|
|
opts.Role = bootloader.RoleRunMode
|
|
|
|
|
}
|
|
|
|
|
// keys relevant to all uc20 bootloader implementations
|
|
|
|
|
allKeys = []string{
|
|
|
|
|
"snapd_recovery_mode",
|
|
|
|
|
"snapd_recovery_system",
|
|
|
|
|
"snapd_recovery_kernel",
|
|
|
|
|
"snap_kernel",
|
2021-02-23 14:24:34 +01:00
|
|
|
"snap_try_kernel",
|
2020-09-22 10:37:21 +02:00
|
|
|
"kernel_status",
|
2021-02-19 14:23:25 +01:00
|
|
|
"recovery_system_status",
|
|
|
|
|
"try_recovery_system",
|
2021-10-01 15:31:17 +02:00
|
|
|
"snapd_good_recovery_systems",
|
2021-04-07 16:21:44 +02:00
|
|
|
"snapd_extra_cmdline_args",
|
2021-04-15 09:14:29 +02:00
|
|
|
"snapd_full_cmdline_args",
|
2020-09-22 10:37:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bloader, err := bootloader.Find(dir, opts)
|
2019-09-26 09:27:05 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2020-04-13 15:02:13 -05:00
|
|
|
|
2019-09-26 09:27:05 +02:00
|
|
|
bootVars, err := bloader.GetBootVars(allKeys...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
for _, k := range allKeys {
|
|
|
|
|
fmt.Fprintf(w, "%s=%s\n", k, bootVars[k])
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2021-02-19 14:48:39 +01:00
|
|
|
|
|
|
|
|
// DebugSetBootVars is a debug helper that takes a list of <var>=<value> entries
|
|
|
|
|
// and sets them for the configured bootloader.
|
2021-02-23 15:41:32 +01:00
|
|
|
func DebugSetBootVars(dir string, recoveryBootloader bool, varEqVal []string) error {
|
2021-02-19 14:48:39 +01:00
|
|
|
opts := &bootloader.Options{
|
|
|
|
|
NoSlashBoot: dir != "" && dir != "/",
|
|
|
|
|
}
|
2021-02-23 15:41:32 +01:00
|
|
|
if opts.NoSlashBoot || osutil.FileExists(dirs.SnapModeenvFile) {
|
|
|
|
|
// implied UC20 bootloader
|
|
|
|
|
opts.Role = bootloader.RoleRunMode
|
|
|
|
|
}
|
|
|
|
|
// try some well known UC20 root dirs
|
2021-02-19 14:48:39 +01:00
|
|
|
switch dir {
|
|
|
|
|
case InitramfsUbuntuBootDir:
|
2021-02-23 15:41:32 +01:00
|
|
|
if recoveryBootloader {
|
|
|
|
|
return fmt.Errorf("cannot use run bootloader root-dir with a recovery flag")
|
|
|
|
|
}
|
2021-02-19 14:48:39 +01:00
|
|
|
opts.Role = bootloader.RoleRunMode
|
|
|
|
|
case InitramfsUbuntuSeedDir:
|
|
|
|
|
opts.Role = bootloader.RoleRecovery
|
|
|
|
|
}
|
2021-02-24 13:00:50 +01:00
|
|
|
if recoveryBootloader {
|
|
|
|
|
// UC20 recovery bootloader
|
|
|
|
|
opts.Role = bootloader.RoleRecovery
|
|
|
|
|
if !opts.NoSlashBoot {
|
|
|
|
|
// no root dir was provided, use the default one for a
|
|
|
|
|
// recovery bootloader
|
|
|
|
|
dir = InitramfsUbuntuSeedDir
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-02-19 14:48:39 +01:00
|
|
|
bloader, err := bootloader.Find(dir, opts)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toSet := map[string]string{}
|
|
|
|
|
|
|
|
|
|
for _, req := range varEqVal {
|
|
|
|
|
split := strings.SplitN(req, "=", 2)
|
|
|
|
|
if len(split) != 2 {
|
|
|
|
|
return fmt.Errorf("incorrect setting %q", varEqVal)
|
|
|
|
|
}
|
|
|
|
|
toSet[split[0]] = split[1]
|
|
|
|
|
}
|
|
|
|
|
return bloader.SetBootVars(toSet)
|
|
|
|
|
}
|