diff --git a/scripts/hostcfgd b/scripts/hostcfgd index cedafcd9..ab017ee0 100644 --- a/scripts/hostcfgd +++ b/scripts/hostcfgd @@ -1137,6 +1137,40 @@ class KdumpCfg(object): "memory": "0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M", "num_dumps": "3" } + # check if kdump is enabled by default with grub config + self.update_config_from_proc_cmdline = False + self.init_kdump_config_from_cmdline() + + def init_kdump_config_from_cmdline(self): + # Update the kdump_defaults with value found /proc/cmdline if + # key "crashkernel=" is pre-defined in and /proc/cmdline (grub.conf) + if os.environ.get("HOSTCFGD_UNIT_TESTING") == "2": + modules_path = os.path.join(os.path.dirname(__file__), "..") + tests_path = os.path.join(modules_path, "tests") + cmdline = os.path.join(tests_path, "proc","cmdline") + else: + cmdline = "/proc/cmdline" + + expected_str = ' crashkernel=' + if os.path.exists(cmdline): + lines= [line.rstrip('\n') for line in open(cmdline)] + p = lines[0].find(expected_str) + if p == -1: + return + kdump_config = self.config_db.get_entry("KDUMP", "config") + syslog.syslog(syslog.LOG_INFO, "kdump enabled is found in /proc/cmdline") + self.kdump_defaults["enabled"] = "true" + next_space = lines[0].find(" ", p+1) + if next_space == -1: + memory = lines[0][p+len(expected_str):] + else: + memory = lines[0][p+len(expected_str):next_space] + self.kdump_defaults["memory"] = memory + if not kdump_config or kdump_config.get("enabled") != self.kdump_defaults["enabled"] or kdump_config.get("memory") != self.kdump_defaults["memory"]: + self.update_config_from_proc_cmdline = True + syslog.syslog(syslog.LOG_INFO, "Update KDUMP config entry with data from /proc/cmdline") + self.config_db.mod_entry("KDUMP", "config", self.kdump_defaults) + def load(self, kdump_table): """ Set the KDUMP table in CFG DB to kdump_defaults if not set by the user @@ -1155,6 +1189,10 @@ class KdumpCfg(object): def kdump_update(self, key, data): syslog.syslog(syslog.LOG_INFO, "Kdump global configuration update") + if self.update_config_from_proc_cmdline and os.environ.get("HOSTCFGD_UNIT_TESTING") != "2": + self.update_config_from_proc_cmdline = False + syslog.syslog(syslog.LOG_INFO, "Kdump is enabled by default with /proc/cmdline. Skip the first update") + return if key == "config": # Admin mode kdump_enabled = self.kdump_defaults["enabled"] diff --git a/tests/hostcfgd/hostcfgd_test.py b/tests/hostcfgd/hostcfgd_test.py index 2c9c03da..dd23247d 100644 --- a/tests/hostcfgd/hostcfgd_test.py +++ b/tests/hostcfgd/hostcfgd_test.py @@ -236,6 +236,31 @@ def test_kdump_load(self): mocked_subprocess.check_call.assert_has_calls(expected, any_order=True) + def test_kdump_event_with_proc_cmdline(self): + os.environ["HOSTCFGD_UNIT_TESTING"] = "2" + MockConfigDb.set_config_db(HOSTCFG_DAEMON_CFG_DB) + daemon = hostcfgd.HostConfigDaemon() + default=daemon.kdumpCfg.kdump_defaults + daemon.kdumpCfg.load(default) + daemon.register_callbacks() + MockConfigDb.event_queue = [('KDUMP', 'config')] + with mock.patch('hostcfgd.subprocess') as mocked_subprocess: + popen_mock = mock.Mock() + attrs = {'communicate.return_value': ('output', 'error')} + popen_mock.configure_mock(**attrs) + mocked_subprocess.Popen.return_value = popen_mock + try: + daemon.start() + except TimeoutError: + pass + expected = [ + call(['sonic-kdump-config', '--enable']), + call(['sonic-kdump-config', '--num_dumps', '3']), + call(['sonic-kdump-config', '--memory', '8G-:1G']) + ] + mocked_subprocess.check_call.assert_has_calls(expected, any_order=True) + os.environ["HOSTCFGD_UNIT_TESTING"] = "" + def test_devicemeta_event(self): """ Test handling DEVICE_METADATA events. diff --git a/tests/proc/cmdline b/tests/proc/cmdline new file mode 100644 index 00000000..ddfc9197 --- /dev/null +++ b/tests/proc/cmdline @@ -0,0 +1 @@ +BOOT_IMAGE=/image-202405.0-dirty-20250403.162657/boot/vmlinuz-6.1.0-22-2-amd64 root=UUID=bba2ec4f-9141-4069-a41e-230ecac4a5fb rw console=tty0 console=ttyS0,115200n8 quiet processor.max_cstate=1 amd_idle.max_cstate=0 sonic_fips=1 net.ifnames=0 biosdevname=0 loop=image-202405.0-dirty-20250403.162657/fs.squashfs loopfstype=squashfs systemd.unified_cgroup_hierarchy=0 apparmor=1 security=apparmor varlog_size=4096 usbcore.autosuspend=-1 amd_iommu=off pci=resource_alignment=48@00:03.1 crashkernel=8G-:1G \ No newline at end of file