Skip to content

Commit

Permalink
virtio_fs_migration_on_error: Migration test with migration-on-error
Browse files Browse the repository at this point in the history
Covered the following viriofsd options:
  --migration-on-error abort
  --migration-on-error guest-error

Signed-off-by: Zhenchao Liu <[email protected]>
  • Loading branch information
zhencliu committed Nov 11, 2024
1 parent 9a57983 commit 12f0380
Show file tree
Hide file tree
Showing 2 changed files with 308 additions and 0 deletions.
88 changes: 88 additions & 0 deletions qemu/tests/cfg/virtio_fs_migration_on_error.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
- virtio_fs_migration_on_error:
no RHEL.6 RHEL.7 RHEL.8.0 RHEL.8.1
no Win2008 Win7 Win2012 Win2012..r2 Win8 Win8.1

type = virtio_fs_migration_on_error
virt_test_type = qemu
required_qemu = [9.0.0,)
kill_vm = yes
start_vm = yes

filesystems = fs
filesystems_migration = targetfs
fs_driver = virtio-fs
fs_source_type = mount
fs_source_dir_fs = /var/tmp/virtio_fs_source
fs_source_dir_targetfs = /var/tmp/virtio_fs_target
fs_target = myfs
fs_dest = /mnt/${fs_target}
force_create_fs_source = no
remove_fs_source = no
fs_driver_props = {"queue-size": 1024}
driver_name = viofs

test_file = test_file
test_data = hello_virtiofs
pre_command = mkdir -p ${fs_source_dir_fs} ${fs_source_dir_targetfs}
post_command = rm -rf ${fs_source_dir_fs} ${fs_source_dir_targetfs}
read_file_cmd = "cat %s/${test_file}"
fs_binary_extra_options = " --cache auto"
on_error = abort

share_mem = yes
vm_mem_share = yes
vm_mem_backend = memory-backend-memfd
Win10.i386:
mem = 4096
!s390, s390x:
mem_devs = mem1
backend_mem_mem1 = memory-backend-memfd
size_mem1 = ${mem}M
use_mem_mem1 = no
guest_numa_nodes = shm0
numa_memdev_shm0 = mem-mem1
numa_nodeid_shm0 = 0
Windows:
# install winfsp tool
i386, i686:
install_winfsp_path = 'C:\Program Files'
devcon_dirname = 'x86'
x86_64:
install_winfsp_path = 'C:\Program Files (x86)'
devcon_dirname = 'amd64'
install_winfsp_cmd = 'msiexec /i WIN_UTILS:\winfsp.msi /qn'
check_installed_cmd = 'dir "%s" |findstr /I winfsp'
viofs_log_file = C:\viofs_log.txt
viofs_svc_name = VirtioFsSvc
viofs_exe_path = C:\virtiofs.exe
viofs_exe_copy_cmd = xcopy %s C:\ /Y
viofs_sc_create_cmd = 'sc create ${viofs_svc_name} binpath=${viofs_exe_path} start=auto'
viofs_sc_create_cmd += ' depend="WinFsp.Launcher/VirtioFsDrv" DisplayName="Virtio FS Service"'
viofs_sc_start_cmd = 'sc start ${viofs_svc_name}'
viofs_sc_query_cmd = 'sc query ${viofs_svc_name}'
viofs_sc_delete_cmd = 'sc delete ${viofs_svc_name}'
debug_log_operation = 'enable'
viofs_debug_enable_cmd = 'reg add HKLM\Software\VirtIO-FS /v DebugFlags /d 0xFFFFFFFF /t REG_DWORD'
viofs_log_enable_cmd = 'reg add HKLM\Software\VirtIO-FS /v DebugLogFile /d ${viofs_log_file} /t REG_SZ'
viofs_debug_delete_cmd = 'reg delete HKLM\Software\VirtIO-FS /v DebugFlags /f'
viofs_log_delete_cmd = 'reg delete HKLM\Software\VirtIO-FS /v DebugLogFile /f'
viofs_reg_query_cmd = 'reg query HKLM\Software\VirtIO-FS'
virtio_win_media_type = iso
cdroms += " virtio"
read_file_cmd = "type %s\${test_file}"
variants:
- @default:
chk_msg = Error loading back-end state of virtio-user-fs device.+\(tag: "${fs_target}"\): Back-end failed to process its internal state
pre_command += " && echo -e ${test_data} > ${fs_source_dir_fs}/${test_file}"
- abort:
on_error = abort
chk_msg = Error loading back-end state of virtio-user-fs device.+\(tag: "${fs_target}"\): Back-end failed to process its internal state
fs_binary_extra_options_targetfs = "${fs_binary_extra_options} --migration-on-error abort"
pre_command += " && echo -e ${test_data} > ${fs_source_dir_fs}/${test_file}"
- guest_error:
on_error = guest_error
fs_binary_extra_options_targetfs = "${fs_binary_extra_options} --migration-on-error guest-error"
variants:
- diff_dir:
pre_command += " && touch ${fs_source_dir_fs}/${test_file}.src1 ${fs_source_dir_fs}/${test_file}.src2"
pre_command += " && touch ${fs_source_dir_targetfs}/${test_file}.tgt1 ${fs_source_dir_targetfs}/${test_file}.tgt2"
220 changes: 220 additions & 0 deletions qemu/tests/virtio_fs_migration_on_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
import os
import re

