diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/vyos/defaults.py | 8 | ||||
| -rw-r--r-- | python/vyos/utils/boot.py | 1 | ||||
| -rw-r--r-- | python/vyos/utils/kernel.py | 70 | ||||
| -rw-r--r-- | python/vyos/utils/memory.py | 28 |
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 |
