普通文本  |  128行  |  4.22 KB

import logging, time, commands, os, string, re
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.client.virt import virt_test_utils, aexpect, virt_test_setup


@error.context_aware
def run_trans_hugepage(test, params, env):
    """
    KVM kernel hugepages user side test:
    1) Smoke test
    2) Stress test

    @param test: KVM test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    def get_mem_status(params, type):
        if type == "host":
            info = utils.system_output("cat /proc/meminfo")
        else:
            info = session.cmd("cat /proc/meminfo")
        for h in re.split("\n+", info):
            if h.startswith("%s" % params):
                output = re.split('\s+', h)[1]
        return output

    dd_timeout = float(params.get("dd_timeout", 900))
    nr_ah = []
    mem = params['mem']
    failures = []

    debugfs_flag = 1
    debugfs_path = os.path.join(test.tmpdir, 'debugfs')
    mem_path = os.path.join("/tmp", 'thp_space')

    login_timeout = float(params.get("login_timeout", "3600"))

    error.context("smoke test setup")
    if not os.path.ismount(debugfs_path):
        if not os.path.isdir(debugfs_path):
            os.makedirs(debugfs_path)
        utils.run("mount -t debugfs none %s" % debugfs_path)

    test_config = virt_test_setup.TransparentHugePageConfig(test, params)
    vm = virt_test_utils.get_living_vm(env, params.get("main_vm"))
    session = virt_test_utils.wait_for_login(vm, timeout=login_timeout)

    try:
        # Check khugepage is used by guest
        test_config.setup()

        logging.info("Smoke test start")
        error.context("smoke test")

        nr_ah_before = get_mem_status('AnonHugePages', 'host')
        if nr_ah_before <= 0:
            e_msg = 'smoke: Host is not using THP'
            logging.error(e_msg)
            failures.append(e_msg)

        # Protect system from oom killer
        if int(get_mem_status('MemFree', 'guest')) / 1024 < mem :
            mem = int(get_mem_status('MemFree', 'guest')) / 1024

        session.cmd("mkdir -p %s" % mem_path)

        session.cmd("mount -t tmpfs -o size=%sM none %s" % (str(mem), mem_path))

        count = mem / 4
        session.cmd("dd if=/dev/zero of=%s/1 bs=4000000 count=%s" %
                    (mem_path, count), timeout=dd_timeout)

        nr_ah_after = get_mem_status('AnonHugePages', 'host')

        if nr_ah_after <= nr_ah_before:
            e_msg = ('smoke: Host did not use new THP during dd')
            logging.error(e_msg)
            failures.append(e_msg)

        if debugfs_flag == 1:
            if int(open('%s/kvm/largepages' % debugfs_path, 'r').read()) <= 0:
                e_msg = 'smoke: KVM is not using THP'
                logging.error(e_msg)
                failures.append(e_msg)

        logging.info("Smoke test finished")

        # Use parallel dd as stress for memory
        count = count / 3
        logging.info("Stress test start")
        error.context("stress test")
        cmd = "rm -rf %s/*; for i in `seq %s`; do dd " % (mem_path, count)
        cmd += "if=/dev/zero of=%s/$i bs=4000000 count=1& done;wait" % mem_path
        output = session.cmd_output(cmd, timeout=dd_timeout)

        if len(re.findall("No space", output)) > count * 0.05:
            e_msg = "stress: Too many dd instances failed in guest"
            logging.error(e_msg)
            failures.append(e_msg)

        try:
            output = session.cmd('pidof dd')
        except Exception:
            output = None

        if output is not None:
            for i in re.split('\n+', output):
                session.cmd('kill -9 %s' % i)

        session.cmd("umount %s" % mem_path)

        logging.info("Stress test finished")

    finally:
        error.context("all tests cleanup")
        if os.path.ismount(debugfs_path):
            utils.run("umount %s" % debugfs_path)
        if os.path.isdir(debugfs_path):
            os.removedirs(debugfs_path)
        session.close()
        test_config.cleanup()

    error.context("")
    if failures:
        raise error.TestFail("THP base test reported %s failures:\n%s" %
                             (len(failures), "\n".join(failures)))