From 7fa9f3954dd64d169b4f9d9b5a2fe89f0c71742b Mon Sep 17 00:00:00 2001 From: Ori Amizur Date: Tue, 15 Aug 2023 11:52:02 +0300 Subject: [PATCH] MCO-708: Extract and merge kernel arguments from /proc/cmdline In firstboot MCO checks if reboot can be skipped. In order for reboot to be skipped, the kernel arguments of the current (booted) system and the expected system need to match. Currently, in firstboot the list of the current kargs is assumed to be empty. To reflect the actual list of arguments the system was booted with, this change extracts the set of booted kargs from /proc/cmdline to be used for comparison. Only kargs that appear both in the requested kargs and /proc/cmdline are used for comparison. --- pkg/daemon/daemon.go | 7 +++++++ pkg/daemon/update.go | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go index 8247a123e0..910b6fe824 100644 --- a/pkg/daemon/daemon.go +++ b/pkg/daemon/daemon.go @@ -1054,6 +1054,13 @@ func (dn *Daemon) RunFirstbootCompleteMachineconfig() error { // it, reflecting the current machine state. oldConfig := canonicalizeEmptyMC(nil) oldConfig.Spec.OSImageURL = dn.bootedOSImageURL + + // Setting the Kernel Arguments is for comparison with the desired MachineConfig. + // The resulting MC should not be used as the actual running configuration. + if err = setRunningKargs(oldConfig, mc.Spec.KernelArguments); err != nil { + return fmt.Errorf("failed to set kernel arguments from /proc/cmdline: %w", err) + } + // Currently, we generally expect the bootimage to be older, but in the special // case of having bootimage == machine-os-content, and no kernel arguments // specified, then we don't need to do anything here. diff --git a/pkg/daemon/update.go b/pkg/daemon/update.go index 53b2eb36e8..ea1ab97018 100644 --- a/pkg/daemon/update.go +++ b/pkg/daemon/update.go @@ -122,6 +122,25 @@ func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string return dn.triggerUpdateWithMachineConfig(state.currentConfig, state.desiredConfig, true) } +func setRunningKargs(config *mcfgv1.MachineConfig, requestedKargs []string) error { + b, err := os.ReadFile("/proc/cmdline") + if err != nil { + return err + } + splits := strings.Split(strings.TrimSpace(string(b)), " ") + config.Spec.KernelArguments = nil + for _, split := range splits { + for _, reqKarg := range requestedKargs { + if strings.ReplaceAll(reqKarg, "\"", "") == strings.ReplaceAll(split, "\"", "") { + config.Spec.KernelArguments = append(config.Spec.KernelArguments, reqKarg) + break + } + } + } + logSystem("requested kargs: %+v, merged kargs: %+v", requestedKargs, config.Spec.KernelArguments) + return nil +} + func canonicalizeEmptyMC(config *mcfgv1.MachineConfig) *mcfgv1.MachineConfig { if config != nil { return config