Skip to content

libvirt_mem: Add vhost configuration for SLES - #6886

Open
sneh-3 wants to merge 1 commit into
autotest:masterfrom
sneh-3:fix_vhost_backend
Open

sneh-3 wants to merge 1 commit into
autotest:masterfrom
sneh-3:fix_vhost_backend

Conversation

@sneh-3

@sneh-3 sneh-3 commented Jun 15, 2026

Copy link
Copy Markdown
  1. Enhanced memory hotplug testing with conditional vhost parameter configuration for SLES systems.
  2. Added automatic kernel module management and configuration verification for improved test reliability on SLES environments.

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling for memory-related test setup on SLES systems, reducing failures when virtual machines are already running.
    • Added safer checks so the test skips configuration changes when the system state can’t be verified, helping avoid disruptive changes during execution.
    • Strengthened validation of runtime settings before continuing with memory hotplug and domain configuration steps.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

A new inner helper setup_vhost_max_mem_regions() is added in libvirt_mem.py. It checks for SLES via /etc/os-release, skips if running libvirt domains are detected, reloads vhost-related modules with max_mem_regions=512, and verifies the setting through /sys/module/vhost/parameters/max_mem_regions when possible. The helper is called immediately after vm.destroy() before the memory hotplug and domain XML setup continues.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding SLES-specific vhost configuration in libvirt_mem.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@libvirt/tests/src/libvirt_mem.py`:
- Around line 148-166: The verification failure for vhost max_mem_regions
configuration and the exception handler are downgrading setup errors to
warnings, allowing the test to continue in an invalid state. When verification
confirms the value is not set to "512" (around line 155-156), raise an exception
instead of just logging a warning. In the exception handler (around line
165-166), re-raise the caught exception instead of logging a warning and
continuing, so that SLES-targeted setup failures properly fail or cancel the
test path rather than silently proceeding.
- Around line 135-137: The current pipeline in the vm_check assignment combines
virsh and grep in a single command, which means the exit_status will reflect
grep's result rather than virsh's failure. If virsh list fails but grep runs
against empty output without error, the condition will incorrectly assess the
situation as safe to proceed. Split the command execution into two separate
steps: first run virsh list --state-running independently and check its exit
status, then only proceed to parse the output with grep if virsh succeeds. This
ensures virsh failures are explicitly caught before attempting to process
output.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 246a485b-d09a-43c6-957c-b8ee9d1ddada

📥 Commits

Reviewing files that changed from the base of the PR and between c96ab65 and 4f34ef4.

📒 Files selected for processing (1)
  • libvirt/tests/src/libvirt_mem.py

Comment thread libvirt/tests/src/libvirt_mem.py Outdated
Comment thread libvirt/tests/src/libvirt_mem.py Outdated
@sneh-3
sneh-3 force-pushed the fix_vhost_backend branch from 4f34ef4 to 4c8ae26 Compare July 1, 2026 17:22

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
libvirt/tests/src/libvirt_mem.py (3)

131-134: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer a proper distro-detection API over shelling out to cat/grep on /etc/os-release.

avocado.utils.distro.detect() provides structured Linux-distro detection and avoids the fragile substring match on /etc/os-release (which could theoretically hit ID_LIKE/PRETTY_NAME false positives, e.g. SLES-based derivatives).

♻️ Proposed refactor
+from avocado.utils import distro
+
     def setup_vhost_max_mem_regions():
         ...
         try:
-            # Check if running on SLES
-            distro_check = process.run("cat /etc/os-release | grep -i sles",
-                                      shell=True, ignore_status=True)
-            if distro_check.exit_status == 0:
+            detected_distro = distro.detect()
+            if "sles" in detected_distro.name.lower():

Please confirm avocado.utils.distro.detect() is available/appropriate for this test's target Avocado version before adopting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libvirt/tests/src/libvirt_mem.py` around lines 131 - 134, The SLES detection
in the test currently shells out to `cat`/`grep` against `/etc/os-release`,
which is fragile and can match unintended fields. Replace that logic in the
`libvirt_mem` test with Avocado’s structured distro detection via
`avocado.utils.distro.detect()`, and use its returned distro info to decide
whether to log the SLES-specific `max_mem_regions=512` message. Make sure
`detect()` is available in the Avocado version targeted by this test before
switching the existing `process.run` check.