from virttest import error_context, utils_disk, utils_misc, utils_test, virt_vm

from provider import virtio_fs_utils


@error_context.context_aware
def run(test, params, env):
"""
Basic migration test with diffirent cache modes over localfs
Steps:
1. Create a shared directory on the host and write a file
2. Run the virtiofsd daemon on the host with different cache modes
3. Boot the source guest with the virtiofs device in step1
4. Mount the virtiofs targets inside the guest
5. Create a different directory on the host and write a file
6. Run the virtiofsd daemon to share the directory in step5
7. Boot the target guest with the virtiofs device in step5
8. Do migration from the source guest to the target guest
9. No error occurs, the virtiofs is mounted automatically and
the file content keeps the same on the target guest
:param test: QEMU test object.
:param params: Dictionary with the test parameters.
:param env: Dictionary with test environment.
"""

def create_service(session):
if os_type == "windows":
error_context.context("Create virtiofs service in guest.", test.log.info)

driver_name = params["driver_name"]

session = utils_test.qemu.windrv_check_running_verifier(
session, vm, test, driver_name
)
viofs_svc_name = params["viofs_svc_name"]
virtio_fs_utils.create_viofs_service(
test, params, session, service=viofs_svc_name
)
return session

def delete_service():
if os_type == "windows":
error_context.context("Delete virtiofs service in guest.", test.log.info)
session = vm.wait_for_login()
virtio_fs_utils.delete_viofs_serivce(test, params, session)
session.close()

def start_service(session):
def start_multifs_instance(fs_tag, fs_target, fs_volume_label):
"""
Only for windows and only for multiple shared directory.
"""
error_context.context(
"MultiFS-%s: Start virtiofs instance with"
" tag %s to %s." % (fs_tag, fs_target, fs_volume_label),
test.log.info,
)
instance_start_cmd = params["instance_start_cmd"]
output = session.cmd_output(
instance_start_cmd % (fs_target, fs_target, fs_volume_label)
)
if re.search("KO.*error", output, re.I):
test.fail(
"MultiFS-%s: Start virtiofs instance failed, "
"output is %s." % (fs_tag, output)
)

for fs in params.objects("filesystems"):
fs_params = params.object_params(fs)

fs_target = fs_params["fs_target"]
fs_dest = fs_params["fs_dest"]

