* functions for adding and removal of drive to vm using host-file or host-scsi_debug device. Signed-off-by: Lukas Doktor <ldoktor@xxxxxxxxxx> --- client/tests/kvm/tests/cgroup.py | 125 ++++++++++++++++++++++++++++++++----- 1 files changed, 108 insertions(+), 17 deletions(-) diff --git a/client/tests/kvm/tests/cgroup.py b/client/tests/kvm/tests/cgroup.py index b9a10ea..d6418b5 100644 --- a/client/tests/kvm/tests/cgroup.py +++ b/client/tests/kvm/tests/cgroup.py @@ -17,6 +17,108 @@ def run_cgroup(test, params, env): vms = None tests = None + # Func + def get_device_driver(): + """ + Discovers the used block device driver {ide, scsi, virtio_blk} + @return: Used block device driver {ide, scsi, virtio} + """ + if test.tagged_testname.count('virtio_blk'): + return "virtio" + elif test.tagged_testname.count('scsi'): + return "scsi" + else: + return "ide" + + + def add_file_drive(vm, driver=get_device_driver(), host_file=None): + """ + Hot-add a drive based on file to a vm + @param vm: Desired VM + @param driver: which driver should be used (default: same as in test) + @param host_file: Which file on host is the image (default: create new) + @return: Tupple(ret_file, device) + ret_file: created file handler (None if not created) + device: PCI id of the virtual disk + """ + if not host_file: + host_file = tempfile.NamedTemporaryFile(prefix="cgroup-disk-", + suffix=".iso") + utils.system("dd if=/dev/zero of=%s bs=1M count=8 &>/dev/null" + % (host_file.name)) + ret_file = host_file + else: + ret_file = None + + out = vm.monitor.cmd("pci_add auto storage file=%s,if=%s,snapshot=off," + "cache=off" % (host_file.name, driver)) + dev = re.search(r'OK domain (\d+), bus (\d+), slot (\d+), function \d+', + out) + if not dev: + raise error.TestFail("Can't add device(%s, %s, %s): %s" % (vm, + host_file.name, driver, out)) + device = "%s:%s:%s" % dev.groups() + return (ret_file, device) + + + def add_scsi_drive(vm, driver=get_device_driver(), host_file=None): + """ + Hot-add a drive based on scsi_debug device to a vm + @param vm: Desired VM + @param driver: which driver should be used (default: same as in test) + @param host_file: Which dev on host is the image (default: create new) + @return: Tupple(ret_file, device) + ret_file: string of the created dev (None if not created) + device: PCI id of the virtual disk + """ + if not host_file: + if utils.system_output("lsmod | grep scsi_debug -c") == 0: + utils.system("modprobe scsi_debug dev_size_mb=8 add_host=0") + utils.system("echo 1 > /sys/bus/pseudo/drivers/scsi_debug/add_host") + host_file = utils.system_output("ls /dev/sd* | tail -n 1") + # Enable idling in scsi_debug drive + utils.system("echo 1 > /sys/block/%s/queue/rotational" % host_file) + ret_file = host_file + else: + # Don't remove this device during cleanup + # Reenable idling in scsi_debug drive (in case it's not) + utils.system("echo 1 > /sys/block/%s/queue/rotational" % host_file) + ret_file = None + + out = vm.monitor.cmd("pci_add auto storage file=%s,if=%s,snapshot=off," + "cache=off" % (host_file, driver)) + dev = re.search(r'OK domain (\d+), bus (\d+), slot (\d+), function \d+', + out) + if not dev: + raise error.TestFail("Can't add device(%s, %s, %s): %s" % (vm, + host_file, driver, out)) + device = "%s:%s:%s" % dev.groups() + return (ret_file, device) + + + def rm_drive(vm, host_file, device): + """ + Remove drive from vm and device on disk + ! beware to remove scsi devices in reverse order ! + """ + vm.monitor.cmd("pci_del %s" % device) + + if isinstance(host_file, file): # file + host_file.close() + elif isinstance(host_file, str): # scsi device + utils.system("echo -1> /sys/bus/pseudo/drivers/scsi_debug/add_host") + else: # custom file, do nothing + pass + + def get_all_pids(ppid): + """ + Get all PIDs of children/threads of parent ppid + param ppid: parent PID + return: list of PIDs of all children/threads of ppid + """ + return (utils.system_output("ps -L --ppid=%d -o lwp" % ppid) + .split('\n')[1:]) + # Tests class _TestBlkioBandwidth: """ @@ -46,9 +148,8 @@ def run_cgroup(test, params, env): """ err = "" try: - for i in range (2): - vms[i].monitor.cmd("pci_del %s" % self.devices[i]) - self.files[i].close() + for i in range(1, -1, -1): + rm_drive(vms[i], self.files[i], self.devices[i]) except Exception, failure_detail: err += "\nCan't remove PCI drive: %s" % failure_detail try: @@ -89,8 +190,7 @@ def run_cgroup(test, params, env): if blkio.set_cgroup(self.vms[i].get_shell_pid(), pwd[i]): raise error.TestError("Could not set cgroup") # Move all existing threads into cgroup - for tmp in utils.system_output("ps -L --ppid=%d -o lwp" - % self.vms[i].get_shell_pid()).split('\n')[1:]: + for tmp in get_all_pids(self.vms[i].get_shell_pid()): if blkio.set_cgroup(int(tmp), pwd[i]): raise error.TestError("Could not set cgroup") if self.blkio.set_property("blkio.weight", 100, pwd[0]): @@ -101,18 +201,9 @@ def run_cgroup(test, params, env): # Add dummy drives # TODO: implement also using QMP. for i in range(2): - self.files.append(tempfile.NamedTemporaryFile( - prefix="cgroup-disk-", - suffix=".iso")) - utils.system("dd if=/dev/zero of=%s bs=1M count=10 &>/dev/null" - % (self.files[i].name)) - out = vms[i].monitor.cmd("pci_add auto storage file=%s," - "if=virtio,snapshot=off,cache=off" - % (self.files[i].name)) - out = re.search(r'OK domain (\d+), bus (\d+), slot (\d+), ' - 'function \d+', out).groups() - self.devices.append("%s:%s:%s" % out) - + (host_file, device) = add_file_drive(vms[i], "virtio") + self.files.append(host_file) + self.devices.append(device) def run(self): """ -- 1.7.6.2 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html