summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/defaults.py8
-rw-r--r--python/vyos/utils/boot.py1
-rw-r--r--python/vyos/utils/kernel.py70
-rw-r--r--python/vyos/utils/memory.py28
4 files changed, 107 insertions, 0 deletions
diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py
index 5829b859f..854f95ff0 100644
--- a/python/vyos/defaults.py
+++ b/python/vyos/defaults.py
@@ -49,6 +49,7 @@ systemd_services = {
'openconnect': 'ocserv.service',
'syslog' : 'syslog.service',
'snmpd' : 'snmpd.service',
+ 'kdump': 'kdump-tools.service',
}
internal_ports = {
@@ -115,3 +116,10 @@ config_sync_exclusion_list = os.path.join(
# Sits between the l3mdev rule (1000) and the l3mdev unreachable rule (2000),
# ensuring fwmark-tagged tunnel packets are routed into the correct VRF table.
wireguard_fwmark_pref = '1998'
+
+# Tiered auto-sizing based on total system RAM, determined by
+# empirical testing across representative VyOS deployments:
+# 1G - 8G RAM -> reserve 512M
+# 8G - 64G RAM -> reserve 768M
+# 64G+ RAM -> reserve 1G
+KDUMP_DEFAULT_MEMORY_AUTO = '1G-8G:512M,8G-64G:768M,64G-:1G'
diff --git a/python/vyos/utils/boot.py b/python/vyos/utils/boot.py
index f804cd94e..dc6fcd408 100644
--- a/python/vyos/utils/boot.py
+++ b/python/vyos/utils/boot.py
@@ -15,6 +15,7 @@
import os
+
def boot_configuration_complete() -> bool:
""" Check if the boot config loader has completed
"""
diff --git a/python/vyos/utils/kernel.py b/python/vyos/utils/kernel.py
index 726025605..69574cefc 100644
--- a/python/vyos/utils/kernel.py
+++ b/python/vyos/utils/kernel.py
@@ -17,10 +17,18 @@ import os
from typing import Tuple
from typing import Optional
+from vyos.utils.file import read_file
+
# A list of used Kernel constants
# https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/wireguard/messages.h?h=linux-6.6.y#n45
WIREGUARD_REKEY_AFTER_TIME = 120
+CMDLINE_PATH = '/proc/cmdline'
+
+# Kernel interface files exposing crash kernel state at runtime
+KEXEC_CRASH_LOADED = '/sys/kernel/kexec_crash_loaded'
+KEXEC_CRASH_SIZE = '/sys/kernel/kexec_crash_size'
+
def load_module(name: str, quiet: bool = True, dry_run: bool = False) -> int:
"""Load a kernel module via modprobe.
@@ -172,3 +180,65 @@ def get_kernel_serial_console() -> Tuple[Optional[str], Optional[str], Optional[
)
return (None, None, None)
+
+
+def get_kernel_boot_arg(argument=None) -> str | None:
+ """Read and parse kernel boot arguments from the kernel command line.
+
+ Args:
+ argument: The name of a specific boot argument to look up (e.g.
+ 'crashkernel'). If omitted or None, the full raw command
+ line string is returned.
+
+ Returns:
+ If argument is None: the full kernel command line string.
+ If argument is given: the value of that argument (the part after '='),
+ or None if the argument is not present on the command line.
+
+ Examples:
+ >>> get_kernel_boot_arg()
+ 'ro quiet crashkernel=256M console=tty0'
+
+ >>> get_kernel_boot_arg('crashkernel')
+ '256M'
+
+ >>> get_kernel_boot_arg('quiet')
+ ''
+
+ >>> get_kernel_boot_arg('nonexistent')
+ None
+ """
+ cmdline = read_file(CMDLINE_PATH)
+ if not argument:
+ return cmdline
+
+ # Kernel arguments with values are formatted as 'key=value' tokens
+ # separated by spaces. Build the prefix to match against:
+ key = f'{argument}='
+
+ # Kernel parses the command line from left to right.
+ # A later argument will overwrite an earlier one.
+ for part in reversed(cmdline.split()):
+ if part.startswith(key):
+ # Strip the 'key=' prefix and return only the value portion
+ return part[len(key) :]
+ elif part == argument:
+ # Statement without value portion should be return empty string
+ return ''
+
+ return None
+
+
+def is_crash_kernel_loaded() -> bool:
+ """Return True when a capture kernel is currently loaded via kexec"""
+ return read_file(KEXEC_CRASH_LOADED, defaultonfailure='0') == '1'
+
+
+def get_crash_kernel_size() -> int:
+ """Return the number of bytes reserved for the capture kernel"""
+
+ if not is_crash_kernel_loaded():
+ return 0
+
+ raw = read_file(KEXEC_CRASH_SIZE, defaultonfailure='0')
+ return int(raw) if raw.isdigit() else 0
diff --git a/python/vyos/utils/memory.py b/python/vyos/utils/memory.py
new file mode 100644
index 000000000..c279168b5
--- /dev/null
+++ b/python/vyos/utils/memory.py
@@ -0,0 +1,28 @@
+# Copyright (C) VyOS Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+from vyos.utils.file import read_file
+
+
+def get_memory_info() -> dict:
+ """Returns system memory information parsed from /proc/meminfo"""
+ data = read_file('/proc/meminfo')
+
+ result = {}
+ regex = r'^(?P<key>\S+):\s+(?P<value>[0-9]+)\s+kB\s*$'
+ for match in re.finditer(regex, data, flags=re.MULTILINE):
+ result[match['key']] = int(match['value'])
+
+ return result