if os_type == "linux":
utils_misc.make_dirs(fs_dest, session)
error_context.context(
"Mount virtiofs target %s to %s inside"
" guest." % (fs_target, fs_dest),
test.log.info,
)
if not utils_disk.mount(
fs_target, fs_dest, "virtiofs", session=session
):
utils_misc.safe_rmdir(fs_dest, session=session)
test.fail("Failed to mount virtiofs {fs_target}.")
else:
if params["viofs_svc_name"] == "VirtioFsSvc":
error_context.context(
"Start virtiofs service in guest.", test.log.info
)
debug_log_operation = params.get("debug_log_operation")
if debug_log_operation:
session = virtio_fs_utils.operate_debug_log(
test, params, session, vm, debug_log_operation
)
virtio_fs_utils.start_viofs_service(test, params, session)
else:
error_context.context(
"Start winfsp.launcher instance in guest.", test.log.info
)
fs_volume_label = fs_params["volume_label"]
start_multifs_instance(fs, fs_target, fs_volume_label)

fs_dest = "%s:" % virtio_fs_utils.get_virtiofs_driver_letter(
test, fs_target, session
)

guest_mnts[fs_target] = fs_dest
return session

def stop_service():
error_context.context("Stop virtiofs service in guest.", test.log.info)

session = vm.wait_for_login()
if os_type == "linux":
for fs_target, fs_dest in guest_mnts.items():
utils_disk.umount(fs_target, fs_dest, "virtiofs", session=session)
utils_misc.safe_rmdir(fs_dest, session=session)
else:
if params["viofs_svc_name"] == "WinFSP.Launcher":
for fs_target in guest_mnts.keys():
error_context.context(
"Unmount fs with WinFsp.Launcher.z", test.log.info
)
instance_stop_cmd = params["instance_stop_cmd"]
session.cmd(instance_stop_cmd % fs_target)
else:
if guest_mnts:
virtio_fs_utils.stop_viofs_service(test, params, session)
session.close()

def check_message():
log_file = os.path.join(
test.resultsdir, params.get("debug_log_file", "debug.log")
)
with open(log_file, "r") as f:
out = f.read().strip()
m = re.search(params["chk_msg"], out, re.M)
if m is not None:
test.log.debug("Expected message: %s", m.group())
return True
return False

def check_service_activated():
error_context.context(
"Check virtiofs service activated after migration.",
test.log.info,
)
session = vm.wait_for_login()
tmo = params.get_numeric("active_timeout", 10)
if os_type == "linux":
for fs_target, fs_dest in guest_mnts.items():
if not utils_misc.wait_for(
lambda: utils_disk.is_mount(
fs_target, fs_dest, "virtiofs", None, True, session
),
tmo,
):
test.log.fail(f"Failed to mount {fs_target}")
else:
for fs_target in guest_mnts.keys():
vol_lable = virtio_fs_utils.get_virtiofs_driver_letter(
test, fs_target, session
)
test.log.debug(
"Fs target %s mounted on volume %s", fs_target, vol_lable
)
session.close()

def check_file_content():
error_context.context("Check file content", test.log.info)
for fs_dest in guest_mnts.values():
out = session.cmd_output(params["read_file_cmd"] % fs_dest).strip()
test.log.debug("File content: %s", out)
if out != params["test_data"]:
test.fail(f"Wrong file content found: {out}")

def test_migration_abort():
check_file_content()
try:
vm.migrate()
except virt_vm.VMMigrateFailedError:
# Sometimes we got status: failed, mostly we got status: completed
test.log.debug("Expected migration failure")

error_context.context("Check error message after migration", test.log.info)
tmo = params.get_numeric("chk_msg_timeout", 600)
if not utils_misc.wait_for(check_message, tmo, step=30):
test.fail("Failed to get the expected message")

def test_migration_guest_error():
vm.migrate()
check_service_activated()

guest_mnts = dict()
os_type = params["os_type"]
on_error = params["on_error"]
test_funcs = {
"abort": test_migration_abort,
"guest_error": test_migration_guest_error,
}

vm = env.get_vm(params.get("main_vm"))
vm.verify_alive()
session = vm.wait_for_login()

try:
session = create_service(session)
session = start_service(session)
# FIXME: Replace the vm's params to use a different shared virtio fs
vm.params["filesystems"] = vm.params["filesystems_migration"]
test_funcs[on_error]()
finally:
if not vm.is_dead():
stop_service()
delete_service()

0 comments on commit 12f0380

Please sign in to comment.