|
| 1 | +import aexpect |
| 2 | +from avocado.utils import process |
| 3 | +from virttest import error_context, utils_disk, utils_misc, utils_test |
| 4 | + |
| 5 | +from provider import virtio_fs_utils |
| 6 | + |
| 7 | + |
| 8 | +@error_context.context_aware |
| 9 | +def run(test, params, env): |
| 10 | + """ |
| 11 | + Test virtio-fs rlimit-nofile. |
| 12 | + Steps: |
| 13 | + 1. Create a shared directory for testing on the host. |
| 14 | + 2. Touch 1024 files in the shared directory. |
| 15 | + 3. Start the virtiofsd daemon with rlimit-nofile and check. |
| 16 | +
|
| 17 | + :param test: QEMU test object. |
| 18 | + :param params: Dictionary with the test parameters. |
| 19 | + :param env: Dictionary with test environment. |
| 20 | + """ |
| 21 | + |
| 22 | + def create_service(session): |
| 23 | + if os_type == "windows": |
| 24 | + error_context.context("Create virtiofs service in guest.", test.log.info) |
| 25 | + |
| 26 | + driver_name = params["driver_name"] |
| 27 | + |
| 28 | + session = utils_test.qemu.windrv_check_running_verifier( |
| 29 | + session, vm, test, driver_name |
| 30 | + ) |
| 31 | + viofs_svc_name = params["viofs_svc_name"] |
| 32 | + virtio_fs_utils.create_viofs_service( |
| 33 | + test, params, session, service=viofs_svc_name |
| 34 | + ) |
| 35 | + return session |
| 36 | + |
| 37 | + def delete_service(): |
| 38 | + if os_type == "windows": |
| 39 | + error_context.context("Delete virtiofs service in guest.", test.log.info) |
| 40 | + session = vm.wait_for_login() |
| 41 | + virtio_fs_utils.delete_viofs_serivce(test, params, session) |
| 42 | + session.close() |
| 43 | + |
| 44 | + def start_service(session): |
| 45 | + fs = params["filesystems"] |
| 46 | + fs_params = params.object_params(fs) |
| 47 | + |
| 48 | + fs_target = fs_params["fs_target"] |
| 49 | + fs_dest = fs_params["fs_dest"] |
| 50 | + |
| 51 | + if os_type == "linux": |
| 52 | + utils_misc.make_dirs(fs_dest, session) |
| 53 | + error_context.context( |
| 54 | + "Mount virtiofs target %s to %s inside guest." % (fs_target, fs_dest), |
| 55 | + test.log.info, |
| 56 | + ) |
| 57 | + if not utils_disk.mount(fs_target, fs_dest, "virtiofs", session=session): |
| 58 | + utils_misc.safe_rmdir(fs_dest, session=session) |
| 59 | + test.fail("Failed to mount virtiofs %s." % fs_target) |
| 60 | + else: |
| 61 | + error_context.context("Start virtiofs service in guest.", test.log.info) |
| 62 | + debug_log_operation = params.get("debug_log_operation") |
| 63 | + if debug_log_operation: |
| 64 | + session = virtio_fs_utils.operate_debug_log( |
| 65 | + test, params, session, vm, debug_log_operation |
| 66 | + ) |
| 67 | + virtio_fs_utils.start_viofs_service(test, params, session) |
| 68 | + |
| 69 | + fs_dest = "%s:" % virtio_fs_utils.get_virtiofs_driver_letter( |
| 70 | + test, fs_target, session |
| 71 | + ) |
| 72 | + |
| 73 | + guest_mnts[fs_target] = fs_dest |
| 74 | + return session |
| 75 | + |
| 76 | + def stop_service(session): |
| 77 | + error_context.context("Stop virtiofs service in guest.", test.log.info) |
| 78 | + |
| 79 | + if os_type == "linux": |
| 80 | + for fs_target, fs_dest in guest_mnts.items(): |
| 81 | + utils_disk.umount(fs_target, fs_dest, "virtiofs", session=session) |
| 82 | + utils_misc.safe_rmdir(fs_dest, session=session) |
| 83 | + else: |
| 84 | + if guest_mnts: |
| 85 | + virtio_fs_utils.stop_viofs_service(test, params, session) |
| 86 | + session.close() |
| 87 | + |
| 88 | + rlimit_nofile = params.get("rlimit_nofile") |
| 89 | + cmd_run_virtiofsd = params["cmd_run_virtiofsd"] |
| 90 | + guest_mnts = dict() |
| 91 | + os_type = params["os_type"] |
| 92 | + |
| 93 | + if rlimit_nofile == "512": |
| 94 | + expected_msg = params["expected_msg"] |
| 95 | + error_context.context( |
| 96 | + "Starting virtiofsd with rlimit-nofile=%s" % rlimit_nofile, test.log.info |
| 97 | + ) |
| 98 | + result = process.run( |
| 99 | + cmd_run_virtiofsd, |
| 100 | + shell=True, |
| 101 | + ignore_status=True, |
| 102 | + verbose=True, |
| 103 | + ) |
| 104 | + # Prefer text-safe access for command output |
| 105 | + out = getattr(result, "stdout_text", None) |
| 106 | + if out is None: |
| 107 | + raw = getattr(result, "stdout", b"") |
| 108 | + out = raw.decode() if isinstance(raw, (bytes, bytearray)) else str(raw) |
| 109 | + status = result.exit_status |
| 110 | + if status == 0: |
| 111 | + test.fail( |
| 112 | + "virtiofsd unexpectedly started successfully with rlimit-nofile=512" |
| 113 | + ) |
| 114 | + elif expected_msg not in out: |
| 115 | + test.fail("virtiofsd failed but without expected message. Output: %s" % out) |
| 116 | + error_context.context( |
| 117 | + "virtiofsd failed as expected with the required message present", |
| 118 | + test.log.info, |
| 119 | + ) |
| 120 | + elif rlimit_nofile == "610": |
| 121 | + expected_msg = params["expected_msg"] |
| 122 | + error_context.context( |
| 123 | + "Starting virtiofsd with rlimit-nofile=%s" % rlimit_nofile, test.log.info |
| 124 | + ) |
| 125 | + session = aexpect.ShellSession( |
| 126 | + cmd_run_virtiofsd, |
| 127 | + auto_close=False, |
| 128 | + output_func=utils_misc.log_line, |
| 129 | + output_params=("virtiofs_fs-virtiofs.log",), |
| 130 | + prompt=r"^\[.*\][\#\$]\s*$", |
| 131 | + ) |
| 132 | + try: |
| 133 | + session.expect(expected_msg, timeout=10) |
| 134 | + test.log.info( |
| 135 | + "virtiofsd started successfully with the required message present" |
| 136 | + ) |
| 137 | + except aexpect.ExpectTimeout as e: |
| 138 | + test.fail("Timeout for virtiofsd start with rlimit-nofile=610: %s" % e) |
| 139 | + finally: |
| 140 | + session.close() |
| 141 | + elif rlimit_nofile == "1000": |
| 142 | + error_context.context( |
| 143 | + "Starting virtiofsd with rlimit-nofile=%s" % rlimit_nofile, test.log.info |
| 144 | + ) |
| 145 | + vm = env.get_vm(params.get("main_vm")) |
| 146 | + vm.verify_alive() |
| 147 | + session = vm.wait_for_login() |
| 148 | + try: |
| 149 | + session = create_service(session) |
| 150 | + session = start_service(session) |
| 151 | + for fs_dest in guest_mnts.values(): |
| 152 | + out = session.cmd_output(params["list_file_cmd"] % fs_dest).strip() |
| 153 | + test.log.debug("The dir output in guest: %s", out) |
| 154 | + if params["ls_check_content"] not in out: |
| 155 | + test.fail("Wrong content found: %s" % out) |
| 156 | + qemu_out = vm.process.get_output() |
| 157 | + if params["qemu_check_content"] not in qemu_out: |
| 158 | + test.fail("Wrong qemu content found: %s" % qemu_out) |
| 159 | + finally: |
| 160 | + stop_service(session) |
| 161 | + delete_service() |
| 162 | + elif rlimit_nofile == "2048": |
| 163 | + error_context.context( |
| 164 | + "Starting virtiofsd with rlimit-nofile=%s" % rlimit_nofile, test.log.info |
| 165 | + ) |
| 166 | + vm = env.get_vm(params.get("main_vm")) |
| 167 | + vm.verify_alive() |
| 168 | + session = vm.wait_for_login() |
| 169 | + try: |
| 170 | + session = create_service(session) |
| 171 | + session = start_service(session) |
| 172 | + for fs_dest in guest_mnts.values(): |
| 173 | + cmd = params["list_file_cmd"] % fs_dest |
| 174 | + status, output = session.cmd_status_output(cmd) |
| 175 | + output = output.strip() |
| 176 | + if status != 0: |
| 177 | + test.fail("list failed: %s" % output) |
| 178 | + finally: |
| 179 | + stop_service(session) |
| 180 | + delete_service() |
0 commit comments