From b1cd8728740be876f25dee658e3e1ade62a2c6f8 Mon Sep 17 00:00:00 2001 From: Anushree-Mathur Date: Thu, 13 Aug 2026 19:24:31 +0530 Subject: [PATCH] libvirt_vcpu_plug_unplug: add kdump test after vCPU hotplug/unplug! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test that the guest kernel survives a live vCPU count change by triggering kdump immediately after hotplug and after unplug, then verifying a new vmcore is generated and the guest recovers. libvirt/tests/cfg/libvirt_vcpu_plug_unplug.cfg: Add kdump_after_plug_unplug variant inside positive_test.vcpu_set as a peer of with_maxvcpu, restricted to live + ppc64le/ppc64. Three sub-variants: - hotplug_kdump: plug 4→8 vCPUs, trigger kdump, verify vmcore - unplug_kdump: unplug 8→4 vCPUs, trigger kdump, verify vmcore - plug_and_unplug_kdump: both in sequence on_crash=restart so the guest reboots after kdump capture and the test can log back in to verify the new vmcore. libvirt/tests/src/libvirt_vcpu_plug_unplug.py: Import utils_kdump and read kdump_after_plug_unplug/crash_dir params. After successful hotplug and after successful unplug, call utils_kdump.trigger_crash() with an explicit session (timeout=240) and wait_time=120. Guard the uptime reboot check with 'if not kdump_after_plug_unplug' since kdump intentionally reboots the guest. All existing non-kdump variants are unaffected. Signed-off-by: Anushree-Mathur Signed-off-by: Anushree-Mathur --- .../tests/cfg/libvirt_vcpu_plug_unplug.cfg | 25 ++++++++++++ libvirt/tests/src/libvirt_vcpu_plug_unplug.py | 40 ++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/libvirt/tests/cfg/libvirt_vcpu_plug_unplug.cfg b/libvirt/tests/cfg/libvirt_vcpu_plug_unplug.cfg index c16e88d4bb3..8c4dc7c7876 100644 --- a/libvirt/tests/cfg/libvirt_vcpu_plug_unplug.cfg +++ b/libvirt/tests/cfg/libvirt_vcpu_plug_unplug.cfg @@ -94,6 +94,31 @@ vcpu_plug_num = 240 vcpu_unplug_num = 1 vcpu_max_num = 240 + - kdump_after_plug_unplug: + # Hotplug vCPUs, trigger kdump, verify vmcore; + # then unplug vCPUs, trigger kdump again, verify + # a new vmcore. Confirms guest kernel stability + # under changing vCPU count. + # Requires kdump service active in the guest. + only live + only ppc64le,ppc64 + kdump_after_plug_unplug = "yes" + on_crash = "restart" + crash_dir = "/var/crash/" + vcpu_max_num = "8" + vcpu_current_num = "4" + vcpu_plug_num = "8" + vcpu_unplug_num = "4" + variants: + - hotplug_kdump: + vcpu_plug = "yes" + vcpu_unplug = "no" + - unplug_kdump: + vcpu_plug = "no" + vcpu_unplug = "yes" + - plug_and_unplug_kdump: + vcpu_plug = "yes" + vcpu_unplug = "yes" variants: - live: diff --git a/libvirt/tests/src/libvirt_vcpu_plug_unplug.py b/libvirt/tests/src/libvirt_vcpu_plug_unplug.py index d6404bd72f8..3249d7a233b 100644 --- a/libvirt/tests/src/libvirt_vcpu_plug_unplug.py +++ b/libvirt/tests/src/libvirt_vcpu_plug_unplug.py @@ -12,6 +12,7 @@ from virttest import utils_libvirtd from virttest import utils_test from virttest.utils_test import libvirt +from virttest import utils_kdump from virttest.libvirt_xml.vm_xml import VMXML from provider.cpu import patch_total_cpu_count_s390x @@ -240,6 +241,8 @@ def check_setvcpus_result(cmd_result, expect_error): with_stress = "yes" == params.get("run_stress", "no") iterations = int(params.get("test_itr", 1)) topology_correction = "yes" == params.get("topology_correction", "no") + kdump_after_plug_unplug = "yes" == params.get("kdump_after_plug_unplug", "no") + crash_dir = params.get("crash_dir", "/var/crash/") # Init expect vcpu count values expect_vcpu_num = {'max_config': vcpu_max_num, 'max_live': vcpu_max_num, 'cur_config': vcpu_current_num, @@ -356,6 +359,21 @@ def check_setvcpus_result(cmd_result, expect_error): vcpu_max_timeout, text="wait for vcpu online") or not online_new_vcpu(vm, vcpu_plug_num): test.fail("Fail to enable new added cpu") + # Trigger kdump after hotplug to verify guest kernel + # stability under the new vCPU count + if kdump_after_plug_unplug: + logging.info("Triggering kdump after vCPU hotplug") + kdump_session = vm.wait_for_login(timeout=240) + utils_kdump.trigger_crash(vm, session=kdump_session, + wait_time=120, test=test) + logging.info("Verifying vmcore generated after hotplug kdump") + pre_vmcores = utils_kdump.get_vmcores( + vm, crash_dir=crash_dir, test=test) + if not pre_vmcores: + test.fail("No vmcore generated after hotplug kdump") + logging.info("vmcore confirmed after hotplug: %s", + pre_vmcores) + # Pin vcpu if pin_after_plug: result = virsh.vcpupin(vm_name, pin_vcpu, pin_cpu_list, @@ -479,6 +497,21 @@ def check_setvcpus_result(cmd_result, expect_error): if session: session.close() + # Trigger kdump after unplug to verify guest kernel + # stability under the reduced vCPU count + if kdump_after_plug_unplug: + logging.info("Triggering kdump after vCPU unplug") + kdump_session = vm.wait_for_login(timeout=240) + utils_kdump.trigger_crash(vm, session=kdump_session, + wait_time=120, test=test) + logging.info("Verifying vmcore generated after unplug kdump") + post_vmcores = utils_kdump.get_vmcores( + vm, crash_dir=crash_dir, test=test) + if not post_vmcores: + test.fail("No vmcore generated after unplug kdump") + logging.info("vmcore confirmed after unplug: %s", + post_vmcores) + check_setvcpus_result(result, status_error) if setvcpu_option == "--config": expect_vcpu_num['cur_config'] = vcpu_unplug_num @@ -542,8 +575,11 @@ def check_setvcpus_result(cmd_result, expect_error): if not cpu.check_vcpu_value(vm, expect_vcpu_num, expect_vcpupin, setvcpu_option): logging.error("Expected vcpu check failed") result_failed += 1 - if vm.uptime() < vm_uptime_init: - test.fail("Unexpected VM reboot detected in between test") + # Skip uptime check when kdump is enabled: kdump intentionally + # crashes and reboots the guest, so a lower uptime is expected. + if not kdump_after_plug_unplug: + if vm.uptime() < vm_uptime_init: + test.fail("Unexpected VM reboot detected in between test") # Recover env finally: if need_mkswap: