fix: upgrades with kexec

Fix by setting the default booted entry as like sd-boot.

Fixes: #10577

Signed-off-by: Noel Georgi <git@frezbo.dev>
This commit is contained in:
Noel Georgi 2025-03-21 09:47:23 +05:30
parent bf80079d4e
commit 8f918a34e1
No known key found for this signature in database
GPG Key ID: 21A9F444075C9E36
3 changed files with 20 additions and 66 deletions

View File

@ -5,72 +5,22 @@
package install
import (
"bytes"
"compress/gzip"
"context"
"fmt"
"io"
"log"
"os"
"runtime"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
pkgkernel "github.com/siderolabs/talos/pkg/kernel"
"github.com/siderolabs/talos/pkg/machinery/client"
"github.com/siderolabs/talos/pkg/machinery/compatibility"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/kernel"
"github.com/siderolabs/talos/pkg/machinery/role"
)
// errataArm64ZBoot handles the case when upgrading from Talos < 1.8.0 on arm64 to compressed kernel.
func errataArm64ZBoot() {
if runtime.GOARCH != "arm64" {
return
}
oldConfig, err := os.OpenFile("/proc/config.gz", os.O_RDONLY, 0)
if err != nil {
log.Printf("failed to open /proc/config.gz: %s", err)
return
}
defer oldConfig.Close() //nolint:errcheck
r, err := gzip.NewReader(oldConfig)
if err != nil {
log.Printf("failed to read /proc/config.gz: %s", err)
return
}
contents, err := io.ReadAll(r)
if err != nil {
log.Printf("failed to read /proc/config.gz: %s", err)
return
}
if bytes.Contains(contents, []byte("CONFIG_ARM64_ZBOOT=y")) {
// nothing to do
return
}
log.Printf("disabling kexec due to upgrade to the compressed kernel")
if err = pkgkernel.WriteParam(&kernel.Param{
Key: "proc.sys.kernel.kexec_load_disabled",
Value: "1",
}); err != nil {
log.Printf("failed to disable kexec: %s", err)
}
}
// errataNetIfnames appends the `net.ifnames=0` kernel parameter to the kernel command line if upgrading
// from an old enough version of Talos.
func (i *Installer) errataNetIfnames(talosVersion *compatibility.TalosVersion) {

View File

@ -240,8 +240,6 @@ func (i *Installer) Install(ctx context.Context, mode Mode) (err error) {
}
if mode == ModeUpgrade {
errataArm64ZBoot()
i.errataNetIfnames(hostTalosVersion)
}

View File

@ -77,16 +77,18 @@ func ProbeWithCallback(disk string, options options.ProbeOptions, callback func(
// here we need to read the EFI vars to see if we have any defaults
// and populate config accordingly
// https://www.freedesktop.org/software/systemd/man/systemd-boot.html#LoaderEntryDefault
// this should be set on install/upgrades
// https://www.freedesktop.org/software/systemd/man/latest/systemd-boot.html#LoaderEntryDefault
// this is set by systemd-boot.
efiCtx := efivario.NewDefaultContext()
bootedEntry, err := ReadVariable(efiCtx, LoaderEntrySelectedName)
// first we start by checking if we have a Default entry
// this is set by installer
bootedEntry, err := ReadVariable(efiCtx, LoaderEntryDefaultName)
if err != nil {
return nil, err
}
config := &Config{}
var sdbootConf *Config
// read /boot/EFI and find if sd-boot is already being used
// this is to make sure sd-boot from Talos is being used and not sd-boot from another distro
@ -116,20 +118,24 @@ func ProbeWithCallback(disk string, options options.ProbeOptions, callback func(
return err
}
for _, ukiFile := range ukiFiles {
if strings.EqualFold(filepath.Base(ukiFile), bootedEntry) {
config.Default = bootedEntry
// here we handle a case when we boot of just kernel+initrd/uki/iso and we don't have a booted entry
// then we know we're booted of UKI
if bootedEntry == "" && len(ukiFiles) == 1 {
sdbootConf = &Config{
Default: filepath.Base(ukiFiles[0]),
}
}
// here we handle a case when we boot of just kernel+initrd/uki and we don't have a booted entry
if bootedEntry == "" && len(ukiFiles) == 1 {
// we have only one UKI, so we can assume it's the default
config.Default = filepath.Base(ukiFiles[0])
for _, ukiFile := range ukiFiles {
if strings.EqualFold(filepath.Base(ukiFile), bootedEntry) {
sdbootConf = &Config{
Default: bootedEntry,
}
}
}
if callback != nil {
return callback(config)
if sdbootConf != nil && callback != nil {
return callback(sdbootConf)
}
return nil
@ -150,7 +156,7 @@ func ProbeWithCallback(disk string, options options.ProbeOptions, callback func(
return nil, err
}
return config, nil
return sdbootConf, nil
}
// Probe for existing sd-boot bootloader.