Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions scripts/hostcfgd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"]
Expand Down
25 changes: 25 additions & 0 deletions tests/hostcfgd/hostcfgd_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions tests/proc/cmdline
Original file line number Diff line number Diff line change
@@ -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
Loading