base_utils.py revision a82dc35ef721720e73db887d895bbd5cb835291c
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"""
109fb37cba7a49579cf484350b9b1e1a1135d6af0emblighimport os, shutil, sys, signal, commands, pickle, glob, statvfs
11b923fc2a01db6e4548ffd541d86f9be49bc5805almrimport math, re, string, fnmatch, logging
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:
124d60882f21c28087da2b33aad1670fe717388ba4almr        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:
131d60882f21c28087da2b33aad1670fe717388ba4almr            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 "
173d60882f21c28087da2b33aad1670fe717388ba4almr                              "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 "
185d60882f21c28087da2b33aad1670fe717388ba4almr                                   "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
313f4c35322b200d65f41a8332b4f3503beb497840dmbligh
314548f29af9e38f87c3609838f5aabeac94bb69f13mblighdef get_current_kernel_arch():
3150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Get the machine architecture, now just a wrap of 'uname -m'."""
3160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return os.popen('uname -m').read().rstrip()
317cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
318cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
319fdbcaec15092d8b4af80970c495038bdf9b0e63fmblighdef get_file_arch(filename):
3200afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # -L means follow symlinks
3212da4d885be334f7db795c3f017daa06ff8ea703dmbligh    file_data = utils.system_output('file -L ' + filename)
3220afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if file_data.count('80386'):
3230afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'i386'
3240afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return None
325fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
326fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
327f4c35322b200d65f41a8332b4f3503beb497840dmblighdef count_cpus():
3280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """number of CPUs in the local machine according to /proc/cpuinfo"""
3290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    f = file('/proc/cpuinfo', 'r')
3300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    cpus = 0
3310afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for line in f.readlines():
332f23fd920c08ca1734e2dd2827a494619f53694c2mbligh        if line.lower().startswith('processor'):
3330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            cpus += 1
3340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return cpus
335f4c35322b200d65f41a8332b4f3503beb497840dmbligh
336e7a170fb097da48af81ca598e29643f3e7cca584mbligh
337e7a170fb097da48af81ca598e29643f3e7cca584mbligh# Returns total memory in kb
338558885e290e3fa847b6a77b6dd66cac33ec6f65cmblighdef read_from_meminfo(key):
3392da4d885be334f7db795c3f017daa06ff8ea703dmbligh    meminfo = utils.system_output('grep %s /proc/meminfo' % key)
3400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return int(re.search(r'\d+', meminfo).group(0))
341558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
342558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
343e7a170fb097da48af81ca598e29643f3e7cca584mblighdef memtotal():
3440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return read_from_meminfo('MemTotal')
345558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
346558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
347558885e290e3fa847b6a77b6dd66cac33ec6f65cmblighdef freememtotal():
3480afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return read_from_meminfo('MemFree')
349558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
350558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
3518493be44f65668c6ebad5d1bee3b97b76abdebbdmblighdef rounded_memtotal():
35253da18eddf69243ca175d9a4603cba5b55300726mbligh    # Get total of all physical mem, in kbytes
35353da18eddf69243ca175d9a4603cba5b55300726mbligh    usable_kbytes = memtotal()
35453da18eddf69243ca175d9a4603cba5b55300726mbligh    # usable_kbytes is system's usable DRAM in kbytes,
3558493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   as reported by memtotal() from device /proc/meminfo memtotal
3568493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   after Linux deducts 1.5% to 5.1% for system table overhead
3578493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # Undo the unknown actual deduction by rounding up
3588493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   to next small multiple of a big power-of-two
3598493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   eg  12GB - 5.1% gets rounded back up to 12GB
3608493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    mindeduct = 0.015  # 1.5 percent
3618493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    maxdeduct = 0.055  # 5.5 percent
3628493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # deduction range 1.5% .. 5.5% supports physical mem sizes
3638493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #    6GB .. 12GB in steps of .5GB
3648493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   12GB .. 24GB in steps of 1 GB
3658493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   24GB .. 48GB in steps of 2 GB ...
3668493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # Finer granularity in physical mem sizes would require
3678493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   tighter spread between min and max possible deductions
3688493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh
3698493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # increase mem size by at least min deduction, without rounding
37053da18eddf69243ca175d9a4603cba5b55300726mbligh    min_kbytes   = int(usable_kbytes / (1.0 - mindeduct))
3718493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # increase mem size further by 2**n rounding, by 0..roundKb or more
37253da18eddf69243ca175d9a4603cba5b55300726mbligh    round_kbytes = int(usable_kbytes / (1.0 - maxdeduct)) - min_kbytes
3738493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # find least binary roundup 2**n that covers worst-cast roundKb
37453da18eddf69243ca175d9a4603cba5b55300726mbligh    mod2n = 1 << int(math.ceil(math.log(round_kbytes, 2)))
37553da18eddf69243ca175d9a4603cba5b55300726mbligh    # have round_kbytes <= mod2n < round_kbytes*2
37653da18eddf69243ca175d9a4603cba5b55300726mbligh    # round min_kbytes up to next multiple of mod2n
37753da18eddf69243ca175d9a4603cba5b55300726mbligh    phys_kbytes = min_kbytes + mod2n - 1
37853da18eddf69243ca175d9a4603cba5b55300726mbligh    phys_kbytes = phys_kbytes - (phys_kbytes % mod2n)  # clear low bits
37953da18eddf69243ca175d9a4603cba5b55300726mbligh    return phys_kbytes
3808493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh
3818493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh
382f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanskidef sysctl(key, value=None):
383f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    """Generic implementation of sysctl, to read and write.
384f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
385f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    @param key: A location under /proc/sys
386f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    @param value: If not None, a value to write into the sysctl.
387f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
388f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    @return The single-line sysctl value as a string.
389f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    """
390f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    path = '/proc/sys/%s' % key
391f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    if value is not None:
392f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski        utils.write_one_line(path, str(value))
393f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    return utils.read_one_line(path)
394f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
395f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
396558885e290e3fa847b6a77b6dd66cac33ec6f65cmblighdef sysctl_kernel(key, value=None):
3970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """(Very) partial implementation of sysctl, for kernel params"""
398f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    if value is not None:
3990afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # write
4002da4d885be334f7db795c3f017daa06ff8ea703dmbligh        utils.write_one_line('/proc/sys/kernel/%s' % key, str(value))
4010afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
4020afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # read
4032da4d885be334f7db795c3f017daa06ff8ea703dmbligh        out = utils.read_one_line('/proc/sys/kernel/%s' % key)
4040afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return int(re.search(r'\d+', out).group(0))
405e7a170fb097da48af81ca598e29643f3e7cca584mbligh
406e7a170fb097da48af81ca598e29643f3e7cca584mbligh
4075285a2dc3c5edbc010825e6d64ecdb219b3ad52cmblighdef _convert_exit_status(sts):
4080afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.WIFSIGNALED(sts):
4090afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return -os.WTERMSIG(sts)
4100afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif os.WIFEXITED(sts):
4110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return os.WEXITSTATUS(sts)
4120afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
4130afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # impossible?
4140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise RuntimeError("Unknown exit status %d!" % sts)
4155285a2dc3c5edbc010825e6d64ecdb219b3ad52cmbligh
4165285a2dc3c5edbc010825e6d64ecdb219b3ad52cmbligh
417f4c35322b200d65f41a8332b4f3503beb497840dmblighdef where_art_thy_filehandles():
4180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Dump the current list of filehandles"""
4190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    os.system("ls -l /proc/%d/fd >> /dev/tty" % os.getpid())
420f4c35322b200d65f41a8332b4f3503beb497840dmbligh
421f4c35322b200d65f41a8332b4f3503beb497840dmbligh
422f4c35322b200d65f41a8332b4f3503beb497840dmblighdef print_to_tty(string):
4230afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Output string straight to the tty"""
4240afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    open('/dev/tty', 'w').write(string + '\n')
425f4c35322b200d65f41a8332b4f3503beb497840dmbligh
426f4c35322b200d65f41a8332b4f3503beb497840dmbligh
427b8a14e358b611f2d97c06e863be9b53ab2bedeefmblighdef dump_object(object):
4280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Dump an object's attributes and methods
429c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
4300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    kind of like dir()
4310afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
4320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for item in object.__dict__.iteritems():
4330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        print item
4340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        try:
4350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            (key,value) = item
4360afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            dump_object(value)
4370afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        except:
4380afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            continue
439b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh
440b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh
4414b089663460063b638124ff665f38d2fe7427648mblighdef environ(env_key):
4420afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """return the requested environment variable, or '' if unset"""
4430afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if (os.environ.has_key(env_key)):
4440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return os.environ[env_key]
4450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
4460afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return ''
4474b089663460063b638124ff665f38d2fe7427648mbligh
4484b089663460063b638124ff665f38d2fe7427648mbligh
4494b089663460063b638124ff665f38d2fe7427648mblighdef prepend_path(newpath, oldpath):
4500afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """prepend newpath to oldpath"""
4510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if (oldpath):
4520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return newpath + ':' + oldpath
4530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
4540afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return newpath
4554b089663460063b638124ff665f38d2fe7427648mbligh
4564b089663460063b638124ff665f38d2fe7427648mbligh
4574b089663460063b638124ff665f38d2fe7427648mblighdef append_path(oldpath, newpath):
4580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """append newpath to oldpath"""
4590afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if (oldpath):
4600afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return oldpath + ':' + newpath
4610afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
4620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return newpath
4634b089663460063b638124ff665f38d2fe7427648mbligh
4644b089663460063b638124ff665f38d2fe7427648mbligh
4654e75b0d3b020f901456217fb8ff0d7d4391fa869mblighdef avgtime_print(dir):
4660afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """ Calculate some benchmarking statistics.
4670afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        Input is a directory containing a file called 'time'.
4680afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        File contains one-per-line results of /usr/bin/time.
4690afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        Output is average Elapsed, User, and System time in seconds,
4700afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski          and average CPU percentage.
4710afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
4720afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    f = open(dir + "/time")
4730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    user = system = elapsed = cpu = count = 0
4740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    r = re.compile('([\d\.]*)user ([\d\.]*)system (\d*):([\d\.]*)elapsed (\d*)%CPU')
4750afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for line in f.readlines():
4760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        try:
4770afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            s = r.match(line);
4780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            user += float(s.group(1))
4790afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            system += float(s.group(2))
4800afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            elapsed += (float(s.group(3)) * 60) + float(s.group(4))
4810afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            cpu += float(s.group(5))
4820afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            count += 1
4830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        except:
4840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            raise ValueError("badly formatted times")
4850afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
4860afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    f.close()
4870afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return "Elapsed: %0.2fs User: %0.2fs System: %0.2fs CPU: %0.0f%%" % \
4880afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski          (elapsed/count, user/count, system/count, cpu/count)
4894e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh
4904e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh
491f06db0f9b381737b9c85bef1c23ea1a1ca73c559mblighdef running_config():
4920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
4930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Return path of config file of the currently running kernel
4940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
4952da4d885be334f7db795c3f017daa06ff8ea703dmbligh    version = utils.system_output('uname -r')
4960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for config in ('/proc/config.gz', \
4970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   '/boot/config-%s' % version,
4980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   '/lib/modules/%s/build/.config' % version):
4990afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if os.path.isfile(config):
5000afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return config
5010afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return None
5029ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh
5039ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh
504a1bef1f2774b539df11c134d9a9a177304c34f3cmblighdef check_for_kernel_feature(feature):
5050afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    config = running_config()
506a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
5070afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if not config:
5080afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise TypeError("Can't find kernel config file")
509a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
510959e8162836703848f8e1801f74e7117b850e889lmr    if magic.guess_type(config) == 'application/x-gzip':
5110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        grep = 'zgrep'
5120afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
5130afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        grep = 'grep'
5140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    grep += ' ^CONFIG_%s= %s' % (feature, config)
515a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
5162da4d885be334f7db795c3f017daa06ff8ea703dmbligh    if not utils.system_output(grep, ignore_status=True):
5170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise ValueError("Kernel doesn't have a %s feature" % (feature))
518a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
519a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
5209ec8acc50c0fe06a40353db0df8e135cebb2ec58mblighdef cpu_online_map():
5210afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
5220afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Check out the available cpu online map
5230afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
5240afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    cpus = []
5250afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for line in open('/proc/cpuinfo', 'r').readlines():
5260afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if line.startswith('processor'):
5270afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            cpus.append(line.split()[2]) # grab cpu number
5280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return cpus
529663e4f664465dbaa9e86c5c20d035ad9bd1e65edmbligh
530663e4f664465dbaa9e86c5c20d035ad9bd1e65edmbligh
531663e4f664465dbaa9e86c5c20d035ad9bd1e65edmblighdef check_glibc_ver(ver):
5320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    glibc_ver = commands.getoutput('ldd --version').splitlines()[0]
5330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    glibc_ver = re.search(r'(\d+\.\d+(\.\d+)?)', glibc_ver).group()
5340fab1e986e36dd9addaa075c6c73e71fbd756652lmr    if utils.compare_versions(glibc_ver, ver) == -1:
5350fab1e986e36dd9addaa075c6c73e71fbd756652lmr        raise error.TestError("Glibc too old (%s). Glibc >= %s is needed." %
5360fab1e986e36dd9addaa075c6c73e71fbd756652lmr                              (glibc_ver, ver))
5370763522bf0dcd6297385a7db965086ed8ba18adambligh
5380763522bf0dcd6297385a7db965086ed8ba18adamblighdef check_kernel_ver(ver):
5392da4d885be334f7db795c3f017daa06ff8ea703dmbligh    kernel_ver = utils.system_output('uname -r')
5400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    kv_tmp = re.split(r'[-]', kernel_ver)[0:3]
54142b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr    # In compare_versions, if v1 < v2, return value == -1
54242b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr    if utils.compare_versions(kv_tmp[0], ver) == -1:
54342b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr        raise error.TestError("Kernel too old (%s). Kernel > %s is needed." %
54442b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr                              (kernel_ver, ver))
54560418bb82d1734a7f73a5e4c8870d06799795397mbligh
5469061a273dfd2e522c15f6dd77cfed1e2815e4e9embligh
547264cd8f4889cea73fa5fb7873e3243c1c770a1bcmblighdef human_format(number):
5480afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # Convert number to kilo / mega / giga format.
5490afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if number < 1024:
5500afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return "%d" % number
5510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    kilo = float(number) / 1024.0
5520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if kilo < 1024:
5530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return "%.2fk" % kilo
5540afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    meg = kilo / 1024.0
5550afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if meg < 1024:
5560afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return "%.2fM" % meg
5570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    gig = meg / 1024.0
5580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return "%.2fG" % gig
559264cd8f4889cea73fa5fb7873e3243c1c770a1bcmbligh
5608eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
5618eca3a98728afabc7fc761c08dbb8e91260c7de4mblighdef numa_nodes():
5620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    node_paths = glob.glob('/sys/devices/system/node/node*')
5630afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    nodes = [int(re.sub(r'.*node(\d+)', r'\1', x)) for x in node_paths]
5640afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return (sorted(nodes))
5658eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
5668eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
5678eca3a98728afabc7fc761c08dbb8e91260c7de4mblighdef node_size():
5680afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    nodes = max(len(numa_nodes()), 1)
5690afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return ((memtotal() * 1024) / nodes)
5708eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
57132bcff3382844181eaf3d74e0fb252d88edfc8fbmbligh
57232bcff3382844181eaf3d74e0fb252d88edfc8fbmblighdef to_seconds(time_string):
5730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Converts a string in M+:SS.SS format to S+.SS"""
5740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elts = time_string.split(':')
5750afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if len(elts) == 1:
5760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return time_string
5770afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return str(int(elts[0]) * 60 + float(elts[1]))
57832bcff3382844181eaf3d74e0fb252d88edfc8fbmbligh
57932bcff3382844181eaf3d74e0fb252d88edfc8fbmbligh
58032bcff3382844181eaf3d74e0fb252d88edfc8fbmblighdef extract_all_time_results(results_string):
5810afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Extract user, system, and elapsed times into a list of tuples"""
5820afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    pattern = re.compile(r"(.*?)user (.*?)system (.*?)elapsed")
5830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    results = []
5840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for result in pattern.findall(results_string):
5850afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        results.append(tuple([to_seconds(elt) for elt in result]))
5860afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return results
587c421164e16db7233ef8fcc4ecfd83f2979aec16ambligh
588c421164e16db7233ef8fcc4ecfd83f2979aec16ambligh
589c421164e16db7233ef8fcc4ecfd83f2979aec16amblighdef pickle_load(filename):
5900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return pickle.load(open(filename, 'r'))
591c421164e16db7233ef8fcc4ecfd83f2979aec16ambligh
592237bed32e0110ccd0db10823df742534dd7dc50dmbligh
593237bed32e0110ccd0db10823df742534dd7dc50dmbligh# Return the kernel version and build timestamp.
594237bed32e0110ccd0db10823df742534dd7dc50dmblighdef running_os_release():
5950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return os.uname()[2:4]
596237bed32e0110ccd0db10823df742534dd7dc50dmbligh
597237bed32e0110ccd0db10823df742534dd7dc50dmbligh
598237bed32e0110ccd0db10823df742534dd7dc50dmblighdef running_os_ident():
5990afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    (version, timestamp) = running_os_release()
6000afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return version + '::' + timestamp
601b830e28297dca51aed2c4b57469a3e04845e54e7mbligh
602b830e28297dca51aed2c4b57469a3e04845e54e7mbligh
6033bf79ca4d5490f9af09e1ddc39b8df5343b34d06mblighdef running_os_full_version():
6043bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh    (version, timestamp) = running_os_release()
6053bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh    return version
6063bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh
6073bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh
608523a19b532a778dd9e752e507ac75d3ffc5c701ambligh# much like find . -name 'pattern'
609523a19b532a778dd9e752e507ac75d3ffc5c701amblighdef locate(pattern, root=os.getcwd()):
6100afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for path, dirs, files in os.walk(root):
611987071e1fba830910658ce987bb803d142480c03mbligh        for f in files:
612987071e1fba830910658ce987bb803d142480c03mbligh            if fnmatch.fnmatch(f, pattern):
6137076b192936caad193898cff194e82f83dd13d63mbligh                yield os.path.abspath(os.path.join(path, f))
614523a19b532a778dd9e752e507ac75d3ffc5c701ambligh
615523a19b532a778dd9e752e507ac75d3ffc5c701ambligh
61625bb1e1fbb67950ac480f6500138c19647472889mblighdef freespace(path):
6170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the disk free space, in bytes"""
6180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    s = os.statvfs(path)
6190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return s.f_bavail * s.f_bsize
6208415f966acaaa3aa3ca6a651d9a190081edbb0eejadmanski
6218415f966acaaa3aa3ca6a651d9a190081edbb0eejadmanski
6228415f966acaaa3aa3ca6a651d9a190081edbb0eejadmanskidef disk_block_size(path):
6230afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the disk block size, in bytes"""
6240afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return os.statvfs(path).f_bsize
6256de9cdfe8ce95c1d87b01aa768526a64755090cambligh
6266de9cdfe8ce95c1d87b01aa768526a64755090cambligh
6276de9cdfe8ce95c1d87b01aa768526a64755090camblighdef get_cpu_family():
6282da4d885be334f7db795c3f017daa06ff8ea703dmbligh    procinfo = utils.system_output('cat /proc/cpuinfo')
6290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    CPU_FAMILY_RE = re.compile(r'^cpu family\s+:\s+(\S+)', re.M)
6300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    matches = CPU_FAMILY_RE.findall(procinfo)
6310afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if matches:
6320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return int(matches[0])
6330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
6340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise error.TestError('Could not get valid cpu family data')
6356de9cdfe8ce95c1d87b01aa768526a64755090cambligh
6363e9062e854a920eead8e250c4e79838c30a0657cmbligh
6372316e52c84ac8799330c52359bc4dd5e7f7324d5mblighdef get_disks():
6382da4d885be334f7db795c3f017daa06ff8ea703dmbligh    df_output = utils.system_output('df')
6390afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    disk_re = re.compile(r'^(/dev/hd[a-z]+)3', re.M)
6400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return disk_re.findall(df_output)
6416de9cdfe8ce95c1d87b01aa768526a64755090cambligh
6423e9062e854a920eead8e250c4e79838c30a0657cmbligh
6433e9062e854a920eead8e250c4e79838c30a0657cmblighdef load_module(module_name):
6440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # Checks if a module has already been loaded
6450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if module_is_loaded(module_name):
6460afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return False
647af4efc23471265a3bfa7fef0146fbc0cbb54515bmbligh
6482da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system('/sbin/modprobe ' + module_name)
6490afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return True
6503e9062e854a920eead8e250c4e79838c30a0657cmbligh
6513e9062e854a920eead8e250c4e79838c30a0657cmbligh
6523e9062e854a920eead8e250c4e79838c30a0657cmblighdef unload_module(module_name):
653b923fc2a01db6e4548ffd541d86f9be49bc5805almr    """
654b923fc2a01db6e4548ffd541d86f9be49bc5805almr    Removes a module. Handles dependencies. If even then it's not possible
655b923fc2a01db6e4548ffd541d86f9be49bc5805almr    to remove one of the modules, it will trhow an error.CmdError exception.
656b923fc2a01db6e4548ffd541d86f9be49bc5805almr
657b923fc2a01db6e4548ffd541d86f9be49bc5805almr    @param module_name: Name of the module we want to remove.
658b923fc2a01db6e4548ffd541d86f9be49bc5805almr    """
659b923fc2a01db6e4548ffd541d86f9be49bc5805almr    l_raw = utils.system_output("/sbin/lsmod").splitlines()
660b923fc2a01db6e4548ffd541d86f9be49bc5805almr    lsmod = [x for x in l_raw if x.split()[0] == module_name]
661b923fc2a01db6e4548ffd541d86f9be49bc5805almr    if len(lsmod) > 0:
662b923fc2a01db6e4548ffd541d86f9be49bc5805almr        line_parts = lsmod[0].split()
663b923fc2a01db6e4548ffd541d86f9be49bc5805almr        if len(line_parts) == 4:
664b923fc2a01db6e4548ffd541d86f9be49bc5805almr            submodules = line_parts[3].split(",")
665b923fc2a01db6e4548ffd541d86f9be49bc5805almr            for submodule in submodules:
666b923fc2a01db6e4548ffd541d86f9be49bc5805almr                unload_module(submodule)
667b923fc2a01db6e4548ffd541d86f9be49bc5805almr        utils.system("/sbin/modprobe -r %s" % module_name)
668b923fc2a01db6e4548ffd541d86f9be49bc5805almr        logging.info("Module %s unloaded" % module_name)
669b923fc2a01db6e4548ffd541d86f9be49bc5805almr    else:
670b923fc2a01db6e4548ffd541d86f9be49bc5805almr        logging.info("Module %s is already unloaded" % module_name)
6713e9062e854a920eead8e250c4e79838c30a0657cmbligh
6723e9062e854a920eead8e250c4e79838c30a0657cmbligh
6733e9062e854a920eead8e250c4e79838c30a0657cmblighdef module_is_loaded(module_name):
6740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    module_name = module_name.replace('-', '_')
6752da4d885be334f7db795c3f017daa06ff8ea703dmbligh    modules = utils.system_output('/sbin/lsmod').splitlines()
6760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for module in modules:
6770afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if module.startswith(module_name) and module[len(module_name)] == ' ':
6780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return True
6790afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return False
6803e9062e854a920eead8e250c4e79838c30a0657cmbligh
6813e9062e854a920eead8e250c4e79838c30a0657cmbligh
6826b34c4cc34bebd20def94c0191ef1e46dd6a1cdemblighdef get_loaded_modules():
6832da4d885be334f7db795c3f017daa06ff8ea703dmbligh    lsmod_output = utils.system_output('/sbin/lsmod').splitlines()[1:]
6840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return [line.split(None, 1)[0] for line in lsmod_output]
6856b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
6866b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
6873e9062e854a920eead8e250c4e79838c30a0657cmblighdef get_huge_page_size():
6882da4d885be334f7db795c3f017daa06ff8ea703dmbligh    output = utils.system_output('grep Hugepagesize /proc/meminfo')
6890afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return int(output.split()[1]) # Assumes units always in kB. :(
6903e9062e854a920eead8e250c4e79838c30a0657cmbligh
6913e9062e854a920eead8e250c4e79838c30a0657cmbligh
6923e9062e854a920eead8e250c4e79838c30a0657cmblighdef get_num_huge_pages():
6932da4d885be334f7db795c3f017daa06ff8ea703dmbligh    raw_hugepages = utils.system_output('/sbin/sysctl vm.nr_hugepages')
6940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return int(raw_hugepages.split()[2])
6953e9062e854a920eead8e250c4e79838c30a0657cmbligh
6963e9062e854a920eead8e250c4e79838c30a0657cmbligh
6973e9062e854a920eead8e250c4e79838c30a0657cmblighdef set_num_huge_pages(num):
6982da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system('/sbin/sysctl vm.nr_hugepages=%d' % num)
6993e9062e854a920eead8e250c4e79838c30a0657cmbligh
7003e9062e854a920eead8e250c4e79838c30a0657cmbligh
7016b34c4cc34bebd20def94c0191ef1e46dd6a1cdemblighdef get_cpu_vendor():
7020afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    cpuinfo = open('/proc/cpuinfo').read()
7030afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    vendors = re.findall(r'(?m)^vendor_id\s*:\s*(\S+)\s*$', cpuinfo)
7040afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for i in xrange(1, len(vendors)):
7050afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if vendors[i] != vendors[0]:
7060afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            raise error.TestError('multiple cpu vendors found: ' + str(vendors))
7070afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return vendors[0]
7086b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
7096b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
7106b34c4cc34bebd20def94c0191ef1e46dd6a1cdemblighdef probe_cpus():
7110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
71253da18eddf69243ca175d9a4603cba5b55300726mbligh    This routine returns a list of cpu devices found under
71353da18eddf69243ca175d9a4603cba5b55300726mbligh    /sys/devices/system/cpu.
7140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
71553da18eddf69243ca175d9a4603cba5b55300726mbligh    cmd = 'find /sys/devices/system/cpu/ -maxdepth 1 -type d -name cpu*'
7162da4d885be334f7db795c3f017daa06ff8ea703dmbligh    return utils.system_output(cmd).splitlines()
7176b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
7186b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
71970c50ad0eec36f4678374040031da84150a75997mblighdef ping_default_gateway():
7200afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Ping the default gateway."""
72170c50ad0eec36f4678374040031da84150a75997mbligh
7220afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    network = open('/etc/sysconfig/network')
7230afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    m = re.search('GATEWAY=(\S+)', network.read())
7240afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
7250afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if m:
7260afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        gw = m.group(1)
7270afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        cmd = 'ping %s -c 5 > /dev/null' % gw
7282da4d885be334f7db795c3f017daa06ff8ea703dmbligh        return utils.system(cmd, ignore_status=True)
7290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
7300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    raise error.TestError('Unable to find default gateway')
73170c50ad0eec36f4678374040031da84150a75997mbligh
73270c50ad0eec36f4678374040031da84150a75997mbligh
733115feb2fee75e8cb75873905f07763fbfafc8f6ejadmanskidef drop_caches():
734115feb2fee75e8cb75873905f07763fbfafc8f6ejadmanski    """Writes back all dirty pages to disk and clears all the caches."""
7352da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system("sync")
736115feb2fee75e8cb75873905f07763fbfafc8f6ejadmanski    # We ignore failures here as this will fail on 2.6.11 kernels.
7372da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system("echo 3 > /proc/sys/vm/drop_caches", ignore_status=True)
738a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh
739a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh
740e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mblighdef process_is_alive(name_pattern):
741a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    """
742a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    'pgrep name' misses all python processes and also long process names.
743a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    'pgrep -f name' gets all shell commands with name in args.
744e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mbligh    So look only for command whose initial pathname ends with name.
745e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mbligh    Name itself is an egrep pattern, so it can use | etc for variations.
746a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    """
747e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mbligh    return utils.system("pgrep -f '^([^ /]*/)*(%s)([ ]|$)'" % name_pattern,
748a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh                        ignore_status=True) == 0
74988f602c1cfa54a0085737817a1a477c833e10837mbligh
75088f602c1cfa54a0085737817a1a477c833e10837mbligh
751a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef get_hwclock_seconds(utc=True):
752a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
753a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Return the hardware clock in seconds as a floating point value.
754a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Use Coordinated Universal Time if utc is True, local time otherwise.
755a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Raise a ValueError if unable to read the hardware clock.
756a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
757a82dc35ef721720e73db887d895bbd5cb835291cEric Li    cmd = '/sbin/hwclock --debug'
758a82dc35ef721720e73db887d895bbd5cb835291cEric Li    if utc:
759a82dc35ef721720e73db887d895bbd5cb835291cEric Li        cmd += ' --utc'
760a82dc35ef721720e73db887d895bbd5cb835291cEric Li    hwclock_output = utils.system_output(cmd, ignore_status=True)
761a82dc35ef721720e73db887d895bbd5cb835291cEric Li    match = re.search(r'= ([0-9]+) seconds since .+ (-?[0-9.]+) seconds$',
762a82dc35ef721720e73db887d895bbd5cb835291cEric Li                      hwclock_output, re.DOTALL)
763a82dc35ef721720e73db887d895bbd5cb835291cEric Li    if match:
764a82dc35ef721720e73db887d895bbd5cb835291cEric Li        seconds = int(match.group(1)) + float(match.group(2))
765a82dc35ef721720e73db887d895bbd5cb835291cEric Li        logging.debug('hwclock seconds = %f' % seconds)
766a82dc35ef721720e73db887d895bbd5cb835291cEric Li        return seconds
767a82dc35ef721720e73db887d895bbd5cb835291cEric Li
768a82dc35ef721720e73db887d895bbd5cb835291cEric Li    raise ValueError('Unable to read the hardware clock -- ' +
769a82dc35ef721720e73db887d895bbd5cb835291cEric Li                     hwclock_output)
770a82dc35ef721720e73db887d895bbd5cb835291cEric Li
771a82dc35ef721720e73db887d895bbd5cb835291cEric Li
772a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef set_wake_alarm(alarm_time):
773a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
774a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Set the hardware RTC-based wake alarm to 'alarm_time'.
775a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
776a82dc35ef721720e73db887d895bbd5cb835291cEric Li    utils.write_one_line('/sys/class/rtc/rtc0/wakealarm', str(alarm_time))
777a82dc35ef721720e73db887d895bbd5cb835291cEric Li
778a82dc35ef721720e73db887d895bbd5cb835291cEric Li
779a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef set_power_state(state):
780a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
781a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Set the system power state to 'state'.
782a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
783a82dc35ef721720e73db887d895bbd5cb835291cEric Li    utils.write_one_line('/sys/power/state', state)
784a82dc35ef721720e73db887d895bbd5cb835291cEric Li
785a82dc35ef721720e73db887d895bbd5cb835291cEric Li
786a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef standby():
787a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
788a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Power-on suspend (S1)
789a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
790a82dc35ef721720e73db887d895bbd5cb835291cEric Li    set_power_state('standby')
791a82dc35ef721720e73db887d895bbd5cb835291cEric Li
792a82dc35ef721720e73db887d895bbd5cb835291cEric Li
793a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef suspend_to_ram():
794a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
795a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Suspend the system to RAM (S3)
796a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
797a82dc35ef721720e73db887d895bbd5cb835291cEric Li    set_power_state('mem')
798a82dc35ef721720e73db887d895bbd5cb835291cEric Li
799a82dc35ef721720e73db887d895bbd5cb835291cEric Li
800a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef suspend_to_disk():
801a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
802a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Suspend the system to disk (S4)
803a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
804a82dc35ef721720e73db887d895bbd5cb835291cEric Li    set_power_state('disk')
805