135-150: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

TOCTOU window between the "no running VMs" check and the module reload.

Between the virsh list --state-running check (lines 135-144) and the modprobe -r/reload (lines 147-150), another process could start a domain that depends on vhost, causing the unload to disrupt it. This is a narrow race in practice for a single-threaded test harness, so treat as a minor hardening opportunity rather than a blocker.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libvirt/tests/src/libvirt_mem.py` around lines 135 - 150, The vhost
reconfiguration in the running-VM check has a small TOCTOU race between the
`virsh list --state-running` validation and the `modprobe` unload/reload
sequence. Harden `libvirt_mem` by rechecking for active VMs immediately before
calling the `process.run` module removal/reload steps, and skip the
configuration if any are detected; use the existing `vm_check`, `running_vms`,
and `process.run` flow to keep the fix localized.

119-172: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Vhost module change is never reverted; persists beyond this test.

setup_vhost_max_mem_regions() unloads and reloads vhost/vhost_net/vhost_scsi/vhost_vsock with max_mem_regions=512 for the whole boot session, but run()'s finally block (lines 837-851) has no matching step to restore the previous module state. Any other test or process on the same host that runs afterward will silently inherit this modified vhost parameter instead of the distro default, which is easy to misdiagnose in shared/CI infrastructure.

Consider restoring the module (unload/reload without max_mem_regions, or track/restore the previous value) in the finally block, mirroring how restore_hugepages() undoes setup_hugepages().

Also applies to: 837-851

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libvirt/tests/src/libvirt_mem.py` around lines 119 - 172, The vhost runtime
tweak in setup_vhost_max_mem_regions is not reverted, so the modified
max_mem_regions value leaks into later tests on the same host. Add matching
cleanup in run()’s finally block to restore the prior vhost module state, either
by unloading/reloading the vhost modules without the override or by saving and
restoring the original parameter value. Use the existing
setup_vhost_max_mem_regions helper as the place to capture state and mirror
restore_hugepages-style teardown in run().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@libvirt/tests/src/libvirt_mem.py`:
- Around line 131-134: The SLES detection in the test currently shells out to
`cat`/`grep` against `/etc/os-release`, which is fragile and can match
unintended fields. Replace that logic in the `libvirt_mem` test with Avocado’s
structured distro detection via `avocado.utils.distro.detect()`, and use its
returned distro info to decide whether to log the SLES-specific
`max_mem_regions=512` message. Make sure `detect()` is available in the Avocado
version targeted by this test before switching the existing `process.run` check.
- Around line 135-150: The vhost reconfiguration in the running-VM check has a
small TOCTOU race between the `virsh list --state-running` validation and the
`modprobe` unload/reload sequence. Harden `libvirt_mem` by rechecking for active
VMs immediately before calling the `process.run` module removal/reload steps,
and skip the configuration if any are detected; use the existing `vm_check`,
`running_vms`, and `process.run` flow to keep the fix localized.
- Around line 119-172: The vhost runtime tweak in setup_vhost_max_mem_regions is
not reverted, so the modified max_mem_regions value leaks into later tests on
the same host. Add matching cleanup in run()’s finally block to restore the
prior vhost module state, either by unloading/reloading the vhost modules
without the override or by saving and restoring the original parameter value.
Use the existing setup_vhost_max_mem_regions helper as the place to capture
state and mirror restore_hugepages-style teardown in run().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7bbaf632-e271-4648-9cd4-6cbc5ec5b4b2

📥 Commits

Reviewing files that changed from the base of the PR and between 4f34ef4 and 4c8ae26.

📒 Files selected for processing (1)
  • libvirt/tests/src/libvirt_mem.py

@sneh-3

sneh-3 commented Jul 1, 2026

Copy link
Copy Markdown
Author

before fix:
(114/413) type_specific.io-github-autotest-libvirt.libvirt_mem.positive_test.memory.hot.plug.max_slots.without_reboot: FAIL: error: Failed to attach device from /var/tmp/xml_utils_temp_lmk15107.xml\nerror: internal error: unable to execute QEMU command 'device_add': a used vhost backend has not enough free memory slots left\n (34.58 s)

after fix:
(1/1) type_specific.io-github-autotest-libvirt.libvirt_mem.positive_test.memory.hot.plug.max_slots.without_reboot: STARTED
(1/1) type_specific.io-github-autotest-libvirt.libvirt_mem.positive_test.memory.hot.plug.max_slots.without_reboot: PASS (177.27 s)
RESULTS : PASS 1 | ERROR 0 | FAIL 0 |

@hholoubk hholoubk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several things that can be better, some of them kind of severe, some just unoptimized.

The main issue is, that test is changing host configuration and not recovering the environement after.

Commited changes will run regardless they are needed.

Suggested changes:

  1. Use the avocado cfg file to change the configuration of host only in cases that really need it.
  2. Do not hardcode set value, introduce the flag if it should be set in the test and the value, that should be set.
  3. move the check (if the value should be done) outside the setter method
  4. backup the value and recover it at the end of the test
  5. reconsider if the test shouldn't be canceled in case that there is any running VM.

Comment thread libvirt/tests/src/libvirt_mem.py Outdated
"""
try:
# Check if running on SLES
distro_check = process.run("cat /etc/os-release | grep -i sles",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use avocado method to check the distro

already used in virsh_dump.py, libvirt_pci_passthrough_hotplug.py, etc.:

from avocado.utils import distro
detected = distro.detect()
if detected.name.lower() in ("suse", "sles"):

BUT
... there is better way how to do it via configuration.

Comment thread libvirt/tests/src/libvirt_mem.py Outdated
# Check if running on SLES
distro_check = process.run("cat /etc/os-release | grep -i sles",
shell=True, ignore_status=True)
if distro_check.exit_status == 0:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is wrong approach mixing os detection into the value setting. Please move the whole detection outside (into the test run)

so the row will be

if detected.name.lower() in ("suse", "sles"):
     setup_vhost_max_mem_regions()

Comment thread libvirt/tests/src/libvirt_mem.py Outdated
Comment thread libvirt/tests/src/libvirt_mem.py Outdated
logging.info("No running VMs detected, proceeding with vhost configuration")
process.run("modprobe -r vhost_net vhost_scsi vhost_vsock vhost",
shell=True, ignore_status=True)
result = process.run("modprobe vhost max_mem_regions=512",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setting this value regardless what is actually set on the host is not good approach ...

Also setting the value without storing it and recover to previous value to return the host in same configuration as before the test is against best practices.

  1. store actual value
  2. check if it is lower than what you want
current = process.run(cmd, shell=True).stdout_text.strip()
needed = int(params.get("vhost_max_mem_regions", 512))
if current < needed:
    # do the setting

return current

restore later in finally of run test.

Comment thread libvirt/tests/src/libvirt_mem.py Outdated
1. check the running dostro and vm state
2. configures vhost max_mem_regions

v2: fixed vhost max_mem_regions setup based on review comments
- Removed OS detection from setup_vhost_max_mem_regions()
- Introduced set_vhost_max_mem_regions flag in cfg to control when the
  setup runs
- Make the value configurable via vhost_max_mem_regions param in cfg
- Restore original vhost max_mem_regions in finally block

Signed-off-by: Sneh Shikha Yadav <syadav@linux.ibm.com>
@sneh-3
sneh-3 requested a review from hholoubk September 4, 2026 11:16
@sneh-3

sneh-3 commented Sep 5, 2026

Copy link
Copy Markdown
Author

--logs--
(1/1) type_specific.io-github-autotest-libvirt.libvirt_mem.positive_test.memory.hot.plug.max_slots.without_reboot: STARTED
(1/1) type_specific.io-github-autotest-libvirt.libvirt_mem.positive_test.memory.hot.plug.max_slots.without_reboot: PASS (152.88 s)
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants