def copy_file_to_samepath(session, test, params): """ Copy autoit scripts and installer tool to the same path. :param session: The guest session object. :param test: kvm test object :param params: the dict used for parameters """ logging.info("Copy autoit scripts and virtio-win-guest-tools.exe " "to the same path.") dst_path = r"C:\\" vol_virtio_key = "VolumeName like '%virtio-win%'" vol_virtio = utils_misc.get_win_disk_vol(session, vol_virtio_key) installer_path = r"%s:\%s" % (vol_virtio, "virtio-win-guest-tools.exe") install_script_path = utils_misc.set_winutils_letter( session, params["install_script_path"]) repair_script_path = utils_misc.set_winutils_letter( session, params["repair_script_path"]) uninstall_script_path = utils_misc.set_winutils_letter( session, params["uninstall_script_path"]) src_files = [ installer_path, install_script_path, repair_script_path, uninstall_script_path ] for src_file in src_files: copy_cmd = "xcopy %s %s /Y" % (src_file, dst_path) status, output = session.cmd_status_output(copy_cmd) if status != 0: test.error("Copy file error," " the detailed info:\n%s." % output)
def get_driver_path(session, driver_name): """ Get the driver path which would be installed. :param session: VM session. :param driver_name: Driver name. :return driver_path: Return the driver path. """ guest_name = params["guest_name"] alias_map = params.get("guest_alias") vol_virtio_key = "VolumeName like '%virtio-win%'" vol_virtio = utils_misc.get_win_disk_vol(session, vol_virtio_key) logging.debug("vol_virtio is %s" % vol_virtio) if alias_map: guest_list = dict([x.split(":") for x in alias_map.split(",")]) guest_name = guest_list[guest_name] # For driver virtio serial, the path name is not same as driver name, # need udpate the path here. if driver_name == "vioser": driver_name = "vioserial" driver_path = r"%s:\%s\%s" % (vol_virtio, driver_name, guest_name) logging.debug("The driver which would be installed is %s" % driver_path) return driver_path
def get_disk_vol(self, session): """ Get virtio-win disk volume letter for windows guest. :param session: VM session. """ key = "VolumeName like 'virtio-win%'" try: return utils_misc.get_win_disk_vol(session, condition=key) except Exception: self.test.error("Could not get virtio-win disk vol!")
def get_disk_vol(session): """ Get virtio-win disk volume letter. :param session: VM session. """ key = "VolumeName like 'virtio-win%'" try: return utils_misc.get_win_disk_vol(session, condition=key) except Exception: raise exceptions.TestFail("Could not get virtio-win disk vol!")
def get_qga_pkg_path(self, test, session, params, vm): """ Get the qemu-ga pkg path which will be installed. There are two methods to get qemu-ga pkg,one is download it from fedora people website,and the other is from virtio-win iso. :param test: kvm test object :param session: VM session. :param params: Dictionary with the test parameters :param vm: Virtual machine object. :return qemu_ga_pkg_path: Return the guest agent pkg path. """ error_context.context("Get qemu-ga.msi path where it locate.", logging.info) qemu_ga_pkg = params["qemu_ga_pkg"] gagent_src_type = params.get("gagent_src_type", "url") if gagent_src_type == "url": gagent_host_path = params["gagent_host_path"] gagent_guest_dir = params["gagent_guest_dir"] gagent_download_cmd = params["gagent_download_cmd"] error_context.context( "Download qemu-ga.msi from website and copy " "it to guest.", logging.info) process.system(gagent_download_cmd, float(params.get("login_timeout", 360))) if not os.path.exists(gagent_host_path): test.error("qemu-ga.msi is not exist, maybe it is not " "successfully downloaded ") s, o = session.cmd_status_output("mkdir %s" % gagent_guest_dir) if s and "already exists" not in o: test.error("Could not create qemu-ga directory in " "VM '%s', detail: '%s'" % (vm.name, o)) error_context.context("Copy qemu-ga.msi to guest", logging.info) vm.copy_files_to(gagent_host_path, gagent_guest_dir) qemu_ga_pkg_path = r"%s\%s" % (gagent_guest_dir, qemu_ga_pkg) elif gagent_src_type == "virtio-win": vol_virtio_key = "VolumeName like '%virtio-win%'" vol_virtio = utils_misc.get_win_disk_vol(session, vol_virtio_key) qemu_ga_pkg_path = r"%s:\%s\%s" % (vol_virtio, "guest-agent", qemu_ga_pkg) else: test.error("Only support 'url' and 'virtio-win' method to " "download qga installer now.") logging.info("The qemu-ga pkg which will be installed is %s" % qemu_ga_pkg_path) return qemu_ga_pkg_path
def get_qga_pkg_path(self, test, session, params, vm): """ Get the qemu-ga pkg path which will be installed. There are two methods to get qemu-ga pkg,one is download it from fedora people website,and the other is from virtio-win iso. :param test: kvm test object :param session: VM session. :param params: Dictionary with the test parameters :param vm: Virtual machine object. :return qemu_ga_pkg_path: Return the guest agent pkg path. """ error_context.context("Get qemu-ga.msi path where it locate.", logging.info) qemu_ga_pkg = params["qemu_ga_pkg"] gagent_src_type = params.get("gagent_src_type", "url") if gagent_src_type == "url": gagent_host_path = params["gagent_host_path"] gagent_guest_dir = params["gagent_guest_dir"] gagent_download_cmd = params["gagent_download_cmd"] error_context.context("Download qemu-ga.msi from website and copy " "it to guest.", logging.info) process.system(gagent_download_cmd, float(params.get("login_timeout", 360))) if not os.path.exists(gagent_host_path): test.error("qemu-ga.msi is not exist, maybe it is not " "successfully downloaded ") s, o = session.cmd_status_output("mkdir %s" % gagent_guest_dir) if s and "already exists" not in o: test.error("Could not create qemu-ga directory in " "VM '%s', detail: '%s'" % (vm.name, o)) error_context.context("Copy qemu-ga.msi to guest", logging.info) vm.copy_files_to(gagent_host_path, gagent_guest_dir) qemu_ga_pkg_path = r"%s\%s" % (gagent_guest_dir, qemu_ga_pkg) elif gagent_src_type == "virtio-win": vol_virtio_key = "VolumeName like '%virtio-win%'" vol_virtio = utils_misc.get_win_disk_vol(session, vol_virtio_key) qemu_ga_pkg_path = r"%s:\%s\%s" % (vol_virtio, "guest-agent", qemu_ga_pkg) else: test.error("Only support 'url' and 'virtio-win' method to " "download qga installer now.") logging.info("The qemu-ga pkg which will be installed is %s" % qemu_ga_pkg_path) return qemu_ga_pkg_path
def install_gagent(session, test, qemu_ga_pkg, gagent_install_cmd, gagent_pkg_info_cmd): """ Install guest agent. :param session: The guest session object. :param test: kvm test object :param qemu_ga_pkg: guest agent pkg name. :param gagent_install_cmd: guest agent install command. :param gagent_pkg_info_cmd: guest agent pkg info check command. """ logging.info("Install 'qemu-guest-agent' package in guest.") vol_virtio_key = "VolumeName like '%virtio-win%'" vol_virtio = utils_misc.get_win_disk_vol(session, vol_virtio_key) qemu_ga_pkg_path = r"%s:\%s\%s" % (vol_virtio, "guest-agent", qemu_ga_pkg) gagent_install_cmd = gagent_install_cmd % qemu_ga_pkg_path s_inst, o_inst = session.cmd_status_output(gagent_install_cmd) if s_inst != 0: test.fail("qemu-guest-agent install failed," " the detailed info:\n%s." % o_inst) gagent_version = session.cmd_output(gagent_pkg_info_cmd).split()[-2] return gagent_version
def _change_agent_media(cdrom_virtio): """ Only for virtio-win method,change virtio-win iso. :param cdrom_virtio: iso file """ logging.info("Change cdrom to %s", cdrom_virtio) virtio_iso = utils_misc.get_path(data_dir.get_data_dir(), cdrom_virtio) vm.change_media("drive_virtio", virtio_iso) logging.info("Wait until device is ready") vol_virtio_key = "VolumeName like '%virtio-win%'" timeout = 10 end_time = time.time() + timeout while time.time() < end_time: time.sleep(2) virtio_win_letter = utils_misc.get_win_disk_vol( session, vol_virtio_key) if virtio_win_letter: break if not virtio_win_letter: test.fail("Couldn't get virtio-win volume letter.")
def _change_agent_media(cdrom_virtio): """ Only for virtio-win method,change virtio-win iso. :param cdrom_virtio: iso file """ logging.info("Change cdrom to %s" % cdrom_virtio) virtio_iso = utils_misc.get_path(data_dir.get_data_dir(), cdrom_virtio) vm.change_media("drive_virtio", virtio_iso) logging.info("Wait until device is ready") vol_virtio_key = "VolumeName like '%virtio-win%'" timeout = 10 end_time = time.time() + timeout while time.time() < end_time: time.sleep(2) virtio_win_letter = utils_misc.get_win_disk_vol(session, vol_virtio_key) if virtio_win_letter: break if not virtio_win_letter: test.fail("Couldn't get virtio-win volume letter.")
def run(test, params, env): """ Test virtio-fs by sharing the data between host and guest. Steps: 1. Create shared directories on the host. 2. Set capability on the host. 3. Run virtiofsd daemons on capability shell env. 4. Boot a guest on the host with virtiofs options. 5. Log into guest then mount the virtiofs targets. 6. Generate files or run stress on the mount points inside guest. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_viofs_exe(session): """ Get viofs.exe from virtio win iso,such as E:\viofs\2k19\amd64 """ media_type = params["virtio_win_media_type"] try: get_drive_letter = getattr(virtio_win, "drive_letter_%s" % media_type) get_product_dirname = getattr(virtio_win, "product_dirname_%s" % media_type) get_arch_dirname = getattr(virtio_win, "arch_dirname_%s" % media_type) except AttributeError: test.error("Not supported virtio win media type '%s'", media_type) viowin_ltr = get_drive_letter(session) if not viowin_ltr: test.error("Could not find virtio-win drive in guest") guest_name = get_product_dirname(session) if not guest_name: test.error("Could not get product dirname of the vm") guest_arch = get_arch_dirname(session) if not guest_arch: test.error("Could not get architecture dirname of the vm") exe_middle_path = ("{name}\\{arch}" if media_type == "iso" else "{arch}\\{name}").format(name=guest_name, arch=guest_arch) exe_file_name = "virtiofs.exe" exe_find_cmd = 'dir /b /s %s\\%s | findstr "\\%s\\\\"' exe_find_cmd %= (viowin_ltr, exe_file_name, exe_middle_path) exe_path = session.cmd(exe_find_cmd).strip() logging.info("Found exe file '%s'", exe_path) return exe_path # data io config cmd_dd = params.get('cmd_dd') cmd_md5 = params.get('cmd_md5') io_timeout = params.get_numeric('io_timeout') # remove capability config cmd_create_fs_source = params.get('cmd_create_fs_source') cmd_run_virtiofsd = params.get('cmd_run_virtiofsd') capability = params.get('capability') cmd_capsh_print = params.get('cmd_capsh_print') cmd_capsh_drop = params.get('cmd_capsh_drop') # set trusted config cmd_yum_attr = params.get('cmd_yum_attr') cmd_set_trusted = params.get('cmd_set_trusted') cmd_get_trusted = params.get('cmd_get_trusted') cmd_create_file = params.get('cmd_create_file') cmd_set_capability = params.get('cmd_set_capability') cmd_get_capability = params.get('cmd_get_capability') cmd_echo_file = params.get('cmd_echo_file') # set fs daemon path target = params.get('fs_target') fs_source = params.get('fs_source_dir') base_dir = params.get('fs_source_base_dir', data_dir.get_data_dir()) if not os.path.isabs(fs_source): fs_source = os.path.join(base_dir, fs_source) if os.path.exists(fs_source): shutil.rmtree(fs_source, ignore_errors=True) logging.info("Create filesystem source %s.", fs_source) os.makedirs(fs_source) sock_path = os.path.join( data_dir.get_tmp_dir(), '-'.join( ('avocado-vt-vm1', 'viofs', 'virtiofsd.sock'))) # set capability cmd_capsh_drop = (cmd_capsh_drop % capability) error_context.context("Remove capability on host.", logging.info) session = aexpect.ShellSession( cmd_capsh_drop, auto_close=False, output_func=utils_misc.log_line, output_params=('virtiofs_fs-virtiofs.log', ), prompt=r"^\[.*\][\#\$]\s*$") output = session.cmd_output(cmd_capsh_print) logging.info("Check current capability is %s.", output) if capability in output: test.error("It's failed to check the trusted info from the host.") # run daemon session.sendline(cmd_create_fs_source) cmd_run_virtiofsd = cmd_run_virtiofsd % sock_path cmd_run_virtiofsd += ' -o source=%s' % fs_source cmd_run_virtiofsd += params.get('fs_binary_extra_options') logging.info('Running daemon command %s.', cmd_run_virtiofsd) session.sendline(cmd_run_virtiofsd) # insert devices vm = env.get_vm(params.get("main_vm")) vm.devices, _ = vm.make_create_command() machine_type = params.get("machine_type", "") qbus_type = "PCI" if machine_type.startswith("q35") or machine_type.startswith("arm64"): qbus_type = "PCIE" devices = [] vfsd = qdevices.QCustomDevice('chardev null,id=serial_vfsd', aobject='fs', child_bus=qdevices.QUnixSocketBus( sock_path, 'fs')) devices.append(vfsd) char_params = Params() char_params["backend"] = "socket" char_params["id"] = 'virtiofs_fs' sock_bus = {'busid': sock_path} char = qdevices.CharDevice(char_params, parent_bus=sock_bus) char.set_aid('virtiofs_fs') devices.append(char) qdriver = "vhost-user-fs" if "-mmio:" in machine_type: qdriver += "-device" qbus_type = "virtio-bus" elif machine_type.startswith("s390"): qdriver += "-ccw" qbus_type = "virtio-bus" else: qdriver += "-pci" bus = {"type": qbus_type} dev_params = { "id": "vufs_virtiofs_fs", "chardev": char.get_qid(), "tag": target } fs_driver_props = json.loads(params.get("fs_driver_props", "{}")) dev_params.update(fs_driver_props) vufs = qdevices.QDevice(qdriver, params=dev_params, parent_bus=bus) vufs.set_aid('virtiofs_fs') devices.append(vufs) vm.devices.insert(devices) # Since if 'redirs' has a value, the vm.create() method will reset the devices. # So set 'redirs' to empty for a workaround. vm.params['redirs'] = '' vm.create() vm.verify_alive() is_windows = params.get("os_type") == "windows" session = vm.wait_for_login() if is_windows: cmd_timeout = params.get_numeric("cmd_timeout", 120) driver_name = params["driver_name"] install_path = params["install_path"] check_installed_cmd = params["check_installed_cmd"] % install_path # Check whether windows driver is running,and enable driver verifier session = utils_test.qemu.windrv_check_running_verifier( session, vm, test, driver_name) # Install winfsp tool error_context.context("Install winfsp for windows guest.", logging.info) is_installed = session.cmd_status(check_installed_cmd) == 0 if is_installed: logging.info("Winfsp tool is already installed.") else: install_cmd = utils_misc.set_winutils_letter( session, params["install_cmd"]) session.cmd(install_cmd, cmd_timeout) if not utils_misc.wait_for( lambda: not session.cmd_status(check_installed_cmd), 60): test.error("Winfsp tool is not installed.") fs_params = params.object_params('fs') fs_target = fs_params.get("fs_target") fs_dest = fs_params.get("fs_dest") host_data = os.path.join(fs_source, 'fs_test') if not is_windows: error_context.context( "Create a destination directory %s " "inside guest." % fs_dest, logging.info) utils_misc.make_dirs(fs_dest, session) error_context.context( "Mount virtiofs target %s to %s inside" " guest." % (fs_target, fs_dest), logging.info) if not utils_disk.mount( fs_target, fs_dest, 'virtiofs', session=session): test.fail('Mount virtiofs target failed.') else: error_context.context("Start virtiofs service in guest.", logging.info) viofs_sc_create_cmd = params["viofs_sc_create_cmd"] viofs_sc_start_cmd = params["viofs_sc_start_cmd"] viofs_sc_query_cmd = params["viofs_sc_query_cmd"] logging.info("Check if virtiofs service is registered.") status, output = session.cmd_status_output(viofs_sc_query_cmd) if "not exist as an installed service" in output: logging.info("Register virtiofs service in windows guest.") exe_path = get_viofs_exe(session) viofs_sc_create_cmd = viofs_sc_create_cmd % exe_path sc_create_s, sc_create_o = session.cmd_status_output( viofs_sc_create_cmd) if sc_create_s != 0: test.fail("Failed to register virtiofs service, output is %s" % sc_create_o) logging.info("Check if virtiofs service is started.") status, output = session.cmd_status_output(viofs_sc_query_cmd) if "RUNNING" not in output: logging.info("Start virtiofs service.") sc_start_s, sc_start_o = session.cmd_status_output( viofs_sc_start_cmd) if sc_start_s != 0: test.fail("Failed to start virtiofs service, output is %s" % sc_start_o) else: logging.info("Virtiofs service is running.") # get fs dest for vm virtio_fs_disk_label = fs_target error_context.context( "Get Volume letter of virtio fs target, the disk" "lable is %s." % virtio_fs_disk_label, logging.info) vol_con = "VolumeName='%s'" % virtio_fs_disk_label vol_func = utils_misc.get_win_disk_vol(session, condition=vol_con) volume_letter = utils_misc.wait_for(lambda: vol_func, 120) if volume_letter is None: test.fail("Could not get virtio-fs mounted volume letter.") fs_dest = "%s:" % volume_letter guest_file = os.path.join(fs_dest, 'fs_test') logging.info("The guest file in shared dir is %s.", guest_file) try: # No extended attributes (file steams) in virtio-fs for windows if not is_windows: if cmd_set_trusted: error_context.context( "Trusted attribute test without " "%s for linux guest" % capability, logging.info) host_attributes = params["host_attributes"] guest_trusted = params["guest_trusted"] file_capability = params["file_capability"] logging.info("Set a trusted on guest.") session.cmd(cmd_yum_attr) session.cmd(cmd_set_trusted) output = session.cmd_output(cmd_get_trusted) logging.info( "Failed to check the trusted attribute from " "guest, the output is %s.", output) if guest_trusted not in output: test.fail( "It's failed to check the trusted info from the guest." ) process.run(cmd_yum_attr) output = str( process.run('getfattr %s' % fs_source).stdout.strip()) logging.info("The host file trusted is %s.", output) if host_attributes not in output: test.fail("Failed to check the trusted attribute from " "host, the output is %s." % output) session.cmd(cmd_create_file) error_context.context( "Privileged capabilities test without " "%s for linux guest" % capability, logging.info) session.cmd(cmd_set_capability) output = session.cmd_output(cmd_get_capability) logging.info("The guest file capability is %s.", output) if file_capability not in output: test.fail("Failed to check the trusted attribute from " "guest, the output is %s." % output) logging.info( "Modify file content and check the file capability.") session.cmd(cmd_echo_file) output = session.cmd_output(cmd_get_capability) logging.info("The guest change file capability is %s.", output) if file_capability in output: test.fail( "Still can get capability after file content is changed." ) if cmd_dd: error_context.context( "Creating file under %s inside guest." % fs_dest, logging.info) session.cmd(cmd_dd % guest_file, io_timeout) if not is_windows: cmd_md5_vm = cmd_md5 % guest_file else: guest_file_win = guest_file.replace("/", "\\") cmd_md5_vm = cmd_md5 % (volume_letter, guest_file_win) md5_guest = session.cmd_output(cmd_md5_vm, io_timeout).strip().split()[0] logging.info(md5_guest) md5_host = process.run("md5sum %s" % host_data, io_timeout).stdout_text.strip().split()[0] if md5_guest != md5_host: test.fail('The md5 value of host is not same to guest.') finally: if not is_windows: utils_disk.umount(fs_target, fs_dest, 'virtiofs', session=session) utils_misc.safe_rmdir(fs_dest, session=session) session.close() vm.destroy() utils_misc.safe_rmdir(fs_source)
def run(test, params, env): """ Test virtio-fs by sharing the data between host and guest. Steps: 1. Create shared directories on the host. 2. Run virtiofsd daemons on the host. 3. Boot a guest on the host with virtiofs options. 4. Log into guest then mount the virtiofs targets. 5. Generate files or run stress on the mount points inside guest. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_viofs_exe(session): """ Get viofs.exe from virtio win iso,such as E:\viofs\2k19\amd64 """ logging.info("Get virtiofs exe full path.") media_type = params["virtio_win_media_type"] try: get_drive_letter = getattr(virtio_win, "drive_letter_%s" % media_type) get_product_dirname = getattr(virtio_win, "product_dirname_%s" % media_type) get_arch_dirname = getattr(virtio_win, "arch_dirname_%s" % media_type) except AttributeError: test.error("Not supported virtio win media type '%s'", media_type) viowin_ltr = get_drive_letter(session) if not viowin_ltr: test.error("Could not find virtio-win drive in guest") guest_name = get_product_dirname(session) if not guest_name: test.error("Could not get product dirname of the vm") guest_arch = get_arch_dirname(session) if not guest_arch: test.error("Could not get architecture dirname of the vm") exe_middle_path = ("{name}\\{arch}" if media_type == "iso" else "{arch}\\{name}").format(name=guest_name, arch=guest_arch) exe_file_name = "virtiofs.exe" exe_find_cmd = 'dir /b /s %s\\%s | findstr "\\%s\\\\"' exe_find_cmd %= (viowin_ltr, exe_file_name, exe_middle_path) exe_path = session.cmd(exe_find_cmd).strip() logging.info("Found exe file '%s'", exe_path) return exe_path # data io config cmd_dd = params.get('cmd_dd') cmd_md5 = params.get('cmd_md5') cmd_new_folder = params.get('cmd_new_folder') cmd_copy_file = params.get('cmd_copy_file') cmd_del_folder = params.get('cmd_del_folder') # pjdfs test config cmd_pjdfstest = params.get('cmd_pjdfstest') cmd_unpack = params.get('cmd_unpack') cmd_yum_deps = params.get('cmd_yum_deps') cmd_autoreconf = params.get('cmd_autoreconf') cmd_configure = params.get('cmd_configure') cmd_make = params.get('cmd_make') pjdfstest_pkg = params.get('pjdfstest_pkg') username = params.get('username') password = params.get('password') port = params.get('file_transfer_port') # fio config fio_options = params.get('fio_options') io_timeout = params.get_numeric('io_timeout') # xfstest config cmd_xfstest = params.get('cmd_xfstest') fs_dest_fs2 = params.get('fs_dest_fs2') cmd_download_xfstest = params.get('cmd_download_xfstest') cmd_yum_install = params.get('cmd_yum_install') cmd_make_xfs = params.get('cmd_make_xfs') cmd_setenv = params.get('cmd_setenv') cmd_setenv_nfs = params.get('cmd_setenv_nfs', '') cmd_useradd = params.get('cmd_useradd') fs_dest_fs1 = params.get('fs_dest_fs1') cmd_get_tmpfs = params.get('cmd_get_tmpfs') cmd_set_tmpfs = params.get('cmd_set_tmpfs') size_mem1 = params.get('size_mem1') # xfstest-nfs config setup_local_nfs = params.get('setup_local_nfs') if cmd_xfstest: # /dev/shm is the default memory-backend-file, the default value is the # half of the host memory. Increase it to guest memory size to avoid crash ori_tmpfs_size = process.run(cmd_get_tmpfs, shell=True).stdout_text.replace("\n", "") logging.debug("original tmpfs size is %s", ori_tmpfs_size) params["post_command"] = cmd_set_tmpfs % ori_tmpfs_size params["pre_command"] = cmd_set_tmpfs % size_mem1 if setup_local_nfs: for fs in params.objects("filesystems"): nfs_params = params.object_params(fs) params["export_dir"] = nfs_params.get("export_dir") params["nfs_mount_src"] = nfs_params.get("nfs_mount_src") params["nfs_mount_dir"] = nfs_params.get("fs_source_dir") nfs_local = nfs.Nfs(params) nfs_local.setup() params["start_vm"] = "yes" env_process.preprocess(test, params, env) os_type = params.get("os_type") vm = env.get_vm(params.get("main_vm")) vm.verify_alive() session = vm.wait_for_login() host_addr = vm.get_address() if os_type == "windows": cmd_timeout = params.get_numeric("cmd_timeout", 120) driver_name = params["driver_name"] install_path = params["install_path"] check_installed_cmd = params["check_installed_cmd"] % install_path # Check whether windows driver is running,and enable driver verifier session = utils_test.qemu.windrv_check_running_verifier(session, vm, test, driver_name) # install winfsp tool error_context.context("Install winfsp for windows guest.", logging.info) installed = session.cmd_status(check_installed_cmd) == 0 if installed: logging.info("Winfsp tool is already installed.") else: install_cmd = utils_misc.set_winutils_letter(session, params["install_cmd"]) session.cmd(install_cmd, cmd_timeout) if not utils_misc.wait_for(lambda: not session.cmd_status( check_installed_cmd), 60): test.error("Winfsp tool is not installed.") for fs in params.objects("filesystems"): fs_params = params.object_params(fs) fs_target = fs_params.get("fs_target") fs_dest = fs_params.get("fs_dest") fs_source = fs_params.get("fs_source_dir") base_dir = fs_params.get("fs_source_base_dir", data_dir.get_data_dir()) if not os.path.isabs(fs_source): fs_source = os.path.join(base_dir, fs_source) host_data = os.path.join(fs_source, 'fs_test') if os_type == "linux": error_context.context("Create a destination directory %s " "inside guest." % fs_dest, logging.info) utils_misc.make_dirs(fs_dest, session) if not cmd_xfstest: error_context.context("Mount virtiofs target %s to %s inside" " guest." % (fs_target, fs_dest), logging.info) if not utils_disk.mount(fs_target, fs_dest, 'virtiofs', session=session): test.fail('Mount virtiofs target failed.') else: error_context.context("Start virtiofs service in guest.", logging.info) viofs_sc_create_cmd = params["viofs_sc_create_cmd"] viofs_sc_start_cmd = params["viofs_sc_start_cmd"] viofs_sc_query_cmd = params["viofs_sc_query_cmd"] logging.info("Check if virtiofs service is registered.") status, output = session.cmd_status_output(viofs_sc_query_cmd) if "not exist as an installed service" in output: logging.info("Register virtiofs service in windows guest.") exe_path = get_viofs_exe(session) viofs_sc_create_cmd = viofs_sc_create_cmd % exe_path sc_create_s, sc_create_o = session.cmd_status_output(viofs_sc_create_cmd) if sc_create_s != 0: test.fail("Failed to register virtiofs service, output is %s" % sc_create_o) logging.info("Check if virtiofs service is started.") status, output = session.cmd_status_output(viofs_sc_query_cmd) if "RUNNING" not in output: logging.info("Start virtiofs service.") sc_start_s, sc_start_o = session.cmd_status_output(viofs_sc_start_cmd) if sc_start_s != 0: test.fail("Failed to start virtiofs service, output is %s" % sc_start_o) else: logging.info("Virtiofs service is running.") viofs_log_file_cmd = params.get("viofs_log_file_cmd") if viofs_log_file_cmd: error_context.context("Check if LOG file is created.", logging.info) log_dir_s = session.cmd_status(viofs_log_file_cmd) if log_dir_s != 0: test.fail("Virtiofs log is not created.") # get fs dest for vm virtio_fs_disk_label = fs_target error_context.context("Get Volume letter of virtio fs target, the disk" "lable is %s." % virtio_fs_disk_label, logging.info) vol_con = "VolumeName='%s'" % virtio_fs_disk_label vol_func = utils_misc.get_win_disk_vol(session, condition=vol_con) volume_letter = utils_misc.wait_for(lambda: vol_func, cmd_timeout) if volume_letter is None: test.fail("Could not get virtio-fs mounted volume letter.") fs_dest = "%s:" % volume_letter guest_file = os.path.join(fs_dest, 'fs_test') logging.info("The guest file in shared dir is %s", guest_file) try: if cmd_dd: error_context.context("Creating file under %s inside " "guest." % fs_dest, logging.info) session.cmd(cmd_dd % guest_file, io_timeout) if os_type == "linux": cmd_md5_vm = cmd_md5 % guest_file else: guest_file_win = guest_file.replace("/", "\\") cmd_md5_vm = cmd_md5 % (volume_letter, guest_file_win) md5_guest = session.cmd_output(cmd_md5_vm, io_timeout).strip().split()[0] logging.info(md5_guest) md5_host = process.run("md5sum %s" % host_data, io_timeout).stdout_text.strip().split()[0] if md5_guest != md5_host: test.fail('The md5 value of host is not same to guest.') if cmd_new_folder and cmd_copy_file and cmd_del_folder: error_context.context("Folder test under %s inside " "guest." % fs_dest, logging.info) session.cmd(cmd_new_folder % fs_dest) test_file = guest_file if os_type == "linux" \ else "%s:\\%s" % (volume_letter, 'fs_test') session.cmd(cmd_copy_file % (test_file, fs_dest)) session.cmd(cmd_del_folder % fs_dest) if fio_options: error_context.context("Run fio on %s." % fs_dest, logging.info) fio = generate_instance(params, vm, 'fio') try: fio.run(fio_options % guest_file, io_timeout) finally: fio.clean() vm.verify_dmesg() if cmd_pjdfstest: error_context.context("Run pjdfstest on %s." % fs_dest, logging.info) host_path = os.path.join(data_dir.get_deps_dir('pjdfstest'), pjdfstest_pkg) scp_to_remote(host_addr, port, username, password, host_path, fs_dest) session.cmd(cmd_unpack.format(fs_dest), 180) session.cmd(cmd_yum_deps, 180) session.cmd(cmd_autoreconf % fs_dest, 180) session.cmd(cmd_configure.format(fs_dest), 180) session.cmd(cmd_make % fs_dest, io_timeout) session.cmd(cmd_pjdfstest % fs_dest, io_timeout) if cmd_xfstest: error_context.context("Run xfstest on guest.", logging.info) utils_misc.make_dirs(fs_dest_fs2, session) if session.cmd_status(cmd_download_xfstest, 360): test.error("Failed to download xfstests-dev") session.cmd(cmd_yum_install, 180) session.cmd(cmd_make_xfs, 360) session.cmd(cmd_setenv, 180) session.cmd(cmd_setenv_nfs, 180) session.cmd(cmd_useradd, 180) try: output = session.cmd_output(cmd_xfstest, io_timeout) logging.info("%s", output) if 'Failed' in output: test.fail('The xfstest failed.') else: break except (aexpect.ShellStatusError, aexpect.ShellTimeoutError): test.fail('The xfstest failed.') finally: if os_type == "linux": utils_disk.umount(fs_target, fs_dest, 'virtiofs', session=session) utils_misc.safe_rmdir(fs_dest, session=session) if setup_local_nfs: session.close() vm.destroy() for fs in params.objects("filesystems"): nfs_params = params.object_params(fs) params["export_dir"] = nfs_params.get("export_dir") params["nfs_mount_dir"] = nfs_params.get("fs_source_dir") params["rm_export_dir"] = nfs_params.get("export_dir") params["rm_mount_dir"] = nfs_params.get("fs_source_dir") nfs_local = nfs.Nfs(params) nfs_local.cleanup() utils_misc.safe_rmdir(params["export_dir"]) # during all virtio fs is mounted, reboot vm if params.get('reboot_guest', 'no') == 'yes': def get_vfsd_num(): """ Get virtiofsd daemon number during vm boot up. :return: virtiofsd daemon count. """ cmd_ps_virtiofsd = params.get('cmd_ps_virtiofsd') vfsd_num = 0 for device in vm.devices: if isinstance(device, qdevices.QVirtioFSDev): sock_path = device.get_param('sock_path') cmd_ps_virtiofsd = cmd_ps_virtiofsd % sock_path vfsd_ps = process.system_output(cmd_ps_virtiofsd, shell=True) vfsd_num += len(vfsd_ps.strip().splitlines()) return vfsd_num error_context.context("Check virtiofs daemon before reboot vm.", logging.info) vfsd_num_bf = get_vfsd_num() error_context.context("Reboot guest and check virtiofs daemon.", logging.info) vm.reboot() if not vm.is_alive(): test.fail("After rebooting vm quit unexpectedly.") vfsd_num_af = get_vfsd_num() if vfsd_num_bf != vfsd_num_af: test.fail("Virtiofs daemon is different before and after reboot.\n" "Before reboot: %s\n" "After reboot: %s\n", (vfsd_num_bf, vfsd_num_af))
def run(test, params, env): """ Test to virtio-fs with the multiple VMs and virtiofs daemons. Steps: 1. Create shared directories on the host. 2. Run virtiofs daemons on the host. 3. Boot guests on the host with virtiofs options. 4. Log into guest then mount the virtiofs targets. 5. Generate files on the mount points inside guests. 6. Compare the md5 among guests if multiple virtiofs daemons share the source. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_viofs_exe(session): """ Get viofs.exe from virtio win iso,such as E:\viofs\2k19\amd64 """ media_type = params["virtio_win_media_type"] try: get_drive_letter = getattr(virtio_win, "drive_letter_%s" % media_type) get_product_dirname = getattr(virtio_win, "product_dirname_%s" % media_type) get_arch_dirname = getattr(virtio_win, "arch_dirname_%s" % media_type) except AttributeError: test.error("Not supported virtio win media type '%s'", media_type) viowin_ltr = get_drive_letter(session) if not viowin_ltr: test.error("Could not find virtio-win drive in guest") guest_name = get_product_dirname(session) if not guest_name: test.error("Could not get product dirname of the vm") guest_arch = get_arch_dirname(session) if not guest_arch: test.error("Could not get architecture dirname of the vm") exe_middle_path = ("{name}\\{arch}" if media_type == "iso" else "{arch}\\{name}").format(name=guest_name, arch=guest_arch) exe_file_name = "virtiofs.exe" exe_find_cmd = 'dir /b /s %s\\%s | findstr "\\%s\\\\"' exe_find_cmd %= (viowin_ltr, exe_file_name, exe_middle_path) exe_path = session.cmd(exe_find_cmd).strip() logging.info("Found exe file '%s'", exe_path) return exe_path cmd_dd = params.get('cmd_dd') cmd_md5 = params.get('cmd_md5') io_timeout = params.get_numeric('io_timeout') shared_fs_source_dir = params.get('shared_fs_source_dir') os_type = params.get('os_type') # cfg for windows vm cmd_timeout = params.get_numeric("cmd_timeout", 120) driver_name = params.get("driver_name") wfsp_install_cmd = params.get("wfsp_install_cmd") check_installed_cmd = params.get("check_installed_cmd") sessions = [] vms = env.get_all_vms() for vm in vms: vm.verify_alive() sessions.append(vm.wait_for_login()) mapping = {} for vm, session in zip(params.objects('vms'), sessions): vm_params = params.object_params(vm) mapping[vm] = {'session': session, 'filesystems': []} # check driver verifier in windows vm # install winfsp tool and start virtiofs exe in windows vm if os_type == "windows": # Check whether windows driver is running,and enable driver verifier session = utils_test.qemu.windrv_check_running_verifier( session, vm, test, driver_name) error_context.context("%s: Install winfsp for windows guest." % vm, logging.info) installed = session.cmd_status(check_installed_cmd) == 0 if installed: logging.info("%s: Winfsp tool is already installed.", vm) else: install_cmd = utils_misc.set_winutils_letter( session, wfsp_install_cmd) session.cmd(install_cmd, cmd_timeout) if not utils_misc.wait_for( lambda: not session.cmd_status(check_installed_cmd), 60): test.error("%s: Winfsp tool is not installed." % vm) error_context.context("%s: Start virtiofs service in guest." % vm, logging.info) exe_path = get_viofs_exe(session) start_vfs_cmd = params["start_vfs_cmd"] % exe_path session.sendline(start_vfs_cmd) error_context.context( "%s: Check if virtiofs service is started." % vm, logging.info) check_virtiofs_cmd = params["check_virtiofs_cmd"] if not utils_misc.wait_for( lambda: re.search("virtiofs", session.cmd_output(check_virtiofs_cmd), re.IGNORECASE), 30): test.fail("%s: Virtiofs service is failed to start." % vm) # get fs dest for vm for fs in vm_params.objects('filesystems'): fs_params = vm_params.object_params(fs) fs_target = fs_params.get("fs_target") fs_dest = fs_params.get("fs_dest") if os_type == "linux": error_context.context( "%s: Create a destination directory %s inside guest." % (vm, fs_dest), logging.info) utils_misc.make_dirs(fs_dest, session) error_context.context( "%s: Mount the virtiofs target %s to %s inside guest." % (vm, fs_target, fs_dest), logging.info) utils_disk.mount(fs_target, fs_dest, 'virtiofs', session=session) else: virtio_fs_disk_label = fs_target error_context.context( "%s: Get Volume letter of virtio fs" " target, the disk lable is %s." % (vm, virtio_fs_disk_label), logging.info) vol_con = "VolumeName='%s'" % virtio_fs_disk_label vol_func = utils_misc.get_win_disk_vol(session, condition=vol_con) volume_letter = utils_misc.wait_for(lambda: vol_func, cmd_timeout) fs_dest = "%s:" % volume_letter guest_file = os.path.join(fs_dest, 'fs_test') logging.info("%s: The guest file in shared dir is %s", vm, guest_file) mapping[vm]['filesystems'].append({ 'fs_target': fs_target, 'fs_dest': fs_dest, 'guest_file': guest_file }) if cmd_dd: logging.info("%s: Creating file under %s inside guest.", vm, fs_dest) session.cmd(cmd_dd % guest_file, io_timeout) if shared_fs_source_dir: continue if os_type == "linux": error_context.context( "%s: Umount the viriofs target %s." % (vm, fs_target), logging.info) utils_disk.umount(fs_target, fs_dest, 'virtiofs', session=session) if shared_fs_source_dir: error_context.context("Compare the md5 among VMs.", logging.info) md5_set = set() for vm, info in mapping.items(): session = info['session'] for fs in info['filesystems']: shared_data = fs['guest_file'] error_context.context( "%s: Get the md5 of %s." % (vm, shared_data), logging.info) if os_type == "linux": cmd_md5_vm = cmd_md5 % shared_data else: guest_file_win = shared_data.replace("/", "\\") cmd_md5_vm = cmd_md5 % (volume_letter, guest_file_win) md5_guest = session.cmd(cmd_md5_vm, io_timeout).strip().split()[0] logging.info(md5_guest) md5_set.add(md5_guest) if os_type == "linux": error_context.context( "%s: Umount the viriofs target %s." % (vm, fs['fs_target']), logging.info) utils_disk.umount(fs['fs_target'], fs['fs_dest'], 'virtiofs', session=session) if len(md5_set) != 1: test.fail('The md5 values are different among VMs.')
def run(test, params, env): """ Test virtio-fs by sharing the data between host and guest. Steps: 1. Create shared directories on the host. 2. Run virtiofsd daemons on the host. 3. Boot a guest on the host with virtiofs options. 4. Log into guest then mount the virtiofs targets. 5. Generate files or run stress on the mount points inside guest. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_viofs_exe(session): """ Get viofs.exe from virtio win iso,such as E:\viofs\2k19\amd64 """ media_type = params["virtio_win_media_type"] try: get_drive_letter = getattr(virtio_win, "drive_letter_%s" % media_type) get_product_dirname = getattr(virtio_win, "product_dirname_%s" % media_type) get_arch_dirname = getattr(virtio_win, "arch_dirname_%s" % media_type) except AttributeError: test.error("Not supported virtio win media type '%s'", media_type) viowin_ltr = get_drive_letter(session) if not viowin_ltr: test.error("Could not find virtio-win drive in guest") guest_name = get_product_dirname(session) if not guest_name: test.error("Could not get product dirname of the vm") guest_arch = get_arch_dirname(session) if not guest_arch: test.error("Could not get architecture dirname of the vm") exe_middle_path = ("{name}\\{arch}" if media_type == "iso" else "{arch}\\{name}").format(name=guest_name, arch=guest_arch) exe_file_name = "virtiofs.exe" exe_find_cmd = 'dir /b /s %s\\%s | findstr "\\%s\\\\"' exe_find_cmd %= (viowin_ltr, exe_file_name, exe_middle_path) exe_path = session.cmd(exe_find_cmd).strip() logging.info("Found exe file '%s'", exe_path) return exe_path # data io config cmd_dd = params.get('cmd_dd') cmd_md5 = params.get('cmd_md5') # pjdfs test config cmd_pjdfstest = params.get('cmd_pjdfstest') cmd_unpack = params.get('cmd_unpack') cmd_yum_deps = params.get('cmd_yum_deps') cmd_autoreconf = params.get('cmd_autoreconf') cmd_configure = params.get('cmd_configure') cmd_make = params.get('cmd_make') pjdfstest_pkg = params.get('pjdfstest_pkg') username = params.get('username') password = params.get('password') port = params.get('file_transfer_port') # fio config fio_options = params.get('fio_options') io_timeout = params.get_numeric('io_timeout') os_type = params.get("os_type") vm = env.get_vm(params.get("main_vm")) vm.verify_alive() session = vm.wait_for_login() host_addr = vm.get_address() if os_type == "windows": cmd_timeout = params.get_numeric("cmd_timeout", 120) driver_name = params["driver_name"] install_path = params["install_path"] check_installed_cmd = params["check_installed_cmd"] % install_path # Check whether windows driver is running,and enable driver verifier session = utils_test.qemu.windrv_check_running_verifier(session, vm, test, driver_name) # install winfsp tool error_context.context("Install winfsp for windows guest.", logging.info) installed = session.cmd_status(check_installed_cmd) == 0 if installed: logging.info("Winfsp tool is already installed.") else: install_cmd = utils_misc.set_winutils_letter(session, params["install_cmd"]) session.cmd(install_cmd, cmd_timeout) if not utils_misc.wait_for(lambda: not session.cmd_status( check_installed_cmd), 60): test.error("Winfsp tool is not installed.") for fs in params.objects("filesystems"): fs_params = params.object_params(fs) fs_target = fs_params.get("fs_target") fs_dest = fs_params.get("fs_dest") fs_source = fs_params.get("fs_source_dir") base_dir = fs_params.get("fs_source_base_dir", data_dir.get_data_dir()) if not os.path.isabs(fs_source): fs_source = os.path.join(base_dir, fs_source) host_data = os.path.join(fs_source, 'fs_test') if os_type == "linux": error_context.context("Create a destination directory %s " "inside guest." % fs_dest, logging.info) utils_misc.make_dirs(fs_dest, session) error_context.context("Mount virtiofs target %s to %s inside" " guest." % (fs_target, fs_dest), logging.info) utils_disk.mount(fs_target, fs_dest, 'virtiofs', session=session) else: error_context.context("Start virtiofs service in guest.", logging.info) exe_path = get_viofs_exe(session) start_vfs_cmd = params["start_vfs_cmd"] % exe_path session.sendline(start_vfs_cmd) error_context.context("Check if virtiofs service is started.", logging.info) check_virtiofs_cmd = params["check_virtiofs_cmd"] if not utils_misc.wait_for(lambda: re.search("virtiofs", session.cmd_output( check_virtiofs_cmd), re.IGNORECASE), 30): test.fail("Virtiofs service is failed to start.") virtio_fs_disk_label = fs_target error_context.context("Get Volume letter of virtio fs target, the disk" "lable is %s." % virtio_fs_disk_label, logging.info) vol_con = "VolumeName='%s'" % virtio_fs_disk_label vol_func = utils_misc.get_win_disk_vol(session, condition=vol_con) volume_letter = utils_misc.wait_for(lambda: vol_func, cmd_timeout) fs_dest = "%s:" % volume_letter guest_file = os.path.join(fs_dest, 'fs_test') logging.info("The guest file in shared dir is %s" % guest_file) try: if cmd_dd: logging.info("Creating file under %s inside guest." % fs_dest) session.cmd(cmd_dd % guest_file, io_timeout) if os_type == "linux": cmd_md5_vm = cmd_md5 % guest_file else: guest_file_win = guest_file.replace("/", "\\") cmd_md5_vm = cmd_md5 % (volume_letter, guest_file_win) md5_guest = session.cmd_output(cmd_md5_vm, io_timeout).strip().split()[0] logging.info(md5_guest) md5_host = process.run("md5sum %s" % host_data, io_timeout).stdout_text.strip().split()[0] if md5_guest != md5_host: test.fail('The md5 value of host is not same to guest.') if fio_options: error_context.context("Run fio on %s." % fs_dest, logging.info) fio = generate_instance(params, vm, 'fio') try: fio.run(fio_options % guest_file, io_timeout) finally: fio.clean() vm.verify_dmesg() if cmd_pjdfstest: error_context.context("Run pjdfstest on %s." % fs_dest, logging.info) host_path = os.path.join(data_dir.get_deps_dir('pjdfstest'), pjdfstest_pkg) scp_to_remote(host_addr, port, username, password, host_path, fs_dest) session.cmd(cmd_unpack.format(fs_dest), 180) session.cmd(cmd_yum_deps, 180) session.cmd(cmd_autoreconf % fs_dest, 180) session.cmd(cmd_configure.format(fs_dest), 180) session.cmd(cmd_make % fs_dest, io_timeout) session.cmd(cmd_pjdfstest % fs_dest, io_timeout) finally: if os_type == "linux": utils_disk.umount(fs_target, fs_dest, 'virtiofs', session=session) utils_misc.safe_rmdir(fs_dest, session=session)