base_utils.py revision 8ba770dc9bcf2e60bf2db1b7128d7502df6e8e60
1c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh"""
22da4d885be334f7db795c3f017daa06ff8ea703dmblighDO NOT import this file directly - import client/bin/utils.py,
32da4d885be334f7db795c3f017daa06ff8ea703dmblighwhich will mix this in
43bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh
52da4d885be334f7db795c3f017daa06ff8ea703dmblighConvenience functions for use by tests or whomever.
63bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh
72da4d885be334f7db795c3f017daa06ff8ea703dmblighNote that this file is mixed in by utils.py - note very carefully the
82da4d885be334f7db795c3f017daa06ff8ea703dmblighprecedence order defined there
953da18eddf69243ca175d9a4603cba5b55300726mbligh"""
10f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtzimport os, shutil, commands, pickle, glob
11f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtzimport math, re, fnmatch, logging, multiprocessing
12959e8162836703848f8e1801f74e7117b850e889lmrfrom autotest_lib.client.common_lib import error, utils, magic
13ea397bbc85f1a3eda39c9f2ef4fc209b4ff336f4mbligh
14ea397bbc85f1a3eda39c9f2ef4fc209b4ff336f4mbligh
15f4c35322b200d65f41a8332b4f3503beb497840dmblighdef grep(pattern, file):
160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    This is mainly to fix the return code inversion from grep
180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Also handles compressed files.
197bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh
200afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    returns 1 if the pattern is present in the file, 0 if not.
210afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
220afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    command = 'grep "%s" > /dev/null' % pattern
230afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    ret = cat_file_to_cmd(file, command, ignore_status=True)
240afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return not ret
25af4efc23471265a3bfa7fef0146fbc0cbb54515bmbligh
26af4efc23471265a3bfa7fef0146fbc0cbb54515bmbligh
27c86b0b45cd0198d99d271a79f8b6de29feb98cd5mblighdef difflist(list1, list2):
280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """returns items in list2 that are not in list1"""
290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    diff = [];
300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for x in list2:
310afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if x not in list1:
320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            diff.append(x)
330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return diff
34f4c35322b200d65f41a8332b4f3503beb497840dmbligh
35c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
368ea61e2f9f55bd9f646735069e1f029e86d08320mblighdef cat_file_to_cmd(file, command, ignore_status=0, return_output=False):
370afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
380afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    equivalent to 'cat file | command' but knows to use
390afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    zcat or bzcat if appropriate
400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
41f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh    if not os.path.isfile(file):
42f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh        raise NameError('invalid file %s to cat to command %s'
43f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh                % (file, command))
44f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh
450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if return_output:
462da4d885be334f7db795c3f017daa06ff8ea703dmbligh        run_cmd = utils.system_output
470afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
482da4d885be334f7db795c3f017daa06ff8ea703dmbligh        run_cmd = utils.system
490afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
50959e8162836703848f8e1801f74e7117b850e889lmr    if magic.guess_type(file) == 'application/x-bzip2':
51f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh        cat = 'bzcat'
52959e8162836703848f8e1801f74e7117b850e889lmr    elif magic.guess_type(file) == 'application/x-gzip':
53f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh        cat = 'zcat'
540afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
55f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh        cat = 'cat'
56f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh    return run_cmd('%s %s | %s' % (cat, file, command),
57f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh                                                    ignore_status=ignore_status)
58712cd145672c0033a55173717787c54cd68e6b83mbligh
59c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
60712cd145672c0033a55173717787c54cd68e6b83mblighdef extract_tarball_to_dir(tarball, dir):
610afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Extract a tarball to a specified directory name instead of whatever
630afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    the top level of a tarball is - useful for versioned directory names, etc
640afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
650afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.exists(dir):
66959e8162836703848f8e1801f74e7117b850e889lmr        if os.path.isdir(dir):
67959e8162836703848f8e1801f74e7117b850e889lmr            shutil.rmtree(dir)
68959e8162836703848f8e1801f74e7117b850e889lmr        else:
69959e8162836703848f8e1801f74e7117b850e889lmr            os.remove(dir)
700afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    pwd = os.getcwd()
710afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    os.chdir(os.path.dirname(os.path.abspath(dir)))
720afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    newdir = extract_tarball(tarball)
730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    os.rename(newdir, dir)
740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    os.chdir(pwd)
75712cd145672c0033a55173717787c54cd68e6b83mbligh
76f4c35322b200d65f41a8332b4f3503beb497840dmbligh
77712cd145672c0033a55173717787c54cd68e6b83mblighdef extract_tarball(tarball):
780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Returns the directory extracted by the tarball."""
790afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    extracted = cat_file_to_cmd(tarball, 'tar xvf - 2>/dev/null',
800afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                                    return_output=True).splitlines()
810afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
820afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    dir = None
830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for line in extracted:
850afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        line = re.sub(r'^./', '', line)
860afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if not line or line == '.':
870afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            continue
880afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        topdir = line.split('/')[0]
890afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if os.path.isdir(topdir):
900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            if dir:
910afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                assert(dir == topdir)
920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            else:
930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                dir = topdir
940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if dir:
950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return dir
960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise NameError('extracting tarball produced no dir')
98712cd145672c0033a55173717787c54cd68e6b83mbligh
99cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
100d60882f21c28087da2b33aad1670fe717388ba4almrdef hash_file(filename, size=None, method="md5"):
101d60882f21c28087da2b33aad1670fe717388ba4almr    """
102d60882f21c28087da2b33aad1670fe717388ba4almr    Calculate the hash of filename.
103d60882f21c28087da2b33aad1670fe717388ba4almr    If size is not None, limit to first size bytes.
104d60882f21c28087da2b33aad1670fe717388ba4almr    Throw exception if something is wrong with filename.
105d60882f21c28087da2b33aad1670fe717388ba4almr    Can be also implemented with bash one-liner (assuming size%1024==0):
106d60882f21c28087da2b33aad1670fe717388ba4almr    dd if=filename bs=1024 count=size/1024 | sha1sum -
107d60882f21c28087da2b33aad1670fe717388ba4almr
108d60882f21c28087da2b33aad1670fe717388ba4almr    @param filename: Path of the file that will have its hash calculated.
109d60882f21c28087da2b33aad1670fe717388ba4almr    @param method: Method used to calculate the hash. Supported methods:
110d60882f21c28087da2b33aad1670fe717388ba4almr            * md5
111d60882f21c28087da2b33aad1670fe717388ba4almr            * sha1
112d60882f21c28087da2b33aad1670fe717388ba4almr    @returns: Hash of the file, if something goes wrong, return None.
113d60882f21c28087da2b33aad1670fe717388ba4almr    """
114d60882f21c28087da2b33aad1670fe717388ba4almr    chunksize = 4096
115d60882f21c28087da2b33aad1670fe717388ba4almr    fsize = os.path.getsize(filename)
116d60882f21c28087da2b33aad1670fe717388ba4almr
117d60882f21c28087da2b33aad1670fe717388ba4almr    if not size or size > fsize:
118d60882f21c28087da2b33aad1670fe717388ba4almr        size = fsize
119d60882f21c28087da2b33aad1670fe717388ba4almr    f = open(filename, 'rb')
120d60882f21c28087da2b33aad1670fe717388ba4almr
121d60882f21c28087da2b33aad1670fe717388ba4almr    try:
122d60882f21c28087da2b33aad1670fe717388ba4almr        hash = utils.hash(method)
123d60882f21c28087da2b33aad1670fe717388ba4almr    except ValueError:
124f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz        logging.error("Unknown hash type %s, returning None", method)
125d60882f21c28087da2b33aad1670fe717388ba4almr
126d60882f21c28087da2b33aad1670fe717388ba4almr    while size > 0:
127d60882f21c28087da2b33aad1670fe717388ba4almr        if chunksize > size:
128d60882f21c28087da2b33aad1670fe717388ba4almr            chunksize = size
129d60882f21c28087da2b33aad1670fe717388ba4almr        data = f.read(chunksize)
130d60882f21c28087da2b33aad1670fe717388ba4almr        if len(data) == 0:
131f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz            logging.debug("Nothing left to read but size=%d", size)
132d60882f21c28087da2b33aad1670fe717388ba4almr            break
133d60882f21c28087da2b33aad1670fe717388ba4almr        hash.update(data)
134d60882f21c28087da2b33aad1670fe717388ba4almr        size -= len(data)
135d60882f21c28087da2b33aad1670fe717388ba4almr    f.close()
136d60882f21c28087da2b33aad1670fe717388ba4almr    return hash.hexdigest()
137d60882f21c28087da2b33aad1670fe717388ba4almr
138d60882f21c28087da2b33aad1670fe717388ba4almr
139d60882f21c28087da2b33aad1670fe717388ba4almrdef unmap_url_cache(cachedir, url, expected_hash, method="md5"):
14053da18eddf69243ca175d9a4603cba5b55300726mbligh    """
1410afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Downloads a file from a URL to a cache directory. If the file is already
142d60882f21c28087da2b33aad1670fe717388ba4almr    at the expected position and has the expected hash, let's not download it
143d60882f21c28087da2b33aad1670fe717388ba4almr    again.
144d60882f21c28087da2b33aad1670fe717388ba4almr
145d60882f21c28087da2b33aad1670fe717388ba4almr    @param cachedir: Directory that might hold a copy of the file we want to
146d60882f21c28087da2b33aad1670fe717388ba4almr            download.
147d60882f21c28087da2b33aad1670fe717388ba4almr    @param url: URL for the file we want to download.
148d60882f21c28087da2b33aad1670fe717388ba4almr    @param expected_hash: Hash string that we expect the file downloaded to
149d60882f21c28087da2b33aad1670fe717388ba4almr            have.
150d60882f21c28087da2b33aad1670fe717388ba4almr    @param method: Method used to calculate the hash string (md5, sha1).
1510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
1520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # Let's convert cachedir to a canonical path, if it's not already
1530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    cachedir = os.path.realpath(cachedir)
1540afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if not os.path.isdir(cachedir):
1550afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        try:
156d60882f21c28087da2b33aad1670fe717388ba4almr            os.makedirs(cachedir)
1570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        except:
1580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            raise ValueError('Could not create cache directory %s' % cachedir)
1590afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    file_from_url = os.path.basename(url)
1600afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    file_local_path = os.path.join(cachedir, file_from_url)
161d60882f21c28087da2b33aad1670fe717388ba4almr
162d60882f21c28087da2b33aad1670fe717388ba4almr    file_hash = None
163d60882f21c28087da2b33aad1670fe717388ba4almr    failure_counter = 0
164d60882f21c28087da2b33aad1670fe717388ba4almr    while not file_hash == expected_hash:
165d60882f21c28087da2b33aad1670fe717388ba4almr        if os.path.isfile(file_local_path):
166d60882f21c28087da2b33aad1670fe717388ba4almr            file_hash = hash_file(file_local_path, method)
167d60882f21c28087da2b33aad1670fe717388ba4almr            if file_hash == expected_hash:
168d60882f21c28087da2b33aad1670fe717388ba4almr                # File is already at the expected position and ready to go
169d60882f21c28087da2b33aad1670fe717388ba4almr                src = file_from_url
170d60882f21c28087da2b33aad1670fe717388ba4almr            else:
171d60882f21c28087da2b33aad1670fe717388ba4almr                # Let's download the package again, it's corrupted...
172d60882f21c28087da2b33aad1670fe717388ba4almr                logging.error("Seems that file %s is corrupted, trying to "
173f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz                              "download it again", file_from_url)
174d60882f21c28087da2b33aad1670fe717388ba4almr                src = url
175d60882f21c28087da2b33aad1670fe717388ba4almr                failure_counter += 1
1760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        else:
177d60882f21c28087da2b33aad1670fe717388ba4almr            # File is not there, let's download it
1780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            src = url
179d60882f21c28087da2b33aad1670fe717388ba4almr        if failure_counter > 1:
180d60882f21c28087da2b33aad1670fe717388ba4almr            raise EnvironmentError("Consistently failed to download the "
181d60882f21c28087da2b33aad1670fe717388ba4almr                                   "package %s. Aborting further download "
182d60882f21c28087da2b33aad1670fe717388ba4almr                                   "attempts. This might mean either the "
183d60882f21c28087da2b33aad1670fe717388ba4almr                                   "network connection has problems or the "
184d60882f21c28087da2b33aad1670fe717388ba4almr                                   "expected hash string that was determined "
185f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz                                   "for this file is wrong", file_from_url)
186d60882f21c28087da2b33aad1670fe717388ba4almr        file_path = utils.unmap_url(cachedir, src, cachedir)
187d60882f21c28087da2b33aad1670fe717388ba4almr
188d60882f21c28087da2b33aad1670fe717388ba4almr    return file_path
189ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh
190ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh
191f4c35322b200d65f41a8332b4f3503beb497840dmblighdef force_copy(src, dest):
1920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Replace dest with a new copy of src, even if it exists"""
1930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isfile(dest):
1940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        os.remove(dest)
1950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isdir(dest):
1960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        dest = os.path.join(dest, os.path.basename(src))
1970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    shutil.copyfile(src, dest)
1980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return dest
199f4c35322b200d65f41a8332b4f3503beb497840dmbligh
200f4c35322b200d65f41a8332b4f3503beb497840dmbligh
201fdbcaec15092d8b4af80970c495038bdf9b0e63fmblighdef force_link(src, dest):
2020afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Link src to dest, overwriting it if it exists"""
2032da4d885be334f7db795c3f017daa06ff8ea703dmbligh    return utils.system("ln -sf %s %s" % (src, dest))
204fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
205fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
206cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmblighdef file_contains_pattern(file, pattern):
2070afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return true if file contains the specified egrep pattern"""
2080afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if not os.path.isfile(file):
2090afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise NameError('file %s does not exist' % file)
2102da4d885be334f7db795c3f017daa06ff8ea703dmbligh    return not utils.system('egrep -q "' + pattern + '" ' + file, ignore_status=True)
211cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
212cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
213cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmblighdef list_grep(list, pattern):
2140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """True if any item in list matches the specified pattern."""
2150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    compiled = re.compile(pattern)
2160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for line in list:
2170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        match = compiled.search(line)
2180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if (match):
2190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return 1
2200afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return 0
221cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
222987071e1fba830910658ce987bb803d142480c03mbligh
22342b81ca63a0ab336b844e9c5cce6fe30dae85357mblighdef get_os_vendor():
2240afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Try to guess what's the os vendor
2250afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
22690b97ff1834d2c65df82d9b830be7ebb1dbf2167mbligh    if os.path.isfile('/etc/SuSE-release'):
22790b97ff1834d2c65df82d9b830be7ebb1dbf2167mbligh        return 'SUSE'
22890b97ff1834d2c65df82d9b830be7ebb1dbf2167mbligh
2290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    issue = '/etc/issue'
2300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
2310afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if not os.path.isfile(issue):
2320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Unknown'
2330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
2340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if file_contains_pattern(issue, 'Red Hat'):
2350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Red Hat'
2362f29c19882287b5533312b1c4367819bf3a53f91mbligh    elif file_contains_pattern(issue, 'Fedora'):
2370afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Fedora Core'
2380afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif file_contains_pattern(issue, 'SUSE'):
2390afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'SUSE'
2400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif file_contains_pattern(issue, 'Ubuntu'):
2410afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Ubuntu'
2420afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif file_contains_pattern(issue, 'Debian'):
2430afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Debian'
2440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
2450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Unknown'
246af4efc23471265a3bfa7fef0146fbc0cbb54515bmbligh
247cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
2488a12e800f05f6862fc39c6a45c9c57d9051b795eEric Lidef get_cc():
2498a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li    try:
2508a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li        return os.environ['CC']
2518a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li    except KeyError:
2528a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li        return 'gcc'
2538a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li
2548a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li
255f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmblighdef get_vmlinux():
2560afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the full path to vmlinux
257c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
2580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Ahem. This is crap. Pray harder. Bad Martin.
2590afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
2602da4d885be334f7db795c3f017daa06ff8ea703dmbligh    vmlinux = '/boot/vmlinux-%s' % utils.system_output('uname -r')
2610afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isfile(vmlinux):
2620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return vmlinux
2632da4d885be334f7db795c3f017daa06ff8ea703dmbligh    vmlinux = '/lib/modules/%s/build/vmlinux' % utils.system_output('uname -r')
2640afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isfile(vmlinux):
2650afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return vmlinux
2660afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return None
267f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
268f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
269f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmblighdef get_systemmap():
2700afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the full path to System.map
271c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
2720afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Ahem. This is crap. Pray harder. Bad Martin.
2730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
2742da4d885be334f7db795c3f017daa06ff8ea703dmbligh    map = '/boot/System.map-%s' % utils.system_output('uname -r')
2750afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isfile(map):
2760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return map
2772da4d885be334f7db795c3f017daa06ff8ea703dmbligh    map = '/lib/modules/%s/build/System.map' % utils.system_output('uname -r')
2780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isfile(map):
2790afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return map
2800afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return None
28167b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh
28267b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh
28367b5ece7667fc71429ee05b07ac7654ed5a05df7mblighdef get_modules_dir():
2840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the modules dir for the running kernel version"""
2852da4d885be334f7db795c3f017daa06ff8ea703dmbligh    kernel_version = utils.system_output('uname -r')
2860afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return '/lib/modules/%s/kernel' % kernel_version
287f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
288f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
2895970cf057674accdb00a7742eae50e40c57e52d0mblighdef get_cpu_arch():
2900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Work out which CPU architecture we're running on"""
2910afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    f = open('/proc/cpuinfo', 'r')
2920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    cpuinfo = f.readlines()
2930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    f.close()
2940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if list_grep(cpuinfo, '^cpu.*(RS64|POWER3|Broadband Engine)'):
2950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'power'
2960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif list_grep(cpuinfo, '^cpu.*POWER4'):
2970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'power4'
2980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif list_grep(cpuinfo, '^cpu.*POWER5'):
2990afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'power5'
3000afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif list_grep(cpuinfo, '^cpu.*POWER6'):
3010afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'power6'
3020758c82ce9ef641b746b5b9a2d0ce409ba6169c7mbligh    elif list_grep(cpuinfo, '^cpu.*POWER7'):
3030758c82ce9ef641b746b5b9a2d0ce409ba6169c7mbligh        return 'power7'
3040afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif list_grep(cpuinfo, '^cpu.*PPC970'):
3050afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'power970'
306f23fd920c08ca1734e2dd2827a494619f53694c2mbligh    elif list_grep(cpuinfo, 'ARM'):
307f23fd920c08ca1734e2dd2827a494619f53694c2mbligh        return 'arm'
30812e8b89ac5a26bf29bc89c4d19f2771fa715f52dmbligh    elif list_grep(cpuinfo, '^flags.*:.* lm .*'):
3090afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'x86_64'
3100afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
3110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'i386'
312f4c35322b200d65f41a8332b4f3503beb497840dmbligh
3137c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtzdef get_arm_soc_family():
3147c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    """Work out which ARM SoC we're running on"""
3157c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    f = open('/proc/cpuinfo', 'r')
3167c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    cpuinfo = f.readlines()
3177c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    f.close()
3187c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    if list_grep(cpuinfo, 'EXYNOS5'):
3197c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz        return 'exynos5'
3207c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    elif list_grep(cpuinfo, 'Tegra'):
3217c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz        return 'tegra'
3227c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    return 'arm'
3237c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz
324171137407ec2d93db48123a4331929c8e9290cbbDaniel Kurtzdef get_cpu_soc_family():
3257c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    """Like get_cpu_arch, but for ARM, returns the SoC family name"""
3267c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    family = get_cpu_arch()
3277c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    if family == 'arm':
3287c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz       family = get_arm_soc_family()
3297c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    return family
330f4c35322b200d65f41a8332b4f3503beb497840dmbligh
331548f29af9e38f87c3609838f5aabeac94bb69f13mblighdef get_current_kernel_arch():
3320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Get the machine architecture, now just a wrap of 'uname -m'."""
3330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return os.popen('uname -m').read().rstrip()
334cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
335cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
336fdbcaec15092d8b4af80970c495038bdf9b0e63fmblighdef get_file_arch(filename):
3370afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # -L means follow symlinks
3382da4d885be334f7db795c3f017daa06ff8ea703dmbligh    file_data = utils.system_output('file -L ' + filename)
3390afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if file_data.count('80386'):
3400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'i386'
3410afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return None
342fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
343fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
344f4c35322b200d65f41a8332b4f3503beb497840dmblighdef count_cpus():
3450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """number of CPUs in the local machine according to /proc/cpuinfo"""
34646589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang    try:
34746589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang      return multiprocessing.cpu_count()
34846589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang    except Exception as e:
34946589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang      logging.exception('can not get cpu count from'
35046589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang                        ' multiprocessing.cpu_count()')
35146589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang
3520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    f = file('/proc/cpuinfo', 'r')
3530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    cpus = 0
3540afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for line in f.readlines():
35546589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang        # Matches lines like "processor      : 0"
35646589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang        if re.search(r'^processor\s*:\s*[0-9]+$', line):
3570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            cpus += 1
35846589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang    # Returns at least one cpu. Check comment #1 in crosbug.com/p/9582.
35946589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang    return cpus if cpus > 0 else 1
360f4c35322b200d65f41a8332b4f3503beb497840dmbligh
361e7a170fb097da48af81ca598e29643f3e7cca584mbligh
362e7a170fb097da48af81ca598e29643f3e7cca584mbligh# Returns total memory in kb
363558885e290e3fa847b6a77b6dd66cac33ec6f65cmblighdef read_from_meminfo(key):
3642da4d885be334f7db795c3f017daa06ff8ea703dmbligh    meminfo = utils.system_output('grep %s /proc/meminfo' % key)
3650afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return int(re.search(r'\d+', meminfo).group(0))
366558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
367558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
368e7a170fb097da48af81ca598e29643f3e7cca584mblighdef memtotal():
3690afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return read_from_meminfo('MemTotal')
370558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
371558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
372558885e290e3fa847b6a77b6dd66cac33ec6f65cmblighdef freememtotal():
3730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return read_from_meminfo('MemFree')
374558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
375b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivatdef usable_memtotal():
376b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat    # Assume 30MB reserved by the OS
377b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat    reserved = 30 * 1024
378b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat    ret = read_from_meminfo('MemFree')
379b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat    ret += read_from_meminfo('Buffers')
380b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat    ret += read_from_meminfo('Cached')
381b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat    ret = max(0, ret - reserved)
382b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat    return ret
383b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat
384558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
3858493be44f65668c6ebad5d1bee3b97b76abdebbdmblighdef rounded_memtotal():
38653da18eddf69243ca175d9a4603cba5b55300726mbligh    # Get total of all physical mem, in kbytes
38753da18eddf69243ca175d9a4603cba5b55300726mbligh    usable_kbytes = memtotal()
38853da18eddf69243ca175d9a4603cba5b55300726mbligh    # usable_kbytes is system's usable DRAM in kbytes,
3898493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   as reported by memtotal() from device /proc/meminfo memtotal
3908493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   after Linux deducts 1.5% to 5.1% for system table overhead
3918493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # Undo the unknown actual deduction by rounding up
3928493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   to next small multiple of a big power-of-two
3938493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   eg  12GB - 5.1% gets rounded back up to 12GB
3948493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    mindeduct = 0.015  # 1.5 percent
3958493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    maxdeduct = 0.055  # 5.5 percent
3968493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # deduction range 1.5% .. 5.5% supports physical mem sizes
3978493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #    6GB .. 12GB in steps of .5GB
3988493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   12GB .. 24GB in steps of 1 GB
3998493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   24GB .. 48GB in steps of 2 GB ...
4008493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # Finer granularity in physical mem sizes would require
4018493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   tighter spread between min and max possible deductions
4028493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh
4038493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # increase mem size by at least min deduction, without rounding
404b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat    min_kbytes = int(usable_kbytes / (1.0 - mindeduct))
4058493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # increase mem size further by 2**n rounding, by 0..roundKb or more
40653da18eddf69243ca175d9a4603cba5b55300726mbligh    round_kbytes = int(usable_kbytes / (1.0 - maxdeduct)) - min_kbytes
4078493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # find least binary roundup 2**n that covers worst-cast roundKb
40853da18eddf69243ca175d9a4603cba5b55300726mbligh    mod2n = 1 << int(math.ceil(math.log(round_kbytes, 2)))
40953da18eddf69243ca175d9a4603cba5b55300726mbligh    # have round_kbytes <= mod2n < round_kbytes*2
41053da18eddf69243ca175d9a4603cba5b55300726mbligh    # round min_kbytes up to next multiple of mod2n
41153da18eddf69243ca175d9a4603cba5b55300726mbligh    phys_kbytes = min_kbytes + mod2n - 1
41253da18eddf69243ca175d9a4603cba5b55300726mbligh    phys_kbytes = phys_kbytes - (phys_kbytes % mod2n)  # clear low bits
41353da18eddf69243ca175d9a4603cba5b55300726mbligh    return phys_kbytes
4148493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh
4158493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh
416f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanskidef sysctl(key, value=None):
417f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    """Generic implementation of sysctl, to read and write.
418f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
419f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    @param key: A location under /proc/sys
420f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    @param value: If not None, a value to write into the sysctl.
421f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
422f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    @return The single-line sysctl value as a string.
423f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    """
424f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    path = '/proc/sys/%s' % key
425f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    if value is not None:
426f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski        utils.write_one_line(path, str(value))
427f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    return utils.read_one_line(path)
428f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
429f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
430558885e290e3fa847b6a77b6dd66cac33ec6f65cmblighdef sysctl_kernel(key, value=None):
4310afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """(Very) partial implementation of sysctl, for kernel params"""
432f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    if value is not None:
4330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # write
4342da4d885be334f7db795c3f017daa06ff8ea703dmbligh        utils.write_one_line('/proc/sys/kernel/%s' % key, str(value))
4350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
4360afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # read
4372da4d885be334f7db795c3f017daa06ff8ea703dmbligh        out = utils.read_one_line('/proc/sys/kernel/%s' % key)
4380afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return int(re.search(r'\d+', out).group(0))
439e7a170fb097da48af81ca598e29643f3e7cca584mbligh
440e7a170fb097da48af81ca598e29643f3e7cca584mbligh
4415285a2dc3c5edbc010825e6d64ecdb219b3ad52cmblighdef _convert_exit_status(sts):
4420afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.WIFSIGNALED(sts):
4430afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return -os.WTERMSIG(sts)
4440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif os.WIFEXITED(sts):
4450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return os.WEXITSTATUS(sts)
4460afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
4470afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # impossible?
4480afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise RuntimeError("Unknown exit status %d!" % sts)
4495285a2dc3c5edbc010825e6d64ecdb219b3ad52cmbligh
4505285a2dc3c5edbc010825e6d64ecdb219b3ad52cmbligh
451f4c35322b200d65f41a8332b4f3503beb497840dmblighdef where_art_thy_filehandles():
4520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Dump the current list of filehandles"""
4530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    os.system("ls -l /proc/%d/fd >> /dev/tty" % os.getpid())
454f4c35322b200d65f41a8332b4f3503beb497840dmbligh
455f4c35322b200d65f41a8332b4f3503beb497840dmbligh
456f4c35322b200d65f41a8332b4f3503beb497840dmblighdef print_to_tty(string):
4570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Output string straight to the tty"""
4580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    open('/dev/tty', 'w').write(string + '\n')
459f4c35322b200d65f41a8332b4f3503beb497840dmbligh
460f4c35322b200d65f41a8332b4f3503beb497840dmbligh
461b8a14e358b611f2d97c06e863be9b53ab2bedeefmblighdef dump_object(object):
4620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Dump an object's attributes and methods
463c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
4640afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    kind of like dir()
4650afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
4660afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for item in object.__dict__.iteritems():
4670afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        print item
4680afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        try:
469b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat            (key, value) = item
4700afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            dump_object(value)
4710afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        except:
4720afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            continue
473b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh
474b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh
4754b089663460063b638124ff665f38d2fe7427648mblighdef environ(env_key):
4760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """return the requested environment variable, or '' if unset"""
4770afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if (os.environ.has_key(env_key)):
4780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return os.environ[env_key]
4790afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
4800afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return ''
4814b089663460063b638124ff665f38d2fe7427648mbligh
4824b089663460063b638124ff665f38d2fe7427648mbligh
4834b089663460063b638124ff665f38d2fe7427648mblighdef prepend_path(newpath, oldpath):
4840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """prepend newpath to oldpath"""
4850afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if (oldpath):
4860afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return newpath + ':' + oldpath
4870afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
4880afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return newpath
4894b089663460063b638124ff665f38d2fe7427648mbligh
4904b089663460063b638124ff665f38d2fe7427648mbligh
4914b089663460063b638124ff665f38d2fe7427648mblighdef append_path(oldpath, newpath):
4920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """append newpath to oldpath"""
4930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if (oldpath):
4940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return oldpath + ':' + newpath
4950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
4960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return newpath
4974b089663460063b638124ff665f38d2fe7427648mbligh
4984b089663460063b638124ff665f38d2fe7427648mbligh
4994e75b0d3b020f901456217fb8ff0d7d4391fa869mblighdef avgtime_print(dir):
5000afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """ Calculate some benchmarking statistics.
5010afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        Input is a directory containing a file called 'time'.
5020afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        File contains one-per-line results of /usr/bin/time.
5030afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        Output is average Elapsed, User, and System time in seconds,
5040afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski          and average CPU percentage.
5050afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
5060afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    f = open(dir + "/time")
5070afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    user = system = elapsed = cpu = count = 0
5080afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    r = re.compile('([\d\.]*)user ([\d\.]*)system (\d*):([\d\.]*)elapsed (\d*)%CPU')
5090afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for line in f.readlines():
5100afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        try:
5110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            s = r.match(line);
5120afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            user += float(s.group(1))
5130afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            system += float(s.group(2))
5140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            elapsed += (float(s.group(3)) * 60) + float(s.group(4))
5150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            cpu += float(s.group(5))
5160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            count += 1
5170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        except:
5180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            raise ValueError("badly formatted times")
5190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
5200afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    f.close()
5210afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return "Elapsed: %0.2fs User: %0.2fs System: %0.2fs CPU: %0.0f%%" % \
522b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat          (elapsed / count, user / count, system / count, cpu / count)
5234e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh
5244e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh
525f06db0f9b381737b9c85bef1c23ea1a1ca73c559mblighdef running_config():
5260afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
5270afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Return path of config file of the currently running kernel
5280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
5292da4d885be334f7db795c3f017daa06ff8ea703dmbligh    version = utils.system_output('uname -r')
5300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for config in ('/proc/config.gz', \
5310afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   '/boot/config-%s' % version,
5320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   '/lib/modules/%s/build/.config' % version):
5330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if os.path.isfile(config):
5340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return config
5350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return None
5369ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh
5379ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh
538a1bef1f2774b539df11c134d9a9a177304c34f3cmblighdef check_for_kernel_feature(feature):
5390afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    config = running_config()
540a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
5410afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if not config:
5420afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise TypeError("Can't find kernel config file")
543a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
544959e8162836703848f8e1801f74e7117b850e889lmr    if magic.guess_type(config) == 'application/x-gzip':
5450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        grep = 'zgrep'
5460afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
5470afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        grep = 'grep'
5480afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    grep += ' ^CONFIG_%s= %s' % (feature, config)
549a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
5502da4d885be334f7db795c3f017daa06ff8ea703dmbligh    if not utils.system_output(grep, ignore_status=True):
5510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise ValueError("Kernel doesn't have a %s feature" % (feature))
552a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
553a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
5549ec8acc50c0fe06a40353db0df8e135cebb2ec58mblighdef cpu_online_map():
5550afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
5560afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Check out the available cpu online map
5570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
5580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    cpus = []
5590afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for line in open('/proc/cpuinfo', 'r').readlines():
5600afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if line.startswith('processor'):
5610afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            cpus.append(line.split()[2]) # grab cpu number
5620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return cpus
563663e4f664465dbaa9e86c5c20d035ad9bd1e65edmbligh
564663e4f664465dbaa9e86c5c20d035ad9bd1e65edmbligh
565663e4f664465dbaa9e86c5c20d035ad9bd1e65edmblighdef check_glibc_ver(ver):
5660afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    glibc_ver = commands.getoutput('ldd --version').splitlines()[0]
5670afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    glibc_ver = re.search(r'(\d+\.\d+(\.\d+)?)', glibc_ver).group()
5680fab1e986e36dd9addaa075c6c73e71fbd756652lmr    if utils.compare_versions(glibc_ver, ver) == -1:
5690fab1e986e36dd9addaa075c6c73e71fbd756652lmr        raise error.TestError("Glibc too old (%s). Glibc >= %s is needed." %
5700fab1e986e36dd9addaa075c6c73e71fbd756652lmr                              (glibc_ver, ver))
5710763522bf0dcd6297385a7db965086ed8ba18adambligh
5720763522bf0dcd6297385a7db965086ed8ba18adamblighdef check_kernel_ver(ver):
5732da4d885be334f7db795c3f017daa06ff8ea703dmbligh    kernel_ver = utils.system_output('uname -r')
5740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    kv_tmp = re.split(r'[-]', kernel_ver)[0:3]
57542b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr    # In compare_versions, if v1 < v2, return value == -1
57642b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr    if utils.compare_versions(kv_tmp[0], ver) == -1:
57742b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr        raise error.TestError("Kernel too old (%s). Kernel > %s is needed." %
57842b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr                              (kernel_ver, ver))
57960418bb82d1734a7f73a5e4c8870d06799795397mbligh
5809061a273dfd2e522c15f6dd77cfed1e2815e4e9embligh
581264cd8f4889cea73fa5fb7873e3243c1c770a1bcmblighdef human_format(number):
5820afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # Convert number to kilo / mega / giga format.
5830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if number < 1024:
5840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return "%d" % number
5850afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    kilo = float(number) / 1024.0
5860afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if kilo < 1024:
5870afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return "%.2fk" % kilo
5880afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    meg = kilo / 1024.0
5890afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if meg < 1024:
5900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return "%.2fM" % meg
5910afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    gig = meg / 1024.0
5920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return "%.2fG" % gig
593264cd8f4889cea73fa5fb7873e3243c1c770a1bcmbligh
5948eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
5958eca3a98728afabc7fc761c08dbb8e91260c7de4mblighdef numa_nodes():
5960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    node_paths = glob.glob('/sys/devices/system/node/node*')
5970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    nodes = [int(re.sub(r'.*node(\d+)', r'\1', x)) for x in node_paths]
5980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return (sorted(nodes))
5998eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
6008eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
6018eca3a98728afabc7fc761c08dbb8e91260c7de4mblighdef node_size():
6020afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    nodes = max(len(numa_nodes()), 1)
6030afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return ((memtotal() * 1024) / nodes)
6048eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
60532bcff3382844181eaf3d74e0fb252d88edfc8fbmbligh
60632bcff3382844181eaf3d74e0fb252d88edfc8fbmblighdef to_seconds(time_string):
6070afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Converts a string in M+:SS.SS format to S+.SS"""
6080afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elts = time_string.split(':')
6090afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if len(elts) == 1:
6100afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return time_string
6110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return str(int(elts[0]) * 60 + float(elts[1]))
61232bcff3382844181eaf3d74e0fb252d88edfc8fbmbligh
61332bcff3382844181eaf3d74e0fb252d88edfc8fbmbligh
61432bcff3382844181eaf3d74e0fb252d88edfc8fbmblighdef extract_all_time_results(results_string):
6150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Extract user, system, and elapsed times into a list of tuples"""
6160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    pattern = re.compile(r"(.*?)user (.*?)system (.*?)elapsed")
6170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    results = []
6180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for result in pattern.findall(results_string):
6190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        results.append(tuple([to_seconds(elt) for elt in result]))
6200afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return results
621c421164e16db7233ef8fcc4ecfd83f2979aec16ambligh
622c421164e16db7233ef8fcc4ecfd83f2979aec16ambligh
623c421164e16db7233ef8fcc4ecfd83f2979aec16amblighdef pickle_load(filename):
6240afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return pickle.load(open(filename, 'r'))
625c421164e16db7233ef8fcc4ecfd83f2979aec16ambligh
626237bed32e0110ccd0db10823df742534dd7dc50dmbligh
627237bed32e0110ccd0db10823df742534dd7dc50dmbligh# Return the kernel version and build timestamp.
628237bed32e0110ccd0db10823df742534dd7dc50dmblighdef running_os_release():
6290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return os.uname()[2:4]
630237bed32e0110ccd0db10823df742534dd7dc50dmbligh
631237bed32e0110ccd0db10823df742534dd7dc50dmbligh
632237bed32e0110ccd0db10823df742534dd7dc50dmblighdef running_os_ident():
6330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    (version, timestamp) = running_os_release()
6340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return version + '::' + timestamp
635b830e28297dca51aed2c4b57469a3e04845e54e7mbligh
636b830e28297dca51aed2c4b57469a3e04845e54e7mbligh
6373bf79ca4d5490f9af09e1ddc39b8df5343b34d06mblighdef running_os_full_version():
6383bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh    (version, timestamp) = running_os_release()
6393bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh    return version
6403bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh
6413bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh
642523a19b532a778dd9e752e507ac75d3ffc5c701ambligh# much like find . -name 'pattern'
643523a19b532a778dd9e752e507ac75d3ffc5c701amblighdef locate(pattern, root=os.getcwd()):
6440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for path, dirs, files in os.walk(root):
645987071e1fba830910658ce987bb803d142480c03mbligh        for f in files:
646987071e1fba830910658ce987bb803d142480c03mbligh            if fnmatch.fnmatch(f, pattern):
6477076b192936caad193898cff194e82f83dd13d63mbligh                yield os.path.abspath(os.path.join(path, f))
648523a19b532a778dd9e752e507ac75d3ffc5c701ambligh
649523a19b532a778dd9e752e507ac75d3ffc5c701ambligh
65025bb1e1fbb67950ac480f6500138c19647472889mblighdef freespace(path):
6510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the disk free space, in bytes"""
6520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    s = os.statvfs(path)
6530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return s.f_bavail * s.f_bsize
6548415f966acaaa3aa3ca6a651d9a190081edbb0eejadmanski
6558415f966acaaa3aa3ca6a651d9a190081edbb0eejadmanski
6568415f966acaaa3aa3ca6a651d9a190081edbb0eejadmanskidef disk_block_size(path):
6570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the disk block size, in bytes"""
6580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return os.statvfs(path).f_bsize
6596de9cdfe8ce95c1d87b01aa768526a64755090cambligh
6606de9cdfe8ce95c1d87b01aa768526a64755090cambligh
6616de9cdfe8ce95c1d87b01aa768526a64755090camblighdef get_cpu_family():
6622da4d885be334f7db795c3f017daa06ff8ea703dmbligh    procinfo = utils.system_output('cat /proc/cpuinfo')
6630afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    CPU_FAMILY_RE = re.compile(r'^cpu family\s+:\s+(\S+)', re.M)
6640afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    matches = CPU_FAMILY_RE.findall(procinfo)
6650afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if matches:
6660afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return int(matches[0])
6670afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
6680afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise error.TestError('Could not get valid cpu family data')
6696de9cdfe8ce95c1d87b01aa768526a64755090cambligh
6703e9062e854a920eead8e250c4e79838c30a0657cmbligh
6712316e52c84ac8799330c52359bc4dd5e7f7324d5mblighdef get_disks():
6722da4d885be334f7db795c3f017daa06ff8ea703dmbligh    df_output = utils.system_output('df')
6730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    disk_re = re.compile(r'^(/dev/hd[a-z]+)3', re.M)
6740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return disk_re.findall(df_output)
6756de9cdfe8ce95c1d87b01aa768526a64755090cambligh
6763e9062e854a920eead8e250c4e79838c30a0657cmbligh
6778b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivatdef get_disk_size(disk_name):
6788b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
6798b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    Return size of disk in byte. Return 0 in Error Case
6808b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
6818b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    @param disk_name: disk name to find size
6828b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
6838b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    device = os.path.basename(disk_name)
6848b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    for line in file('/proc/partitions'):
6858b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat        try:
68610e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            _, _, blocks, name = re.split(r' +', line.strip())
6878b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat        except ValueError:
6888b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat            continue
6898b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat        if name == device:
6908b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat            return 1024 * int(blocks)
6918b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    return 0
6928b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
6938b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
6948b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivatdef get_disk_size_gb(disk_name):
6958b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
6968b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    Return size of disk in GB (10^9). Return 0 in Error Case
6978b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
6988b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    @param disk_name: disk name to find size
6998b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
7008b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    return int(get_disk_size(disk_name) / (10.0 ** 9) + 0.5)
7018b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7028b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7038b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivatdef get_disk_model(disk_name):
7048b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
7058b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    Return model name for internal storage device
7068b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7078b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    @param disk_name: disk name to find model
7088b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
7098b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    cmd1 = 'udevadm info --query=property --name=%s' % disk_name
7108b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    cmd2 = 'grep -E "ID_(NAME|MODEL)="'
7118b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    cmd3 = 'cut -f 2 -d"="'
7128b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    cmd = ' | '.join([cmd1, cmd2, cmd3])
7138b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    return utils.system_output(cmd)
7148b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7158b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
71610e71e69c71002f312f7282b3180dda3db5854adGwendal Grignoudef get_disk_from_filename(filename):
71710e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    """
71810e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    Return the disk device the filename is on.
71910e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    If the file is on tmpfs or other special file systems,
72010e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    return None.
72110e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
72210e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    @param filename: name of file, full path.
72310e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    """
72410e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    re_disk = re.compile('/dev/sd[a-z]|/dev/mmcblk[0-9]*')
72510e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
72610e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    if not os.path.isfile(filename):
72710e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        raise error.TestError('file %s missing' % filename)
72810e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
72910e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    if filename[0] != '/':
73010e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        raise error.TestError('This code works only with full path')
73110e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
73210e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    m = re_disk.match(filename)
73310e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    while not m:
73410e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        if filename[0] != '/':
73510e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            return None
73610e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        if filename == '/dev/root':
73710e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            cmd = 'rootdev -d -s'
73810e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        elif filename.startswith('/dev/mapper'):
73910e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            cmd = 'dmsetup table "%s"' % os.path.basename(filename)
74010e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            dmsetup_output = utils.system_output(cmd).split(' ')
74110e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            if dmsetup_output[2] == 'verity':
74210e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou                maj_min = dmsetup_output[4]
74310e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            elif dmsetup_output[2] == 'crypt':
74410e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou                maj_min = dmsetup_output[6]
74510e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            cmd = 'realpath "/dev/block/%s"' % maj_min
74610e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        elif filename.startswith('/dev/loop'):
74710e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            cmd = 'losetup -O BACK-FILE "%s" | tail -1' % filename
74810e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        else:
74910e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            cmd = 'df "%s" | tail -1 | cut -f 1 -d" "' % filename
75010e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        filename = utils.system_output(cmd)
75110e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        m = re_disk.match(filename)
75210e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    return m.group(0)
75310e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
75410e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
7558ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivatdef get_disk_firmware_version(disk_name):
7568ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
7578ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    Return firmware version for internal storage device. (empty string for eMMC)
7588ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7598ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param disk_name: disk name to find model
7608ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
7618ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd1 = 'udevadm info --query=property --name=%s' % disk_name
7628ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd2 = 'grep -E "ID_REVISION="'
7638ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd3 = 'cut -f 2 -d"="'
7648ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd = ' | '.join([cmd1, cmd2, cmd3])
7658ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    return utils.system_output(cmd)
7668ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7678ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7688ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivatdef is_disk_scsi(disk_name):
7698ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
7708ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    Return true if disk is a scsi device, return false otherwise
7718ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7728ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param disk_name: disk name check
7738ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
7748ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    return re.match('/dev/sd[a-z]+', disk_name)
7758ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7768ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7778ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivatdef is_disk_harddisk(disk_name):
7788ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
7798ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    Return true if disk is a harddisk, return false otherwise
7808ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7818ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param disk_name: disk name check
7828ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
7838ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd1 = 'udevadm info --query=property --name=%s' % disk_name
7848ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd2 = 'grep -E "ID_ATA_ROTATION_RATE_RPM="'
7858ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd3 = 'cut -f 2 -d"="'
7868ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd = ' | '.join([cmd1, cmd2, cmd3])
7878ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7888ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    rtt = utils.system_output(cmd)
7898ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7908ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    # eMMC will not have this field; rtt == ''
7918ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    # SSD will have zero rotation rate; rtt == '0'
7928ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    # For harddisk rtt > 0
7938ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    return rtt and int(rtt) > 0
7948ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7958ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
7968ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivatdef verify_hdparm_feature(disk_name, feature):
7978ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
7988ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    Check for feature support for SCSI disk using hdparm
7998ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8008ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param disk_name: target disk
8018ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param feature: hdparm output string of the feature
8028ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8038ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd = 'hdparm -I %s | grep -q "%s"' % (disk_name, feature)
8048ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    ret = utils.system(cmd, ignore_status=True)
8058ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    if ret == 0:
8068ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat        return True
8078ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    elif ret == 1:
8088ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat        return False
8098ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    else:
8108ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat        raise error.TestFail('Error running command %s' % cmd)
8118ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8128ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8138ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivatdef get_storage_error_msg(disk_name, reason):
8148ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8158ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    Get Error message for storage test which include disk model.
8168ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    and also include the firmware version for the SCSI disk
8178ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8188ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param disk_name: target disk
8198ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param reason: Reason of the error.
8208ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8218ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8228ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    msg = reason
8238ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8248ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    model = get_disk_model(disk_name)
8258ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    msg += ' Disk model: %s' % model
8268ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8278ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    if is_disk_scsi(disk_name):
8288ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat        fw = get_disk_firmware_version(disk_name)
8298ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat        msg += ' firmware: %s' % fw
8308ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8318ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    return msg
8328ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8338ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8343e9062e854a920eead8e250c4e79838c30a0657cmblighdef load_module(module_name):
8350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # Checks if a module has already been loaded
8360afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if module_is_loaded(module_name):
8370afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return False
838af4efc23471265a3bfa7fef0146fbc0cbb54515bmbligh
8392da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system('/sbin/modprobe ' + module_name)
8400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return True
8413e9062e854a920eead8e250c4e79838c30a0657cmbligh
8423e9062e854a920eead8e250c4e79838c30a0657cmbligh
8433e9062e854a920eead8e250c4e79838c30a0657cmblighdef unload_module(module_name):
844b923fc2a01db6e4548ffd541d86f9be49bc5805almr    """
845b923fc2a01db6e4548ffd541d86f9be49bc5805almr    Removes a module. Handles dependencies. If even then it's not possible
846b923fc2a01db6e4548ffd541d86f9be49bc5805almr    to remove one of the modules, it will trhow an error.CmdError exception.
847b923fc2a01db6e4548ffd541d86f9be49bc5805almr
848b923fc2a01db6e4548ffd541d86f9be49bc5805almr    @param module_name: Name of the module we want to remove.
849b923fc2a01db6e4548ffd541d86f9be49bc5805almr    """
850abbd237f6e10e469e11682669bd49ed8f61e42b8Henrik Kjellander    l_raw = utils.system_output("/bin/lsmod").splitlines()
851b923fc2a01db6e4548ffd541d86f9be49bc5805almr    lsmod = [x for x in l_raw if x.split()[0] == module_name]
852b923fc2a01db6e4548ffd541d86f9be49bc5805almr    if len(lsmod) > 0:
853b923fc2a01db6e4548ffd541d86f9be49bc5805almr        line_parts = lsmod[0].split()
854b923fc2a01db6e4548ffd541d86f9be49bc5805almr        if len(line_parts) == 4:
855b923fc2a01db6e4548ffd541d86f9be49bc5805almr            submodules = line_parts[3].split(",")
856b923fc2a01db6e4548ffd541d86f9be49bc5805almr            for submodule in submodules:
857b923fc2a01db6e4548ffd541d86f9be49bc5805almr                unload_module(submodule)
858b923fc2a01db6e4548ffd541d86f9be49bc5805almr        utils.system("/sbin/modprobe -r %s" % module_name)
859f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz        logging.info("Module %s unloaded", module_name)
860b923fc2a01db6e4548ffd541d86f9be49bc5805almr    else:
861f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz        logging.info("Module %s is already unloaded", module_name)
8623e9062e854a920eead8e250c4e79838c30a0657cmbligh
8633e9062e854a920eead8e250c4e79838c30a0657cmbligh
8643e9062e854a920eead8e250c4e79838c30a0657cmblighdef module_is_loaded(module_name):
8650afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    module_name = module_name.replace('-', '_')
866abbd237f6e10e469e11682669bd49ed8f61e42b8Henrik Kjellander    modules = utils.system_output('/bin/lsmod').splitlines()
8670afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for module in modules:
8680afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if module.startswith(module_name) and module[len(module_name)] == ' ':
8690afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return True
8700afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return False
8713e9062e854a920eead8e250c4e79838c30a0657cmbligh
8723e9062e854a920eead8e250c4e79838c30a0657cmbligh
8736b34c4cc34bebd20def94c0191ef1e46dd6a1cdemblighdef get_loaded_modules():
874abbd237f6e10e469e11682669bd49ed8f61e42b8Henrik Kjellander    lsmod_output = utils.system_output('/bin/lsmod').splitlines()[1:]
8750afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return [line.split(None, 1)[0] for line in lsmod_output]
8766b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
8776b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
8783e9062e854a920eead8e250c4e79838c30a0657cmblighdef get_huge_page_size():
8792da4d885be334f7db795c3f017daa06ff8ea703dmbligh    output = utils.system_output('grep Hugepagesize /proc/meminfo')
8800afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return int(output.split()[1]) # Assumes units always in kB. :(
8813e9062e854a920eead8e250c4e79838c30a0657cmbligh
8823e9062e854a920eead8e250c4e79838c30a0657cmbligh
8833e9062e854a920eead8e250c4e79838c30a0657cmblighdef get_num_huge_pages():
8842da4d885be334f7db795c3f017daa06ff8ea703dmbligh    raw_hugepages = utils.system_output('/sbin/sysctl vm.nr_hugepages')
8850afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return int(raw_hugepages.split()[2])
8863e9062e854a920eead8e250c4e79838c30a0657cmbligh
8873e9062e854a920eead8e250c4e79838c30a0657cmbligh
8883e9062e854a920eead8e250c4e79838c30a0657cmblighdef set_num_huge_pages(num):
8892da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system('/sbin/sysctl vm.nr_hugepages=%d' % num)
8903e9062e854a920eead8e250c4e79838c30a0657cmbligh
8913e9062e854a920eead8e250c4e79838c30a0657cmbligh
8926b34c4cc34bebd20def94c0191ef1e46dd6a1cdemblighdef get_cpu_vendor():
8930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    cpuinfo = open('/proc/cpuinfo').read()
8940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    vendors = re.findall(r'(?m)^vendor_id\s*:\s*(\S+)\s*$', cpuinfo)
8950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for i in xrange(1, len(vendors)):
8960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if vendors[i] != vendors[0]:
8970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            raise error.TestError('multiple cpu vendors found: ' + str(vendors))
8980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return vendors[0]
8996b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
9006b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
9016b34c4cc34bebd20def94c0191ef1e46dd6a1cdemblighdef probe_cpus():
9020afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
90353da18eddf69243ca175d9a4603cba5b55300726mbligh    This routine returns a list of cpu devices found under
90453da18eddf69243ca175d9a4603cba5b55300726mbligh    /sys/devices/system/cpu.
9050afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
90653da18eddf69243ca175d9a4603cba5b55300726mbligh    cmd = 'find /sys/devices/system/cpu/ -maxdepth 1 -type d -name cpu*'
9072da4d885be334f7db795c3f017daa06ff8ea703dmbligh    return utils.system_output(cmd).splitlines()
9086b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
9096b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
91070c50ad0eec36f4678374040031da84150a75997mblighdef ping_default_gateway():
9110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Ping the default gateway."""
91270c50ad0eec36f4678374040031da84150a75997mbligh
9130afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    network = open('/etc/sysconfig/network')
9140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    m = re.search('GATEWAY=(\S+)', network.read())
9150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
9160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if m:
9170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        gw = m.group(1)
9180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        cmd = 'ping %s -c 5 > /dev/null' % gw
9192da4d885be334f7db795c3f017daa06ff8ea703dmbligh        return utils.system(cmd, ignore_status=True)
9200afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
9210afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    raise error.TestError('Unable to find default gateway')
92270c50ad0eec36f4678374040031da84150a75997mbligh
92370c50ad0eec36f4678374040031da84150a75997mbligh
924115feb2fee75e8cb75873905f07763fbfafc8f6ejadmanskidef drop_caches():
925115feb2fee75e8cb75873905f07763fbfafc8f6ejadmanski    """Writes back all dirty pages to disk and clears all the caches."""
9262da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system("sync")
927115feb2fee75e8cb75873905f07763fbfafc8f6ejadmanski    # We ignore failures here as this will fail on 2.6.11 kernels.
9282da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system("echo 3 > /proc/sys/vm/drop_caches", ignore_status=True)
929a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh
930a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh
931e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mblighdef process_is_alive(name_pattern):
932a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    """
933a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    'pgrep name' misses all python processes and also long process names.
934a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    'pgrep -f name' gets all shell commands with name in args.
935e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mbligh    So look only for command whose initial pathname ends with name.
936e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mbligh    Name itself is an egrep pattern, so it can use | etc for variations.
937a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    """
938e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mbligh    return utils.system("pgrep -f '^([^ /]*/)*(%s)([ ]|$)'" % name_pattern,
939a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh                        ignore_status=True) == 0
94088f602c1cfa54a0085737817a1a477c833e10837mbligh
94188f602c1cfa54a0085737817a1a477c833e10837mbligh
942a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef get_hwclock_seconds(utc=True):
943a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
944a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Return the hardware clock in seconds as a floating point value.
945a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Use Coordinated Universal Time if utc is True, local time otherwise.
946a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Raise a ValueError if unable to read the hardware clock.
947a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
948a82dc35ef721720e73db887d895bbd5cb835291cEric Li    cmd = '/sbin/hwclock --debug'
949a82dc35ef721720e73db887d895bbd5cb835291cEric Li    if utc:
950a82dc35ef721720e73db887d895bbd5cb835291cEric Li        cmd += ' --utc'
951a82dc35ef721720e73db887d895bbd5cb835291cEric Li    hwclock_output = utils.system_output(cmd, ignore_status=True)
952a82dc35ef721720e73db887d895bbd5cb835291cEric Li    match = re.search(r'= ([0-9]+) seconds since .+ (-?[0-9.]+) seconds$',
953a82dc35ef721720e73db887d895bbd5cb835291cEric Li                      hwclock_output, re.DOTALL)
954a82dc35ef721720e73db887d895bbd5cb835291cEric Li    if match:
955a82dc35ef721720e73db887d895bbd5cb835291cEric Li        seconds = int(match.group(1)) + float(match.group(2))
956f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz        logging.debug('hwclock seconds = %f', seconds)
957a82dc35ef721720e73db887d895bbd5cb835291cEric Li        return seconds
958a82dc35ef721720e73db887d895bbd5cb835291cEric Li
959a82dc35ef721720e73db887d895bbd5cb835291cEric Li    raise ValueError('Unable to read the hardware clock -- ' +
960a82dc35ef721720e73db887d895bbd5cb835291cEric Li                     hwclock_output)
961a82dc35ef721720e73db887d895bbd5cb835291cEric Li
962a82dc35ef721720e73db887d895bbd5cb835291cEric Li
963a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef set_wake_alarm(alarm_time):
964a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
965a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Set the hardware RTC-based wake alarm to 'alarm_time'.
966a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
967a82dc35ef721720e73db887d895bbd5cb835291cEric Li    utils.write_one_line('/sys/class/rtc/rtc0/wakealarm', str(alarm_time))
968a82dc35ef721720e73db887d895bbd5cb835291cEric Li
969a82dc35ef721720e73db887d895bbd5cb835291cEric Li
970a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef set_power_state(state):
971a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
972a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Set the system power state to 'state'.
973a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
974a82dc35ef721720e73db887d895bbd5cb835291cEric Li    utils.write_one_line('/sys/power/state', state)
975a82dc35ef721720e73db887d895bbd5cb835291cEric Li
976a82dc35ef721720e73db887d895bbd5cb835291cEric Li
977a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef standby():
978a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
979a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Power-on suspend (S1)
980a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
981a82dc35ef721720e73db887d895bbd5cb835291cEric Li    set_power_state('standby')
982a82dc35ef721720e73db887d895bbd5cb835291cEric Li
983a82dc35ef721720e73db887d895bbd5cb835291cEric Li
984a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef suspend_to_ram():
985a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
986a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Suspend the system to RAM (S3)
987a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
988a82dc35ef721720e73db887d895bbd5cb835291cEric Li    set_power_state('mem')
989a82dc35ef721720e73db887d895bbd5cb835291cEric Li
990a82dc35ef721720e73db887d895bbd5cb835291cEric Li
991a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef suspend_to_disk():
992a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
993a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Suspend the system to disk (S4)
994a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
995a82dc35ef721720e73db887d895bbd5cb835291cEric Li    set_power_state('disk')
996