18adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis#!/usr/bin/python
28adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis# -*- coding: utf-8 -*-
38adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis"""
48adf78936c915df6fd1edb6c592f40a7ed8350a5Dale CurtisHelpers for cgroup testing.
58adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
68adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis@copyright: 2011 Red Hat Inc.
78adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis@author: Lukas Doktor <ldoktor@redhat.com>
88adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis"""
98adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtisimport os, logging, subprocess, time, shutil
108adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtisfrom tempfile import mkdtemp
118adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtisfrom autotest_lib.client.bin import utils
128adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtisfrom autotest_lib.client.common_lib import error
138adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
148adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
158adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtisclass Cgroup(object):
168adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    """
178adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    Cgroup handling class.
188adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    """
198adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def __init__(self, module, _client):
208adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
218adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Constructor
228adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param module: Name of the cgroup module
238adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param _client: Test script pwd + name
248adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
258adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        self.module = module
268adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        self._client = _client
278adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        self.root = None
288adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
298adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
308adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def initialize(self, modules):
318adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
328adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Initializes object for use.
338adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
348adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param modules: Array of all available cgroup modules.
358adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: 0 when PASSED.
368adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
378adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        self.root = modules.get_pwd(self.module)
388adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if self.root:
398adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return 0
408adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        else:
418adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.initialize(): Module %s not found", self.module)
428adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
438adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return 0
448adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
458adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
468adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def mk_cgroup(self, root=None):
478adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
488adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Creates new temporary cgroup
498adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param root: where to create this cgroup (default: self.root)
508adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: 0 when PASSED
518adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
528adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        try:
538adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            if root:
548adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                pwd = mkdtemp(prefix='cgroup-', dir=root) + '/'
558adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            else:
568adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                pwd = mkdtemp(prefix='cgroup-', dir=self.root) + '/'
578adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        except Exception, inst:
588adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.mk_cgroup(): %s" , inst)
598adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return None
608adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return pwd
618adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
628adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
638adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def rm_cgroup(self, pwd, supress=False):
648adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
658adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Removes cgroup.
668adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
678adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pwd: cgroup directory.
688adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param supress: supress output.
698adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: 0 when PASSED
708adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
718adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        try:
728adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            os.rmdir(pwd)
738adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        except Exception, inst:
748adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            if not supress:
758adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                logging.error("cg.rm_cgroup(): %s" , inst)
768adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
778adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return 0
788adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
798adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
808adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def test(self, cmd):
818adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
828adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Executes cgroup_client.py with cmd parameter.
838adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
848adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param cmd: command to be executed
858adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: subprocess.Popen() process
868adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
878adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        logging.debug("cg.test(): executing paralel process '%s'", cmd)
888adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        cmd = self._client + ' ' + cmd
898adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        process = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
908adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                                   stdout=subprocess.PIPE,
918adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                                   stderr=subprocess.PIPE, close_fds=True)
928adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return process
938adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
948adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
958adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def is_cgroup(self, pid, pwd):
968adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
978adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Checks if the 'pid' process is in 'pwd' cgroup
988adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pid: pid of the process
998adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pwd: cgroup directory
1008adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: 0 when is 'pwd' member
1018adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1028adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if open(pwd + '/tasks').readlines().count("%d\n" % pid) > 0:
1038adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return 0
1048adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        else:
1058adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
1068adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1078adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1088adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def is_root_cgroup(self, pid):
1098adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1108adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Checks if the 'pid' process is in root cgroup (WO cgroup)
1118adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pid: pid of the process
1128adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: 0 when is 'root' member
1138adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1148adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return self.is_cgroup(pid, self.root)
1158adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1168adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1178adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def set_cgroup(self, pid, pwd):
1188adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1198adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Sets cgroup membership
1208adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pid: pid of the process
1218adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pwd: cgroup directory
1228adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: 0 when PASSED
1238adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1248adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        try:
1258adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            open(pwd+'/tasks', 'w').write(str(pid))
1268adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        except Exception, inst:
1278adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.set_cgroup(): %s" , inst)
1288adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
1298adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if self.is_cgroup(pid, pwd):
1308adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.set_cgroup(): Setting %d pid into %s cgroup "
1318adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                          "failed", pid, pwd)
1328adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
1338adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        else:
1348adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return 0
1358adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1368adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def set_root_cgroup(self, pid):
1378adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1388adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Resets the cgroup membership (sets to root)
1398adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pid: pid of the process
1408adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: 0 when PASSED
1418adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1428adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return self.set_cgroup(pid, self.root)
1438adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1448adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1458adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def get_prop(self, prop, pwd=None, supress=False):
1468adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1478adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Gets one line of the property value
1488adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param prop: property name (file)
1498adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pwd: cgroup directory
1508adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param supress: supress the output
1518adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: String value or None when FAILED
1528adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1538adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        tmp = self.get_property(prop, pwd, supress)
1548adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if tmp:
1558adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            if tmp[0][-1] == '\n':
1568adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                tmp[0] = tmp[0][:-1]
1578adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return tmp[0]
1588adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        else:
1598adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return None
1608adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1618adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1628adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def get_property(self, prop, pwd=None, supress=False):
1638adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1648adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Gets the property value
1658adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param prop: property name (file)
1668adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pwd: cgroup directory
1678adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param supress: supress the output
1688adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: [] values or None when FAILED
1698adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1708adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if pwd == None:
1718adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            pwd = self.root
1728adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        try:
1738adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            ret = open(pwd+prop, 'r').readlines()
1748adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        except Exception, inst:
1758adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            ret = None
1768adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            if not supress:
1778adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                logging.error("cg.get_property(): %s" , inst)
1788adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return ret
1798adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1808adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
1818adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def set_prop(self, prop, value, pwd=None, check=True):
1828adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1838adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Sets the one-line property value concerning the K,M,G postfix
1848adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param prop: property name (file)
1858adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param value: desired value
1868adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pwd: cgroup directory
1878adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param check: check the value after setup
1888adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: 0 when PASSED
1898adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
1908adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        _value = value
1918adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        try:
1928adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            value = str(value)
1938adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            if value[-1] == '\n':
1948adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                value = value[:-1]
1958adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            if value[-1] == 'K':
1968adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                value = int(value[:-1]) * 1024
1978adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            elif value[-1] == 'M':
1988adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                value = int(value[:-1]) * 1048576
1998adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            elif value[-1] == 'G':
2008adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                value = int(value[:-1]) * 1073741824
2018adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        except:
2028adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.set_prop() fallback into cg.set_property.")
2038adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            value = _value
2048adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return self.set_property(prop, value, pwd, check)
2058adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2068adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2078adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def set_property(self, prop, value, pwd=None, check=True):
2088adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
2098adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Sets the property value
2108adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param prop: property name (file)
2118adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param value: desired value
2128adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param pwd: cgroup directory
2138adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param check: check the value after setup
2148adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: 0 when PASSED
2158adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
2168adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        value = str(value)
2178adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if pwd == None:
2188adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            pwd = self.root
2198adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        try:
2208adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            open(pwd+prop, 'w').write(value)
2218adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        except Exception, inst:
2228adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.set_property(): %s" , inst)
2238adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
2248adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if check:
2258adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            # Get the first line - '\n'
2268adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            _value = self.get_property(prop, pwd)[0][:-1]
2278adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            if value != _value:
2288adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                logging.error("cg.set_property(): Setting failed: desired = %s,"
2298adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                              " real value = %s", value, _value)
2308adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                return -1
2318adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return 0
2328adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2338adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2348adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def smoke_test(self):
2358adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
2368adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Smoke test
2378adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Module independent basic tests
2388adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
2398adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        part = 0
2408adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        pwd = self.mk_cgroup()
2418adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if pwd == None:
2428adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.smoke_test[%d]: Can't create cgroup", part)
2438adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
2448adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2458adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        part += 1
2468adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        ps = self.test("smoke")
2478adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if ps == None:
2488adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.smoke_test[%d]: Couldn't create process", part)
2498adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
2508adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2518adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        part += 1
2528adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if (ps.poll() != None):
2538adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.smoke_test[%d]: Process died unexpectidly", part)
2548adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
2558adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2568adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        # New process should be a root member
2578adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        part += 1
2588adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if self.is_root_cgroup(ps.pid):
2598adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.smoke_test[%d]: Process is not a root member",
2608adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                          part)
2618adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
2628adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2638adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        # Change the cgroup
2648adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        part += 1
2658adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if self.set_cgroup(ps.pid, pwd):
2668adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.smoke_test[%d]: Could not set cgroup", part)
2678adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
2688adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2698adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        # Try to remove used cgroup
2708adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        part += 1
2718adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if self.rm_cgroup(pwd, supress=True) == 0:
2728adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.smoke_test[%d]: Unexpected successful deletion of"
2738adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                          " the used cgroup", part)
2748adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
2758adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2768adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        # Return the process into the root cgroup
2778adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        part += 1
2788adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if self.set_root_cgroup(ps.pid):
2798adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.smoke_test[%d]: Could not return the root cgroup "
2808adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                          "membership", part)
2818adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
2828adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2838adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        # It should be safe to remove the cgroup now
2848adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        part += 1
2858adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if self.rm_cgroup(pwd):
2868adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.smoke_test[%d]: Can't remove cgroup directory",
2878adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                          part)
2888adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
2898adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2908adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        # Finish the process
2918adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        part += 1
2928adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        ps.stdin.write('\n')
2938adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        time.sleep(2)
2948adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        if (ps.poll() == None):
2958adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("cg.smoke_test[%d]: Process is not finished", part)
2968adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return -1
2978adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
2988adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return 0
2998adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
3008adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
3018adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtisclass CgroupModules(object):
3028adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    """
3038adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    Handles the list of different cgroup filesystems.
3048adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    """
3058adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def __init__(self):
3068adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        self.modules = []
3078adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        self.modules.append([])
3088adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        self.modules.append([])
3098adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        self.modules.append([])
3108adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        self.mountdir = mkdtemp(prefix='cgroup-') + '/'
3118adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
3128adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
3138adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def init(self, _modules):
3148adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
3158adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Checks the mounted modules and if necessary mounts them into tmp
3168adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            mountdir.
3178adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param _modules: Desired modules.
3188adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: Number of initialized modules.
3198adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
3208adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        logging.debug("Desired cgroup modules: %s", _modules)
3218adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        mounts = []
3228adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        fp = open('/proc/mounts', 'r')
3238adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        line = fp.readline().split()
3248adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        while line:
3258adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            if line[2] == 'cgroup':
3268adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                mounts.append(line)
3278adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            line = fp.readline().split()
3288adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        fp.close()
3298adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
3308adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        for module in _modules:
3318adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            # Is it already mounted?
3328adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            i = False
3338adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            for mount in mounts:
3348adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                if mount[3].find(module) != -1:
3358adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                    self.modules[0].append(module)
3368adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                    self.modules[1].append(mount[1] + '/')
3378adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                    self.modules[2].append(False)
3388adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                    i = True
3398adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                    break
3408adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            if not i:
3418adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                # Not yet mounted
3428adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                os.mkdir(self.mountdir + module)
3438adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                cmd = ('mount -t cgroup -o %s %s %s' %
3448adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                       (module, module, self.mountdir + module))
3458adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                try:
3468adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                    utils.run(cmd)
3478adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                    self.modules[0].append(module)
3488adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                    self.modules[1].append(self.mountdir + module)
3498adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                    self.modules[2].append(True)
3508adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                except error.CmdError:
3518adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                    logging.info("Cgroup module '%s' not available", module)
3528adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
3538adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        logging.debug("Initialized cgroup modules: %s", self.modules[0])
3548adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return len(self.modules[0])
3558adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
3568adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
3578adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def cleanup(self):
3588adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
3598adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Unmount all cgroups and remove the mountdir.
3608adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
3618adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        for i in range(len(self.modules[0])):
3628adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            if self.modules[2][i]:
3638adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                utils.system('umount %s -l' % self.modules[1][i],
3648adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis                             ignore_status=True)
3658adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        shutil.rmtree(self.mountdir)
3668adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
3678adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis
3688adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis    def get_pwd(self, module):
3698adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
3708adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        Returns the mount directory of 'module'
3718adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @param module: desired module (memory, ...)
3728adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        @return: mount directory of 'module' or None
3738adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        """
3748adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        try:
3758adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            i = self.modules[0].index(module)
3768adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        except Exception, inst:
3778adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            logging.error("module %s not found: %s", module, inst)
3788adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis            return None
3798adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        return self.modules[1][i]
380