From 79fc4216ded80926876a8e9dacfaf39eb4fb376f Mon Sep 17 00:00:00 2001 From: lcheng Date: Mon, 30 Sep 2024 22:04:28 +0800 Subject: [PATCH] migration: Add two cases about kill qemu XXX-298187 - [VM migration] kill qemu process during PerformPhase of migration XXX-298189 - [VM migration] kill qemu process during FinishPhase of postcopy migration Signed-off-by: lcheng --- .../kill_qemu_during_finishphase.cfg | 53 ++++++++++++++ .../kill_qemu_during_performphase.cfg | 69 ++++++++++++++++++ .../kill_qemu_during_finishphase.py | 72 +++++++++++++++++++ .../kill_qemu_during_performphase.py | 71 ++++++++++++++++++ 4 files changed, 265 insertions(+) create mode 100644 libvirt/tests/cfg/migration/destructive_operations_around_live_migration/kill_qemu_during_finishphase.cfg create mode 100644 libvirt/tests/cfg/migration/destructive_operations_around_live_migration/kill_qemu_during_performphase.cfg create mode 100644 libvirt/tests/src/migration/destructive_operations_around_live_migration/kill_qemu_during_finishphase.py create mode 100644 libvirt/tests/src/migration/destructive_operations_around_live_migration/kill_qemu_during_performphase.py diff --git a/libvirt/tests/cfg/migration/destructive_operations_around_live_migration/kill_qemu_during_finishphase.cfg b/libvirt/tests/cfg/migration/destructive_operations_around_live_migration/kill_qemu_during_finishphase.cfg new file mode 100644 index 0000000000..15a2aa7163 --- /dev/null +++ b/libvirt/tests/cfg/migration/destructive_operations_around_live_migration/kill_qemu_during_finishphase.cfg @@ -0,0 +1,53 @@ +- migration.destructive_operations_around_live_migration.kill_qemu_during_finishphase: + type = kill_qemu_during_finishphase + migration_setup = 'yes' + storage_type = 'nfs' + setup_local_nfs = 'yes' + disk_type = "file" + disk_source_protocol = "netfs" + mnt_path_name = ${nfs_mount_dir} + # Console output can only be monitored via virsh console output + only_pty = True + take_regular_screendumps = no + # Extra options to pass after + virsh_migrate_extra = '' + # SSH connection time out + ssh_timeout = 60 + # Local URI + virsh_migrate_connect_uri = 'qemu:///system' + virsh_migrate_dest_state = "running" + virsh_migrate_src_state = "shut off" + image_convert = 'no' + server_ip = "${migrate_dest_host}" + server_user = "root" + server_pwd = "${migrate_dest_pwd}" + check_network_accessibility_after_mig = "yes" + migrate_desturi_port = "16509" + migrate_desturi_type = "tcp" + virsh_migrate_desturi = "qemu+tcp://${migrate_dest_host}/system" + status_error = "yes" + migrate_again = "yes" + service_name = "qemu-kvm" + migrate_again_status_error = "no" + variants: + - p2p: + virsh_migrate_options = '--live --p2p --verbose' + - non_p2p: + virsh_migrate_options = '--live --verbose' + variants: + - with_postcopy: + postcopy_options = "--timeout 2 --timeout-postcopy --postcopy --postcopy-bandwidth 10 --bandwidth 10" + variants test_case: + - kill_dest_qemu: + service_on_dst = "yes" + expected_event_src = ["Suspended Post-copy", "Suspended Post-copy Error"] + expected_event_target = ["Stopped Failed"] + action_during_mig = '[{"func": "libvirt.check_vm_state", "func_param": {"vm_name": "${main_vm}", "state": "paused", "reason":"post-copy"}, "need_sleep_time": "5"}, {"func": "libvirt_service.kill_service", "func_param": "params"}]' + expected_dest_state = "nonexist" + expected_src_state = "paused" + - kill_src_qemu: + expected_dest_state = "running" + expected_src_state = "shut off" + expected_event_src = ["Suspended Post-copy Error", "Stopped Failed"] + expected_event_target = ["Resumed Post-copy Error"] + action_during_mig = '[{"func": "libvirt.check_vm_state", "func_param": {"vm_name": "${main_vm}", "state": "paused", "reason":"post-copy"}, "need_sleep_time": "8"}, {"func": "libvirt_service.kill_service", "func_param": "params"}]' diff --git a/libvirt/tests/cfg/migration/destructive_operations_around_live_migration/kill_qemu_during_performphase.cfg b/libvirt/tests/cfg/migration/destructive_operations_around_live_migration/kill_qemu_during_performphase.cfg new file mode 100644 index 0000000000..9af9a89cd4 --- /dev/null +++ b/libvirt/tests/cfg/migration/destructive_operations_around_live_migration/kill_qemu_during_performphase.cfg @@ -0,0 +1,69 @@ +- migration.destructive_operations_around_live_migration.kill_qemu_during_performphase: + type = kill_qemu_during_performphase + migration_setup = 'yes' + storage_type = 'nfs' + setup_local_nfs = 'yes' + disk_type = "file" + disk_source_protocol = "netfs" + mnt_path_name = ${nfs_mount_dir} + # Console output can only be monitored via virsh console output + only_pty = True + take_regular_screendumps = no + # Extra options to pass after + virsh_migrate_extra = '' + # SSH connection time out + ssh_timeout = 60 + # Local URI + virsh_migrate_connect_uri = 'qemu:///system' + virsh_migrate_dest_state = "running" + virsh_migrate_src_state = "shut off" + image_convert = 'no' + server_ip = "${migrate_dest_host}" + server_user = "root" + server_pwd = "${migrate_dest_pwd}" + check_network_accessibility_after_mig = "yes" + migrate_desturi_port = "16509" + migrate_desturi_type = "tcp" + virsh_migrate_desturi = "qemu+tcp://${migrate_dest_host}/system" + status_error = "yes" + migrate_again = "yes" + service_name = "qemu-kvm" + migrate_again_status_error = "no" + migrate_speed = "10" + simple_disk_check_after_mig = "yes" + variants: + - p2p: + virsh_migrate_options = '--live --p2p --verbose' + - non_p2p: + virsh_migrate_options = '--live --verbose' + variants: + - with_precopy: + variants test_case: + - kill_dest_qemu_before_vm_paused: + service_on_dst = "yes" + expected_event_src = ["migration-iteration"] + expected_event_target = ["lifecycle", "lifecycle.*: Stopped Failed"] + action_during_mig = '[{"func": "libvirt_service.kill_service", "func_param": "params", "need_sleep_time": "1"}]' + expected_dest_state = "nonexist" + expected_src_state = "running" + migrate_speed = "1" + err_msg = "QEMU unexpectedly closed the monitor" + check_disk_on_dest = "no" + virsh_migrate_extra = "--bandwidth 1000" + - kill_dest_qemu_after_vm_paused: + service_on_dst = "yes" + expected_event_src = ["migration-iteration", "lifecycle.*: Suspended Migrated", "lifecycle.*: Resumed Migrated"] + expected_event_target = ["lifecycle", "lifecycle.*: Stopped Failed"] + action_during_mig = '[{"func": "libvirt_service.kill_service", "after_event": "migration-iteration", "func_param": "params"}]' + expected_dest_state = "nonexist" + expected_src_state = "running" + virsh_migrate_extra = "--timeout 2 --timeout-suspend --bandwidth 1000" + err_msg = "QEMU unexpectedly closed the monitor" + - kill_src_qemu: + expected_dest_state = "nonexist" + expected_src_state = "shut off" + expected_event_src = ["migration-iteration", "lifecycle.*: Stopped Failed"] + expected_event_target = ["lifecycle", "lifecycle.*: Stopped Failed"] + action_during_mig = '[{"func": "libvirt_service.kill_service", "after_event": "migration-iteration", "func_param": "params"}]' + virsh_migrate_extra = "--bandwidth 1000" + err_msg = "operation failed: domain is not running" diff --git a/libvirt/tests/src/migration/destructive_operations_around_live_migration/kill_qemu_during_finishphase.py b/libvirt/tests/src/migration/destructive_operations_around_live_migration/kill_qemu_during_finishphase.py new file mode 100644 index 0000000000..456b987069 --- /dev/null +++ b/libvirt/tests/src/migration/destructive_operations_around_live_migration/kill_qemu_during_finishphase.py @@ -0,0 +1,72 @@ +from virttest import virsh + +from virttest.utils_test import libvirt + +from provider.migration import base_steps +from provider.migration import migration_base + + +def run(test, params, env): + """ + This case is to verify that if killing qemu process during FinishPhase of + postcopy migration, migration will fail. + + :param test: test object + :param params: Dictionary with the test parameters + :param env: Dictionary with test environment. + """ + def verify_test(): + """ + Verify migration result + + """ + dest_uri = params.get("virsh_migrate_desturi") + expected_src_state = params.get("expected_src_state") + expected_dest_state = params.get("expected_dest_state") + + func_returns = dict(migration_obj.migration_test.func_ret) + migration_obj.migration_test.func_ret.clear() + test.log.debug("Migration returns function results: %s", func_returns) + if expected_src_state: + if not libvirt.check_vm_state(vm.name, expected_src_state, uri=migration_obj.src_uri): + test.fail("Migrated VM failed to be in %s state at source." % expected_src_state) + if expected_dest_state and expected_dest_state == "nonexist": + virsh.domstate(vm_name, uri=dest_uri, debug=True) + if virsh.domain_exists(vm_name, uri=dest_uri): + test.fail("The domain on target host is found, but expected not") + if expected_src_state == "shut off": + vm.start() + vm.wait_for_login().close() + elif expected_src_state == "paused": + vm.destroy() + vm.start() + vm.wait_for_login().close() + + if expected_dest_state == "running": + virsh.destroy(vm_name, uri=dest_uri) + + vm_name = params.get("migrate_main_vm") + test_case = params.get("test_case", "") + migrate_again = "yes" == params.get("migrate_again", "no") + + virsh_session = None + remote_virsh_session = None + + vm = env.get_vm(vm_name) + migration_obj = base_steps.MigrationBase(test, vm, params) + setup_test = eval("setup_%s" % test_case) if "setup_%s" % test_case in \ + locals() else migration_obj.setup_connection + migration_test_again = eval("migration_%s_again" % test_case) if "migration_%s_again" % test_case in \ + locals() else migration_obj.run_migration_again + + try: + setup_test() + virsh_session, remote_virsh_session = migration_base.monitor_event(params) + migration_obj.run_migration() + verify_test() + migration_base.check_event_output(params, test, virsh_session, remote_virsh_session) + if migrate_again: + migration_test_again() + migration_obj.verify_default() + finally: + migration_obj.cleanup_connection() diff --git a/libvirt/tests/src/migration/destructive_operations_around_live_migration/kill_qemu_during_performphase.py b/libvirt/tests/src/migration/destructive_operations_around_live_migration/kill_qemu_during_performphase.py new file mode 100644 index 0000000000..6b93af23f5 --- /dev/null +++ b/libvirt/tests/src/migration/destructive_operations_around_live_migration/kill_qemu_during_performphase.py @@ -0,0 +1,71 @@ +from virttest import virsh + +from virttest.utils_test import libvirt + +from provider.migration import base_steps +from provider.migration import migration_base + + +def run(test, params, env): + """ + This case is to verify that if killing qemu process during PerformPhase of + migration, migration will fail. If dst qemu is killed, src qemu will keep + running. If src qemu is killed, dst qemu will be closed. + + :param test: test object + :param params: Dictionary with the test parameters + :param env: Dictionary with test environment. + """ + def verify_test(): + """ + Verify migration result + + """ + dest_uri = params.get("virsh_migrate_desturi") + expected_src_state = params.get("expected_src_state") + expected_dest_state = params.get("expected_dest_state") + + func_returns = dict(migration_obj.migration_test.func_ret) + migration_obj.migration_test.func_ret.clear() + test.log.debug("Migration returns function results: %s", func_returns) + virsh.domstate(vm_name, uri=migration_obj.src_uri, debug=True) + if expected_src_state: + if not libvirt.check_vm_state(vm.name, expected_src_state, uri=migration_obj.src_uri): + test.fail("Migrated VM failed to be in %s state at source." % expected_src_state) + if expected_dest_state and expected_dest_state == "nonexist": + virsh.domstate(vm_name, uri=dest_uri, debug=True) + if virsh.domain_exists(vm_name, uri=dest_uri): + test.fail("The domain on target host is found, but expected not") + # Check disk on source + if test_case == "kill_src_qemu_before_vm_paused": + migration_obj.migration_test.post_migration_check([vm], params) + if expected_src_state == "shut off": + vm.start() + vm.wait_for_login().close() + #migration_base.set_migrate_speed_to_high(params) + + vm_name = params.get("migrate_main_vm") + test_case = params.get("test_case", "") + migrate_again = "yes" == params.get("migrate_again", "no") + + virsh_session = None + remote_virsh_session = None + + vm = env.get_vm(vm_name) + migration_obj = base_steps.MigrationBase(test, vm, params) + setup_test = eval("setup_%s" % test_case) if "setup_%s" % test_case in \ + locals() else migration_obj.setup_connection + migration_test_again = eval("migration_%s_again" % test_case) if "migration_%s_again" % test_case in \ + locals() else migration_obj.run_migration_again + + try: + setup_test() + virsh_session, remote_virsh_session = migration_base.monitor_event(params) + migration_obj.run_migration() + verify_test() + migration_base.check_event_output(params, test, virsh_session, remote_virsh_session) + if migrate_again: + migration_test_again() + migration_obj.verify_default() + finally: + migration_obj.cleanup_connection()