This subtest tries to attach scsi_debug disk with different cgroup
devices.list setting.
* subtests the devices.{allow, deny, list} cgroup functionality
* new function get_maj_min(dev) which returns (major, minor) numbers
of dev
* rm_drive: support for rm_device without drive (only remove the host
file)
* improved logging
Signed-off-by: Lukas Doktor <[email protected]>
---
client/tests/kvm/tests/cgroup.py | 234 +++++++++++++++++++++++++++++++++-----
1 files changed, 203 insertions(+), 31 deletions(-)
diff --git a/client/tests/kvm/tests/cgroup.py b/client/tests/kvm/tests/cgroup.py
index 6c64532..c83f91a 100644
--- a/client/tests/kvm/tests/cgroup.py
+++ b/client/tests/kvm/tests/cgroup.py
@@ -50,7 +50,7 @@ def run_cgroup(test, params, env):
return abs(float(actual-reference) / reference)
- def get_dd_cmd(direction, dev='vd?', count=None, bs=None):
+ def get_dd_cmd(direction, dev=None, count=None, bs=None):
"""
Generates dd_cmd string
@param direction: {read,write,bi} dd direction
@@ -59,6 +59,11 @@ def run_cgroup(test, params, env):
@param bs: bs parameter of dd
@return: dd command string
"""
+ if dev is None:
+ if get_device_driver() == "virtio":
+ dev = 'vd?'
+ else:
+ dev = '[sh]d?'
if direction == "read":
params = "if=$FILE of=/dev/null iflag=direct"
elif direction == "write":
@@ -82,6 +87,21 @@ def run_cgroup(test, params, env):
return params.get('drive_format', 'virtio')
+ def get_maj_min(dev):
+ """
+ Returns the major and minor numbers of the dev device
+ @return: Tupple(major, minor) numbers of the dev device
+ """
+ try:
+ ret = utils.system_output("ls -l %s" % dev)
+ ret = re.match(r'[bc][rwx-]{9} \d+ \w+ \w+ (\d+), (\d+)',
+ ret).groups()
+ except Exception, details:
+ raise error.TestFail("Couldn't get %s maj and min numbers: %s" %
+ (dev, details))
+ return ret
+
+
def add_file_drive(vm, driver=get_device_driver(), host_file=None):
"""
Hot-add a drive based on file to a vm
@@ -173,14 +193,17 @@ def run_cgroup(test, params, env):
"""
err = False
# TODO: Implement also via QMP
- vm.monitor.cmd("pci_del %s" % device)
- time.sleep(3)
- qtree = vm.monitor.info('qtree', debug=False)
- if qtree.count('addr %s.0' % device) != 0:
- err = True
- vm.destroy()
-
- if isinstance(host_file, str): # scsi device
+ if device:
+ vm.monitor.cmd("pci_del %s" % device)
+ time.sleep(3)
+ qtree = vm.monitor.info('qtree', debug=False)
+ if qtree.count('addr %s.0' % device) != 0:
+ err = True
+ vm.destroy()
+
+ if host_file is None: # Do not remove
+ pass
+ elif isinstance(host_file, str): # scsi device
utils.system("echo -1>
/sys/bus/pseudo/drivers/scsi_debug/add_host")
else: # file
host_file.close()
@@ -334,7 +357,7 @@ def run_cgroup(test, params, env):
_TestBlkioBandwidth.__init__(self, vms, modules)
# Read from the last vd* in a loop until test removes the
# /tmp/cgroup_lock file (and kills us)
- self.dd_cmd = get_dd_cmd("read", bs="100K")
+ self.dd_cmd = get_dd_cmd("read", dev='vd?', bs="100K")
class TestBlkioBandwidthWeigthWrite(_TestBlkioBandwidth):
@@ -350,7 +373,7 @@ def run_cgroup(test, params, env):
# Write on the last vd* in a loop until test removes the
# /tmp/cgroup_lock file (and kills us)
_TestBlkioBandwidth.__init__(self, vms, modules)
- self.dd_cmd = get_dd_cmd("write", bs="100K")
+ self.dd_cmd = get_dd_cmd("write", dev='vd?', bs="100K")
class _TestBlkioThrottle:
@@ -376,10 +399,6 @@ def run_cgroup(test, params, env):
self.devices = None # Temporary virt devices (PCI drive 1 per vm)
self.dd_cmd = None # DD command used to test the throughput
self.speeds = None # cgroup throughput
- if get_device_driver() == "virtio":
- self.dev = "vd?"
- else:
- self.dev = "[sh]d?"
def cleanup(self):
"""
@@ -417,13 +436,8 @@ def run_cgroup(test, params, env):
driver="virtio")
else:
(self.files, self.devices) = add_scsi_drive(self.vm)
- try:
- dev = utils.system_output("ls -l %s" % self.files).split()[4:6]
- dev[0] = dev[0][:-1] # Remove tailing ','
- except:
- time.sleep(5)
- raise error.TestFail("Couldn't get %s maj and min numbers"
- % self.files)
+ time.sleep(3)
+ dev = get_maj_min(self.files)
cgroup = self.cgroup
cgroup.initialize(self.modules)
@@ -548,7 +562,7 @@ def run_cgroup(test, params, env):
@param modules: initialized cgroup module class
"""
_TestBlkioThrottle.__init__(self, vms, modules)
- self.dd_cmd = get_dd_cmd("read", dev=self.dev, count=1)
+ self.dd_cmd = get_dd_cmd("read", count=1)
self.speeds = [1024]
@@ -561,7 +575,7 @@ def run_cgroup(test, params, env):
@param modules: initialized cgroup module class
"""
_TestBlkioThrottle.__init__(self, vms, modules)
- self.dd_cmd = get_dd_cmd("write", dev=self.dev, count=1)
+ self.dd_cmd = get_dd_cmd("write", count=1)
self.speeds = [1024]
@@ -577,7 +591,7 @@ def run_cgroup(test, params, env):
@param modules: initialized cgroup module class
"""
_TestBlkioThrottle.__init__(self, vms, modules)
- self.dd_cmd = get_dd_cmd("read", dev=self.dev, count=1)
+ self.dd_cmd = get_dd_cmd("read", count=1)
self.speeds = [0, 1024, 0, 2048, 0, 4096]
@@ -593,10 +607,166 @@ def run_cgroup(test, params, env):
@param modules: initialized cgroup module class
"""
_TestBlkioThrottle.__init__(self, vms, modules)
- self.dd_cmd = get_dd_cmd("write", dev=self.dev, count=1)
+ self.dd_cmd = get_dd_cmd("write", count=1)
self.speeds = [0, 1024, 0, 2048, 0, 4096]
+ class TestDevicesAccess:
+ """
+ It tries to attach scsi_debug disk with different cgroup devices.list
+ setting.
+ * self.permitions are defined as a list of dictionaries:
+ {'property': control property, 'value': permition value,
+ 'check_value': check value (from devices.list property),
+ 'read_results': excepced read results T/F,
+ 'write_results': expected write results T/F}
+ """
+ def __init__(self, vms, modules):
+ """
+ Initialization
+ @param vms: list of vms
+ @param modules: initialized cgroup module class
+ """
+ self.vm = vms[0] # Virt machines
+ self.modules = modules # cgroup module handler
+ self.cgroup = Cgroup('devices', '') # cgroup blkio handler
+ self.files = None # Temporary files (files of virt disks)
+ self.devices = None # Temporary virt devices
+ self.permitions = None # Test dictionary, see init for details
+
+
+ def cleanup(self):
+ """ Cleanup """
+ err = ""
+ try:
+ rm_drive(self.vm, self.files, self.devices)
+ except Exception, failure_detail:
+ err += "\nCan't remove PCI drive: %s" % failure_detail
+ try:
+ del(self.cgroup)
+ except Exception, failure_detail:
+ err += "\nCan't remove Cgroup: %s" % failure_detail
+
+ if err:
+ logging.error("Some cleanup operations failed: %s", err)
+ raise error.TestError("Some cleanup operations failed: %s"
+ % err)
+
+
+ def init(self):
+ """
+ Initialization
+ * creates a new scsi_debug device
+ * prepares one cgroup and assign vm to it
+ """
+ # Only create the host /dev/sd? device
+ (self.files, self.devices) = add_scsi_drive(self.vm)
+ rm_drive(self.vm, host_file=None, device=self.devices)
+ self.devices = None # We don't want to mess cleanup
+
+ time.sleep(3)
+ dev = "%s:%s" % get_maj_min(self.files)
+
+ self.cgroup.initialize(self.modules)
+ self.cgroup.mk_cgroup()
+ self.cgroup.set_cgroup(self.vm.get_shell_pid(),
+ self.cgroup.cgroups[0])
+ for pid in utils.get_children_pids(self.vm.get_shell_pid()):
+ self.cgroup.set_cgroup(int(pid), self.cgroup.cgroups[0])
+
+ # Test dictionary
+ # Beware of persistence of some setting to another round!!!
+ self.permitions = [
+ {'property' : 'deny',
+ 'value' : 'a',
+ 'check_value' : '',
+ 'result' : False},
+ {'property' : 'allow',
+ 'value' : 'b %s rm' % dev,
+ 'check_value' : True,
+ 'result' : False},
+ {'property' : 'allow',
+ 'value' : 'b %s w' % dev,
+ 'check_value' : 'b %s rwm' % dev,
+ 'result' : True},
+ {'property' : 'deny',
+ 'value' : 'b %s r' % dev,
+ 'check_value' : 'b %s wm' % dev,
+ 'result' : False},
+ {'property' : 'deny',
+ 'value' : 'b %s wm' % dev,
+ 'check_value' : '',
+ 'result' : False},
+ {'property' : 'allow',
+ 'value' : 'a',
+ 'check_value' : 'a *:* rwm',
+ 'result' : True},
+ ]
+
+
+
+ def run(self):
+ """
+ Actual test:
+ * For each self.permitions sets the cgroup devices permition
+ and tries attach the disk. Checks the results with prescription.
+ """
+ def set_permitions(cgroup, permitions):
+ """
+ Wrapper for setting permitions to first cgroup
+ @param self.permitions: is defined as a list of dictionaries:
+ {'property': control property, 'value': permition value,
+ 'check_value': check value (from devices.list property),
+ 'read_results': excepced read results T/F,
+ 'write_results': expected write results T/F}
+ """
+ cgroup.set_property('devices.'+permitions['property'],
+ permitions['value'],
+ cgroup.cgroups[0],
+ check=permitions['check_value'],
+ checkprop='devices.list')
+
+
+ session = self.vm.wait_for_login(timeout=30)
+
+ cgroup = self.cgroup
+ results = ""
+ for i in range(len(self.permitions)):
+ perm = self.permitions[i]
+ set_permitions(cgroup, perm)
+ logging.debug("Setting permitions: {%s: %s}, value: %s",
+ perm['property'], perm['value'],
+ cgroup.get_property('devices.list',
+ cgroup.cgroups[0]))
+
+ try:
+ (_, self.devices) = add_scsi_drive(self.vm,
+ host_file=self.files)
+ except Exception, details:
+ if perm['result']:
+ logging.error("Perm: {%s: %s}: drive was not attached:"
+ " %s", perm['property'], perm['value'],
+ details)
+ results += ("{%s: %s => NotAttached}, " %
+ (perm['property'], perm['value']))
+ else:
+ if not perm['result']:
+ logging.error("Perm: {%s: %s}: drive was attached",
+ perm['property'], perm['value'])
+ results += ("{%s: %s => Attached}, " %
+ (perm['property'], perm['value']))
+ rm_drive(self.vm, host_file=None, device=self.devices)
+ self.devices = None
+
+ session.close()
+ if results:
+ raise error.TestFail("Some restrictions were broken: {%s}" %
+ results[:-2])
+
+ time.sleep(10)
+
+ return ("All restrictions enforced successfully.")
+
# Setup
# TODO: Add all new tests here
tests = {"blkio_bandwidth_weigth_read" : TestBlkioBandwidthWeigthRead,
@@ -605,9 +775,10 @@ def run_cgroup(test, params, env):
"blkio_throttle_write" : TestBlkioThrottleWrite,
"blkio_throttle_multiple_read" : TestBlkioThrottleMultipleRead,
"blkio_throttle_multiple_write" : TestBlkioThrottleMultipleWrite,
+ "devices_access" : TestDevicesAccess,
}
modules = CgroupModules()
- if (modules.init(['blkio']) <= 0):
+ if (modules.init(['blkio', 'devices']) <= 0):
raise error.TestFail('Can\'t mount any cgroup modules')
# Add all vms
vms = []
@@ -674,14 +845,15 @@ def run_cgroup(test, params, env):
results += ("\n [F] %s: {%s} FAILED: %s" %
(cg_test, err[:-2], out))
elif err:
- results += ("\n [E] %s: Test passed but {%s} FAILED: %s" %
+ results += ("\n [W] %s: Test passed but {%s} FAILED: %s" %
(cg_test, err[:-2], out))
else:
results += ("\n [P] %s: PASSED: %s" % (cg_test, out))
- out = ("SUM: All tests finished (%d PASS / %d FAIL = %d TOTAL)%s" %
- (results.count("PASSED"), results.count("FAILED"),
- (results.count("PASSED")+results.count("FAILED")), results))
+ out = ("SUM: All tests finished (%d PASS / %d WARN / %d FAIL = %d
TOTAL)%s"%
+ (results.count("\n [P]"), results.count("\n [W]"),
+ results.count("\n [F]"), (results.count("\n [P]") +
+ results.count("\n [F]") + results.count("\n [W]")), results))
logging.info(out)
if results.count("FAILED"):
raise error.TestFail("Some subtests failed\n%s" % out)
--
1.7.6.2
_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest