Skip to content

Commit

Permalink
virtio_fs_nfs_migration_handler: Migration test with handler
Browse files Browse the repository at this point in the history
Testing --migration-verify-handles and --migration-confirm-paths over NFS

Signed-off-by: Zhenchao Liu <[email protected]>
  • Loading branch information
zhencliu committed Jan 17, 2025
1 parent bd33da7 commit 1ce0899
Show file tree
Hide file tree
Showing 2 changed files with 358 additions and 0 deletions.
90 changes: 90 additions & 0 deletions qemu/tests/cfg/virtio_fs_nfs_migration_handler.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
- virtio_fs_nfs_migration_handler:
no RHEL.6 RHEL.7 RHEL.8.0 RHEL.8.1
no Win2008 Win7 Win2012 Win2012..r2 Win8 Win8.1

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

# local nfs config
setup_local_nfs = yes
export_options = 'rw,insecure,no_root_squash,async'
export_dir = /var/tmp/virtio_fs_test_nfs
nfs_mount_options = rw
nfs_mount_dir = /var/mnt/fs
nfs_mount_dir_targetfs = /var/mnt/targetfs

filesystems = fs
filesystems_migration = targetfs
fs_driver = virtio-fs
fs_source_type = mount
fs_source_dir_fs = ${nfs_mount_dir}
fs_source_dir_targetfs = ${nfs_mount_dir_targetfs}
fs_target = myfs
fs_dest = /mnt/${fs_target}
force_create_fs_source = no
remove_fs_source = no
fs_driver_props = {"queue-size": 1024}
fs_binary_extra_options = " --cache auto --migration-verify-handles --migration-confirm-paths"
fs_binary_extra_options_targetfs = " --cache auto"
driver_name = viofs

test_file = test_file
test_data = hello_virtiofs
pre_command = mkdir -p ${nfs_mount_dir_targetfs} ${nfs_mount_dir} ${export_dir}
pre_command += " && echo -e ${test_data} > ${export_dir}/${test_file}"
post_command = rm -rf ${nfs_mount_dir_targetfs} ${nfs_mount_dir} ${export_dir}
read_file_cmd = cat %s/${test_file}
cmd_tail_file = tail -f %s/${test_file}
tail_name = tail
cmd_chk_tail = ps aux | grep ${tail_name}| grep -v grep
cmd_kill_tail = killall -s SIGKILL tail

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}
tail_name = powershell
cmd_tail_file = powershell -command "Get-Content %s\${test_file} -wait"
cmd_chk_tail = TASKLIST /FI "IMAGENAME eq POWERSHELL.EXE
cmd_kill_tail = TASKKILL /F /IM powershell.exe /T
268 changes: 268 additions & 0 deletions qemu/tests/virtio_fs_nfs_migration_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
import re

from virttest import env_process, error_context, nfs, utils_disk, utils_misc, utils_test

from provider import virtio_fs_utils


@error_context.context_aware
def run(test, params, env):
"""
Migration test over nfs with handler verify and path confirm
Steps:
1. Create a nfs share dir and write a file
2. Setup a local nfs server and mount fs to dirs fs and targetfs
3. Run the virtiofsd daemon to share fs
4. Boot the source guest with the virtiofs device in step3
5. Mount the virtiofs targets inside the guest
6. Check the file content and open the file by tail
7. Run the virtiofsd daemon to share targetfs
8. Boot the target guest with the virtiofs device in step7
9. Do migration from the source guest to the target guest
10. No error occurs, the virtiofs is mounted automatically and
the file cotent keeps the same, tail is still running
: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(f"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(session):
error_context.context("Stop virtiofs service in guest.", test.log.info)
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 open_file(session):
def do_tail():
fs_dest = guest_mnts[fs_target]
error_context.context("Open file on %s." % fs_dest, test.log.info)

tmo = params.get_numeric("tail_runtime", 1800)
bg_test = utils_test.BackgroundTest(
session.cmd_output, (params["cmd_tail_file"] % fs_dest, tmo)
)
bg_test.start()

for fs in params.objects("filesystems"):
fs_params = params.object_params(fs)
fs_target = fs_params["fs_target"]
do_tail()

def close_file(session):
error_context.context("Close file", test.log.info)
session.cmd_output(params["cmd_kill_tail"])

def test_migration():
def check_file_content():
error_context.context(
"Check file content",
test.log.info,
)
s = vm.wait_for_login()
for fs_dest in guest_mnts.values():
out = s.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}")
s.close()

def check_tail_running():
error_context.context(
"Check tail is running after migration", test.log.info
)
tail_name = params["tail_name"]
out = session.cmd_output(params["cmd_chk_tail"])
test.log.debug("Status of tail process: %s", out)

procs = re.findall(tail_name, out, re.M | re.I)
if not procs:
test.fail("Failed to get any running tail process")
elif len(procs) != len(params.get_list("filesystems")):
test.fail("Failed to get all running tail processes")

def check_service_activated():
error_context.context(
"Check virtiofs service activated after migration",
test.log.info,
)
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.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
)

check_file_content()

# FIXME: Replace the vm's params to use a different shared virtio fs
vm.params["filesystems"] = vm.params["filesystems_migration"]
vm.migrate()
session = vm.wait_for_login()

check_service_activated()
check_tail_running()
check_file_content()

return session

def setup_local_nfs():
error_context.context("Setup nfs server, mount it to two dirs", test.log.info)

# Setup the local nfs server and mount it to nfs_mount_dir
nfs_obj = nfs.Nfs(params)
nfs_obj.setup()

# Mount the local nfs server to nfs_mount_dir_targetfs
target_params = params.copy()
target_params["nfs_mount_dir"] = params["nfs_mount_dir_targetfs"]
target_params["setup_local_nfs"] = "no"
nfs_target = nfs.Nfs(target_params)
nfs_target.mount()

return nfs_obj, nfs_target

def cleanup_local_nfs():
error_context.context("Umount all and stop nfs server", test.log.info)
if target_nfs:
target_nfs.umount()
if local_nfs:
local_nfs.cleanup()

guest_mnts = dict()
os_type = params["os_type"]
local_nfs = None
target_nfs = None
vm = None
session = None

try:
local_nfs, target_nfs = setup_local_nfs()
env_process.process(
test, params, env, env_process.preprocess_image, env_process.preprocess_vm
)
vm = env.get_vm(params.get("main_vm"))
vm.verify_alive()
session = vm.wait_for_login()
session = create_service(session)
session = start_service(session)
open_file(session)
session = test_migration()
finally:
try:
close_file(session)
stop_service(session)
delete_service()
finally:
if vm:
vm.destroy()
cleanup_local_nfs()

0 comments on commit 1ce0899

Please sign in to comment.