blob: e4d79f8a194b59b3ac9b35efc61f0d99b9a2771a [file] [log] [blame]
import os, logging, re
from autotest_lib.client.common_lib import error
from autotest_lib.client.virt import virt_test_utils
@error.context_aware
def run_cpu_hotplug(test, params, env):
"""
Runs CPU hotplug test:
1) Pick up a living guest
2) Send the monitor command cpu_set [cpu id] for each cpu we wish to have
3) Verify if guest has the additional CPUs showing up under
/sys/devices/system/cpu
4) Try to bring them online by writing 1 to the 'online' file inside that dir
5) Run the CPU Hotplug test suite shipped with autotest inside guest
@param test: KVM test object.
@param params: Dictionary with test parameters.
@param env: Dictionary with the test environment.
"""
vm = env.get_vm(params["main_vm"])
vm.verify_alive()
timeout = int(params.get("login_timeout", 360))
session = vm.wait_for_login(timeout=timeout)
n_cpus_add = int(params.get("n_cpus_add", 1))
current_cpus = int(params.get("smp", 1))
onoff_iterations = int(params.get("onoff_iterations", 20))
total_cpus = current_cpus + n_cpus_add
error.context("getting guest dmesg before addition")
dmesg_before = session.cmd("dmesg -c")
error.context("Adding %d CPUs to guest" % n_cpus_add)
for i in range(total_cpus):
vm.monitor.cmd("cpu_set %s online" % i)
output = vm.monitor.cmd("info cpus")
logging.debug("Output of info cpus:\n%s", output)
cpu_regexp = re.compile("CPU #(\d+)")
total_cpus_monitor = len(cpu_regexp.findall(output))
if total_cpus_monitor != total_cpus:
raise error.TestFail("Monitor reports %s CPUs, when VM should have %s" %
(total_cpus_monitor, total_cpus))
dmesg_after = session.cmd("dmesg -c")
logging.debug("Guest dmesg output after CPU add:\n%s" % dmesg_after)
# Verify whether the new cpus are showing up on /sys
error.context("verifying if new CPUs are showing on guest's /sys dir")
n_cmd = 'find /sys/devices/system/cpu/cpu[0-99] -maxdepth 0 -type d | wc -l'
output = session.cmd(n_cmd)
logging.debug("List of cpus on /sys:\n%s" % output)
try:
cpus_after_addition = int(output)
except ValueError:
logging.error("Output of '%s': %s", n_cmd, output)
raise error.TestFail("Unable to get CPU count after CPU addition")
if cpus_after_addition != total_cpus:
raise error.TestFail("%s CPUs are showing up under "
"/sys/devices/system/cpu, was expecting %s" %
(cpus_after_addition, total_cpus))
error.context("locating online files for guest's new CPUs")
r_cmd = 'find /sys/devices/system/cpu/cpu[1-99]/online -maxdepth 0 -type f'
online_files = session.cmd(r_cmd)
logging.debug("CPU online files detected: %s", online_files)
online_files = online_files.split().sort()
if not online_files:
raise error.TestFail("Could not find CPUs that can be "
"enabled/disabled on guest")
for online_file in online_files:
cpu_regexp = re.compile("cpu(\d+)", re.IGNORECASE)
cpu_id = cpu_regexp.findall(online_file)[0]
error.context("changing online status for CPU %s" % cpu_id)
check_online_status = session.cmd("cat %s" % online_file)
try:
check_online_status = int(check_online_status)
except ValueError:
raise error.TestFail("Unable to get online status from CPU %s" %
cpu_id)
assert(check_online_status in [0, 1])
if check_online_status == 0:
error.context("Bringing CPU %s online" % cpu_id)
session.cmd("echo 1 > %s" % online_file)
# Now that all CPUs were onlined, let's execute the
# autotest CPU Hotplug test
control_path = os.path.join(test.bindir, "autotest_control",
"cpu_hotplug.control")
timeout = int(params.get("cpu_hotplug_timeout"), 300)
error.context("running cpu_hotplug autotest after cpu addition")
virt_test_utils.run_autotest(vm, session, control_path, timeout,
test.outputdir, params)
# Last, but not least, let's offline/online the CPUs in the guest
# several times
irq = 15
irq_mask = "f0"
for i in xrange(onoff_iterations):
session.cmd("echo %s > /proc/irq/%s/smp_affinity" % (irq_mask, irq))
for online_file in online_files:
session.cmd("echo 0 > %s" % online_file)
for online_file in online_files:
session.cmd("echo 1 > %s" % online_file)