From b90d76630bd3325221a7f4f6cbdfc3b2a16e9d62 Mon Sep 17 00:00:00 2001 From: nanli Date: Wed, 21 Jun 2023 17:02:39 +0800 Subject: [PATCH] memory: add case for hugepage mount path VIRT-297104: Huge page mount path Signed-off-by: nanli --- .../memory_backing/hugepage_mount_path.cfg | 41 ++++ .../memory_backing/hugepage_mount_path.py | 185 ++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 libvirt/tests/cfg/memory/memory_backing/hugepage_mount_path.cfg create mode 100644 libvirt/tests/src/memory/memory_backing/hugepage_mount_path.py diff --git a/libvirt/tests/cfg/memory/memory_backing/hugepage_mount_path.cfg b/libvirt/tests/cfg/memory/memory_backing/hugepage_mount_path.cfg new file mode 100644 index 00000000000..6817a3d6637 --- /dev/null +++ b/libvirt/tests/cfg/memory/memory_backing/hugepage_mount_path.cfg @@ -0,0 +1,41 @@ +- memory.backing.mount_path: + type = hugepage_mount_path + mem_value = 2097152 + set_pagesize_1 = "1048576" + set_pagenum_1 = "2" + set_pagesize_2 = "2048" + set_pagenum_2 = "3072" + security_context = "drwxr-xr-x. 3 root root system_u:object_r:hugetlbfs_t:s0" + log_path = "/var/log/libvirt/qemu/%s.log" + guest_log_error1 = "hugepage is not mounted" + guest_log_error2 = "unable to create backing store for hugepages: Permission denied" + page_unit = "KiB" + page_size = "2048" + numa_size = 1048576 + mem_unit = "KiB" + mem_value = 2097152 + current_mem = 2097152 + max_mem = 15242880 + memory_backing_dict = "'mb': {'hugepages': {'pages': [{'unit': '${page_unit}', 'size': '${page_size}'}]}}" + numa_cpu = {'numa_cell': [{'id': '0', 'cpus': '0-1', 'memory': '${numa_size}', 'unit': 'KiB'}, {'id': '1', 'cpus': '2-3', 'memory': '${numa_size}', 'unit': 'KiB'}]} + vm_attrs = {${memory_backing_dict},"cpu":${numa_cpu},'vcpu': 4,'max_mem_rt_slots': 16,'memory_unit':"${mem_unit}",'memory':${mem_value},'current_mem':${current_mem},'current_mem_unit':'KiB','max_mem_rt': ${max_mem}, 'max_mem_rt_unit': "KiB"} + start_vm = "no" + variants case: + - default: + hugepage_path = "/dev/hugepages1G" + mount_pagesize = "1G" + expect_state = "active" + check_qemu = ['"mem-path":"/dev/hugepages/libvirt/qemu/','"prealloc":true'] + attach_dict = {'mem_model': 'dimm', 'source': {"pagesize":1048576, "pagesize_unit":"KiB"},'target': {'size': 1048576, 'size_unit': 'KiB','node':0}} + check_security_cmd = "ls -l -Z /dev/hugepages/libvirt/qemu/ -d" + - disabled: + hugetlbfs_mount = '""' + expect_state = "failed" + - customized: + path = "/dev/hugetest" + hugepage_path = "${path}" + hugetlbfs_mount = "${path}" + expect_state = "active" + qemu_cmd_line = ["mem-path":"/dev/hugepages/libvirt/qemu/", ] + check_security_cmd = "ls -l -Z ${path}/libvirt/qemu -d" + check_qemu = ['"mem-path":"/dev/hugepages/libvirt/qemu/"','"prealloc":true'] diff --git a/libvirt/tests/src/memory/memory_backing/hugepage_mount_path.py b/libvirt/tests/src/memory/memory_backing/hugepage_mount_path.py new file mode 100644 index 00000000000..b1dc8227915 --- /dev/null +++ b/libvirt/tests/src/memory/memory_backing/hugepage_mount_path.py @@ -0,0 +1,185 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright Redhat +# +# SPDX-License-Identifier: GPL-2.0 + +# Author: Nan Li +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +import re + +from avocado.utils import process + +from virttest import utils_libvirtd +from virttest import utils_misc +from virttest import virsh +from virttest import test_setup + +from virttest.libvirt_xml import vm_xml +from virttest.libvirt_xml.devices import memory + +from virttest.utils_test import libvirt +from virttest.staging import utils_memory + + +def run(test, params, env): + """ + Verify the mount path config takes effect + Verify huge page path mount doesn't impact running guest vm + + """ + def setup_test(): + """ + Set hugepage on host and prepare guest + """ + test.log.info("TEST_SETUP: Set hugepage on host and prepare guest") + + hp_cfg = test_setup.HugePageConfig(params) + if case == "customized": + process.run("umount /dev/hugepages/; mount -t hugetlbfs hugetlbfs " + "%s" % hugepage_path, ignore_status=True) + hp_cfg.set_kernel_hugepages(set_pagesize_1, set_pagenum_1) + hp_cfg.set_kernel_hugepages(set_pagesize_2, set_pagenum_2) + + vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) + vmxml.setup_attrs(**vm_attrs) + virsh.define(vmxml.xml, debug=True, ignore_status=False) + + def run_test(): + """ + Define guest, start guest and check mem. + """ + test.log.info("TEST_STEP1: Modify the huge page mount path config ") + if case != "default": + qemu_obj = libvirt.customize_libvirt_config( + {"hugetlbfs_mount": hugetlbfs_mount}, "qemu", restart_libvirt=False) + params.update({"qemu_conf_obj": qemu_obj}) + process.run("cat /etc/libvirt/qemu.conf | grep huge", shell=True) + + test.log.info("TEST_STEP2: Restart libvirt service") + libvirtd = utils_libvirtd.Libvirtd() + process.run("systemctl restart %s" % libvirtd.service_name, shell=True) + + def _compare_state(): + state = process.run("systemctl is-active %s" % libvirtd.service_name, + shell=True, ignore_status=True).stdout_text.strip() + return state == expect_state + + if not utils_misc.wait_for(lambda: _compare_state(), timeout=20): + test.fail("Expect libvirt service state: '%s'" % expect_state) + else: + test.log.debug("Get expected '%s' libvirt service" % expect_state) + if case == "disabled": + return + + test.log.info("TEST_STEP3: Start guest guest") + vm.start() + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) + test.log.debug("Current vmxml is:\n %s", vmxml) + + test.log.info("TEST_STEP4: Check the qemu cmd line") + out_file = "output.txt" + process.run("ps -ef | grep qemu | grep prealloc > %s" % out_file, shell=True) + for item in check_qemu: + libvirt.check_logfile(item, out_file) + + test.log.info("TEST_STEP5: Check security context") + cmd_result = process.run(check_security_cmd, ignore_status=True, + shell=True).stdout_text + if not re.search(security_context, cmd_result): + test.fail("Expect get %s in %s" % (security_context, cmd_result)) + + test.log.info("TEST_STEP6: Check the guest log") + libvirt.check_logfile(err_1, log_path % vm_name, str_in_log=False) + libvirt.check_logfile(err_2, log_path % vm_name, str_in_log=False) + + if case == "customized": + return + + test.log.info("TEST_STEP7: Stop services") + utils_libvirtd.libvirtd_stop() + + test.log.info("TEST_STEP8: Mount hugepage path") + hp_cfg = test_setup.HugePageConfig(params) + hp_cfg.hugepage_size = mount_pagesize + hp_cfg.mount_hugepage_fs() + + test.log.info("TEST_STEP9: Do virsh list to check guest status") + output = virsh.dom_list("--all", debug=True).stdout.strip() + result = re.search(r".*%s.*%s.*" % (vm_name, "running"), output) + if not result: + test.fail("VM '{}' with the state running is not found".format(vm_name)) + + test.log.info("TEST_STEP10: Attach memory device") + mem_dev = memory.Memory() + mem_dev.setup_attrs(**attach_dict) + virsh.attach_device(vm.name, mem_dev.xml, debug=True, + ignore_status=False) + + test.log.info("TEST_STEP11: Check mem") + session = vm.wait_for_login() + mem_free = utils_memory.freememtotal(session) + status, stdout = session.cmd_status_output("swapoff -a; memhog %s" % ( + mem_free - 204800)) + if status: + raise test.fail("Failed to consume memory:%s", stdout) + + test.log.info("TEST_STEP12: Destroy the guest") + virsh.destroy(vm_name, ignore_status=False) + + test.log.info("TEST_STEP13: Restart service") + process.run("systemctl restart %s" % libvirtd.service_name, shell=True) + if not utils_misc.wait_for(lambda: _compare_state(), timeout=20): + test.fail("Expect libvirt service state: '%s'" % expect_state) + else: + test.log.debug("Get expected '%s' libvirt service" % expect_state) + + test.log.info("TEST_STEP14: Start the guest") + virsh.start(vm_name, ignore_status=False) + + def teardown_test(): + """ + Clean data. + """ + test.log.info("TEST_TEARDOWN: Clean up env.") + libvirt.customize_libvirt_config( + None, "qemu", config_object=params.get("qemu_conf_obj"), + is_recover=True) + bkxml.sync() + + hp_cfg = test_setup.HugePageConfig(params) + hp_cfg.cleanup() + + vm_name = params.get("main_vm") + vm = env.get_vm(vm_name) + vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) + bkxml = vmxml.copy() + + log_path = params.get("log_path") + err_1 = params.get("guest_log_error1") + err_2 = params.get("guest_log_error2") + hugetlbfs_mount = params.get("hugetlbfs_mount") + hugepage_path = params.get("hugepage_path") + + mount_pagesize = params.get("mount_pagesize", '{}') + set_pagesize_1 = params.get("set_pagesize_1") + set_pagenum_1 = params.get("set_pagenum_1") + set_pagesize_2 = params.get("set_pagesize_2") + set_pagenum_2 = params.get("set_pagenum_2") + + case = params.get("case") + check_security_cmd = params.get("check_security_cmd") + check_qemu = eval(params.get("check_qemu", '{}')) + security_context = params.get("security_context") + expect_state = params.get("expect_state") + attach_dict = eval(params.get("attach_dict", "{}")) + + vm_attrs = eval(params.get("vm_attrs", "{}")) + + try: + setup_test() + run_test() + + finally: + teardown_test() \ No newline at end of file