From: Lukas Doktor <ldoktor@redhat.com>
To: autotest@test.kernel.org, kvm@vger.kernel.org,
kvm-autotest@redhat.com, akong@redhat.com, lmr@redhat.com,
ldoktor@redhat.com, jzupka@redhat.com
Subject: [PATCH] [kvm-autotest]client.tests.kvm.tests.cgroup: Add TestDeviceAccess subtest
Date: Mon, 24 Oct 2011 14:46:05 +0200 [thread overview]
Message-ID: <1319460365-11819-2-git-send-email-ldoktor@redhat.com> (raw)
In-Reply-To: <1319460365-11819-1-git-send-email-ldoktor@redhat.com>
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 <ldoktor@redhat.com>
---
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
prev parent reply other threads:[~2011-10-24 12:46 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-24 12:46 [kvm-autotest]client.tests.kvm.tests.cgroup: Add TestDeviceAccess subtest Lukas Doktor
2011-10-24 12:46 ` Lukas Doktor [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1319460365-11819-2-git-send-email-ldoktor@redhat.com \
--to=ldoktor@redhat.com \
--cc=akong@redhat.com \
--cc=autotest@test.kernel.org \
--cc=jzupka@redhat.com \
--cc=kvm-autotest@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=lmr@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.