From 65eecf4cef29ca48602cc320b0c534830327134c 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 | 4 ++++ pkg/daemon/update.go | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go index 8247a123e0..00e04bca71 100644 --- a/pkg/daemon/daemon.go +++ b/pkg/daemon/daemon.go @@ -1054,6 +1054,10 @@ func (dn *Daemon) RunFirstbootCompleteMachineconfig() error { // it, reflecting the current machine state. oldConfig := canonicalizeEmptyMC(nil) oldConfig.Spec.OSImageURL = dn.bootedOSImageURL + if err = mergeRunningKargs(oldConfig, mc.Spec.KernelArguments); err != nil { + return fmt.Errorf("failed to merge kernel arguments: %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..c4c797ca71 100644 --- a/pkg/daemon/update.go +++ b/pkg/daemon/update.go @@ -122,6 +122,24 @@ func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string return dn.triggerUpdateWithMachineConfig(state.currentConfig, state.desiredConfig, true) } +func mergeRunningKargs(config *mcfgv1.MachineConfig, requestedKargs []string) error { + b, err := os.ReadFile("/proc/cmdline") + if err != nil { + return err + } + splits := strings.Split(strings.TrimSpace(string(b)), " ") + 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