Skip to content

Commit 6561f5e

Browse files
utils_kernel_module: filter out not applicable module parameters
When reading kernel module parameters from sysfs, some parameters may return the string "not required" if they are not applicable, for example module kvm_intel parameter vmentry_l1d_flush. Previously, these values were included in the parameter string passed to modprobe when restoring the module, which leads to module loading failure. This change introduces new parameters "kvm_module_ignored_parameters" and "kvm_probe_module_ignored_parameters", (e.g., "vmentry_l1d_flush=not required") to skip the parameters. Signed-off-by: Liang Cong <lcong@redhat.com>
1 parent a471275 commit 6561f5e

3 files changed

Lines changed: 76 additions & 4 deletions

File tree

virttest/shared/cfg/base.cfg

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,3 +1225,18 @@ uuid_dimm = ""
12251225
# enable_igvm = no
12261226
# igvm_path = /usr/share/coconut-svsm
12271227
# igvm_filename = coconut-qemu.igvm
1228+
1229+
# KVM Module Reload/Restore Settings for Test Pre-processing and Post-processing
1230+
# ---------------------------------------------------------
1231+
# Force reload KVM module
1232+
#kvm_module_force_load = yes
1233+
# Force reload vendor-specific module (kvm_intel/kvm_amd)
1234+
#kvm_probe_module_force_load = yes
1235+
# Parameters for KVM module (e.g., "nested=1")
1236+
#kvm_module_parameters = "nested=1"
1237+
# Parameters for vendor-specific module (e.g., "tdx=1")
1238+
#kvm_probe_module_parameters = "tdx=1"
1239+
# Values to ignore when backing up/restoring KVM module params
1240+
#kvm_module_ignored_parameters = vmentry_l1d_flush=not required
1241+
# Values to ignore when backing up/restoring vendor-specific module (kvm_intel/kvm_amd) params
1242+
#kvm_probe_module_ignored_parameters = vmentry_l1d_flush=not required

virttest/test_setup/kernel.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import re
2+
13
from virttest import arch, test_setup, utils_kernel_module
24
from virttest.test_setup.core import Setuper
35

@@ -7,10 +9,30 @@ def __init__(self, test, params, env):
79
super().__init__(test, params, env)
810
self.kvm_module_handlers = []
911

12+
def _get_param_prefix(self, module_name):
13+
"""Determine parameter prefix based on module name."""
14+
return "kvm" if module_name == "kvm" else "kvm_probe"
15+
16+
def _parse_ignored_params(self, ignored_params):
17+
"""
18+
Parse ignored parameters string into a list of 'key=value' pairs.
19+
20+
:param ignored_params: string contains parameters to ignore
21+
:return: list of 'key=value' strings
22+
"""
23+
ignored_list = []
24+
if not ignored_params:
25+
return ignored_list
26+
27+
pattern = r'(\w+)=(?:["\']([^"\']*)["\']|(.*?))(?=\s+\w+=|$)'
28+
matches = re.findall(pattern, ignored_params)
29+
ignored_list = ["%s=%s" % (k, (q or u).strip()) for k, q, u in matches]
30+
return ignored_list
31+
1032
def setup(self):
1133
kvm_modules = arch.get_kvm_module_list()
1234
for module in reversed(kvm_modules):
13-
param_prefix = module if module == "kvm" else "kvm_probe"
35+
param_prefix = self._get_param_prefix(module)
1436
module_force_load = self.params.get_boolean(
1537
"%s_module_force_load" % param_prefix
1638
)
@@ -25,7 +47,12 @@ def setup(self):
2547

2648
def cleanup(self):
2749
for kvm_module in self.kvm_module_handlers:
28-
kvm_module.restore()
50+
param_prefix = self._get_param_prefix(kvm_module.module_name)
51+
module_ignored_parameters = self.params.get(
52+
"%s_module_ignored_parameters" % param_prefix
53+
)
54+
ignored_list = self._parse_ignored_params(module_ignored_parameters)
55+
kvm_module.restore(ignored_list)
2956

3057

3158
class KSMSetup(Setuper):

virttest/utils_kernel_module.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import logging
2020
import os
21+
import re
2122

2223
from avocado.utils import process
2324

@@ -164,10 +165,26 @@ def reload_module(self, force, params=""):
164165
for holder in self._module_holders:
165166
holder.restore()
166167

167-
def restore(self):
168+
def _remove_key_value_pair(self, original, target):
169+
"""
170+
Remove target key=value pair from a space-separated config string
171+
172+
:param original: source string with space-separated key=value pairs
173+
:param target: specific key=value pair to remove
174+
:return: modified string with the target pair removed if found
175+
"""
176+
177+
pattern = r"(\w+=\S+(?:\s+(?!\w+=)\S+)*)"
178+
parts = re.findall(pattern, original)
179+
result_parts = [p for p in parts if p.strip() != target.strip()]
180+
return " ".join(result_parts)
181+
182+
def restore(self, ignored_params=None):
168183
"""
169184
Restore previous module state.
170185
186+
:param ignored_params: params list to be ignored for module restore
187+
171188
The state will only be restored if the original state
172189
was altered.
173190
@@ -188,9 +205,16 @@ def restore(self):
188205
# TODO: Handle cases were module cannot be removed
189206
self.unload_module()
190207
if self._was_loaded:
208+
restore_config = self._config_backup
209+
if ignored_params:
210+
for param in ignored_params:
211+
restore_config = self._remove_key_value_pair(
212+
restore_config, param
213+
)
214+
LOG.debug("Module restore ignores parameter '%s'.", param)
191215
restore_cmd = "modprobe %s %s" % (
192216
self._module_name,
193-
self._config_backup,
217+
restore_config,
194218
)
195219
LOG.debug("Restoring module state: %s", restore_cmd)
196220
status, output = process.getstatusoutput(restore_cmd)
@@ -217,6 +241,12 @@ def _backup_config(self):
217241
self._config_backup,
218242
)
219243

244+
@property
245+
def module_name(self):
246+
"""Read-only property"""
247+
248+
return self._module_name
249+
220250
@property
221251
def was_loaded(self):
222252
"""Read-only property"""

0 commit comments

Comments
 (0)