blob: f915c1b747b3981e21899506755dee9ccc51ba1d [file] [log] [blame]
"""
Library to perform pre/post test setup for KVM autotest.
"""
import os, logging
from autotest_lib.client.common_lib import error
from autotest_lib.client.bin import utils
class HugePageConfig(object):
def __init__(self, params):
"""
Gets environment variable values and calculates the target number
of huge memory pages.
@param params: Dict like object containing parameters for the test.
"""
self.vms = len(params.objects("vms"))
self.mem = int(params.get("mem"))
self.max_vms = int(params.get("max_vms", 0))
self.hugepage_path = '/mnt/kvm_hugepage'
self.hugepage_size = self.get_hugepage_size()
self.target_hugepages = self.get_target_hugepages()
self.kernel_hp_file = '/proc/sys/vm/nr_hugepages'
def get_hugepage_size(self):
"""
Get the current system setting for huge memory page size.
"""
meminfo = open('/proc/meminfo', 'r').readlines()
huge_line_list = [h for h in meminfo if h.startswith("Hugepagesize")]
try:
return int(huge_line_list[0].split()[1])
except ValueError, e:
raise ValueError("Could not get huge page size setting from "
"/proc/meminfo: %s" % e)
def get_target_hugepages(self):
"""
Calculate the target number of hugepages for testing purposes.
"""
if self.vms < self.max_vms:
self.vms = self.max_vms
# memory of all VMs plus qemu overhead of 64MB per guest
vmsm = (self.vms * self.mem) + (self.vms * 64)
return int(vmsm * 1024 / self.hugepage_size)
@error.context_aware
def set_hugepages(self):
"""
Sets the hugepage limit to the target hugepage value calculated.
"""
error.context("setting hugepages limit to %s" % self.target_hugepages)
hugepage_cfg = open(self.kernel_hp_file, "r+")
hp = hugepage_cfg.readline()
while int(hp) < self.target_hugepages:
loop_hp = hp
hugepage_cfg.write(str(self.target_hugepages))
hugepage_cfg.flush()
hugepage_cfg.seek(0)
hp = int(hugepage_cfg.readline())
if loop_hp == hp:
raise ValueError("Cannot set the kernel hugepage setting "
"to the target value of %d hugepages." %
self.target_hugepages)
hugepage_cfg.close()
logging.debug("Successfuly set %s large memory pages on host ",
self.target_hugepages)
@error.context_aware
def mount_hugepage_fs(self):
"""
Verify if there's a hugetlbfs mount set. If there's none, will set up
a hugetlbfs mount using the class attribute that defines the mount
point.
"""
error.context("mounting hugepages path")
if not os.path.ismount(self.hugepage_path):
if not os.path.isdir(self.hugepage_path):
os.makedirs(self.hugepage_path)
cmd = "mount -t hugetlbfs none %s" % self.hugepage_path
utils.system(cmd)
def setup(self):
logging.debug("Number of VMs this test will use: %d", self.vms)
logging.debug("Amount of memory used by each vm: %s", self.mem)
logging.debug("System setting for large memory page size: %s",
self.hugepage_size)
logging.debug("Number of large memory pages needed for this test: %s",
self.target_hugepages)
self.set_hugepages()
self.mount_hugepage_fs()
@error.context_aware
def cleanup(self):
error.context("trying to dealocate hugepage memory")
try:
utils.system("umount %s" % self.hugepage_path)
except error.CmdError:
return
utils.system("echo 0 > %s" % self.kernel_hp_file)
logging.debug("Hugepage memory successfuly dealocated")