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"""
10b46d3c05d6507bc65a6498c531cc217561bbc116Allen Li
11b46d3c05d6507bc65a6498c531cc217561bbc116Allen Liimport commands
12b46d3c05d6507bc65a6498c531cc217561bbc116Allen Liimport fnmatch
13b46d3c05d6507bc65a6498c531cc217561bbc116Allen Liimport glob
14b46d3c05d6507bc65a6498c531cc217561bbc116Allen Liimport logging
15b46d3c05d6507bc65a6498c531cc217561bbc116Allen Liimport math
16b46d3c05d6507bc65a6498c531cc217561bbc116Allen Liimport multiprocessing
17b46d3c05d6507bc65a6498c531cc217561bbc116Allen Liimport os
18b46d3c05d6507bc65a6498c531cc217561bbc116Allen Liimport pickle
19b46d3c05d6507bc65a6498c531cc217561bbc116Allen Liimport re
20b46d3c05d6507bc65a6498c531cc217561bbc116Allen Liimport shutil
21b46d3c05d6507bc65a6498c531cc217561bbc116Allen Li
22b46d3c05d6507bc65a6498c531cc217561bbc116Allen Lifrom autotest_lib.client.common_lib import error
23b46d3c05d6507bc65a6498c531cc217561bbc116Allen Lifrom autotest_lib.client.common_lib import magic
24b46d3c05d6507bc65a6498c531cc217561bbc116Allen Lifrom autotest_lib.client.common_lib import utils
25ea397bbc85f1a3eda39c9f2ef4fc209b4ff336f4mbligh
26ea397bbc85f1a3eda39c9f2ef4fc209b4ff336f4mbligh
27f4c35322b200d65f41a8332b4f3503beb497840dmblighdef grep(pattern, file):
280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    This is mainly to fix the return code inversion from grep
300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Also handles compressed files.
317bdbfbdf088f9c2a72c199d5a530194bb2ac257fmbligh
320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    returns 1 if the pattern is present in the file, 0 if not.
330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    command = 'grep "%s" > /dev/null' % pattern
350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    ret = cat_file_to_cmd(file, command, ignore_status=True)
360afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return not ret
37af4efc23471265a3bfa7fef0146fbc0cbb54515bmbligh
38af4efc23471265a3bfa7fef0146fbc0cbb54515bmbligh
39c86b0b45cd0198d99d271a79f8b6de29feb98cd5mblighdef difflist(list1, list2):
400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """returns items in list2 that are not in list1"""
410afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    diff = [];
420afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for x in list2:
430afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if x not in list1:
440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            diff.append(x)
450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return diff
46f4c35322b200d65f41a8332b4f3503beb497840dmbligh
47c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
488ea61e2f9f55bd9f646735069e1f029e86d08320mblighdef cat_file_to_cmd(file, command, ignore_status=0, return_output=False):
490afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
500afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    equivalent to 'cat file | command' but knows to use
510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    zcat or bzcat if appropriate
520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
53f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh    if not os.path.isfile(file):
54f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh        raise NameError('invalid file %s to cat to command %s'
55f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh                % (file, command))
56f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh
570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if return_output:
582da4d885be334f7db795c3f017daa06ff8ea703dmbligh        run_cmd = utils.system_output
590afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
602da4d885be334f7db795c3f017daa06ff8ea703dmbligh        run_cmd = utils.system
610afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
62959e8162836703848f8e1801f74e7117b850e889lmr    if magic.guess_type(file) == 'application/x-bzip2':
63f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh        cat = 'bzcat'
64959e8162836703848f8e1801f74e7117b850e889lmr    elif magic.guess_type(file) == 'application/x-gzip':
65f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh        cat = 'zcat'
660afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
67f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh        cat = 'cat'
68f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh    return run_cmd('%s %s | %s' % (cat, file, command),
69f2fa471f5306887847024a50ebfca57dd0c6bd71mbligh                                                    ignore_status=ignore_status)
70712cd145672c0033a55173717787c54cd68e6b83mbligh
71c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
72712cd145672c0033a55173717787c54cd68e6b83mblighdef extract_tarball_to_dir(tarball, dir):
730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Extract a tarball to a specified directory name instead of whatever
750afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    the top level of a tarball is - useful for versioned directory names, etc
760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
770afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.exists(dir):
78959e8162836703848f8e1801f74e7117b850e889lmr        if os.path.isdir(dir):
79959e8162836703848f8e1801f74e7117b850e889lmr            shutil.rmtree(dir)
80959e8162836703848f8e1801f74e7117b850e889lmr        else:
81959e8162836703848f8e1801f74e7117b850e889lmr            os.remove(dir)
820afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    pwd = os.getcwd()
830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    os.chdir(os.path.dirname(os.path.abspath(dir)))
840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    newdir = extract_tarball(tarball)
850afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    os.rename(newdir, dir)
860afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    os.chdir(pwd)
87712cd145672c0033a55173717787c54cd68e6b83mbligh
88f4c35322b200d65f41a8332b4f3503beb497840dmbligh
89712cd145672c0033a55173717787c54cd68e6b83mblighdef extract_tarball(tarball):
900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Returns the directory extracted by the tarball."""
910afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    extracted = cat_file_to_cmd(tarball, 'tar xvf - 2>/dev/null',
920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                                    return_output=True).splitlines()
930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    dir = None
950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for line in extracted:
9777e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp        if line.startswith('./'):
9877e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp            line = line[2:]
990afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if not line or line == '.':
1000afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            continue
1010afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        topdir = line.split('/')[0]
1020afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if os.path.isdir(topdir):
1030afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            if dir:
1040afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                assert(dir == topdir)
1050afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            else:
1060afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                dir = topdir
1070afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if dir:
1080afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return dir
1090afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
1100afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise NameError('extracting tarball produced no dir')
111712cd145672c0033a55173717787c54cd68e6b83mbligh
112cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
113d60882f21c28087da2b33aad1670fe717388ba4almrdef unmap_url_cache(cachedir, url, expected_hash, method="md5"):
11453da18eddf69243ca175d9a4603cba5b55300726mbligh    """
1150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Downloads a file from a URL to a cache directory. If the file is already
116d60882f21c28087da2b33aad1670fe717388ba4almr    at the expected position and has the expected hash, let's not download it
117d60882f21c28087da2b33aad1670fe717388ba4almr    again.
118d60882f21c28087da2b33aad1670fe717388ba4almr
119d60882f21c28087da2b33aad1670fe717388ba4almr    @param cachedir: Directory that might hold a copy of the file we want to
120d60882f21c28087da2b33aad1670fe717388ba4almr            download.
121d60882f21c28087da2b33aad1670fe717388ba4almr    @param url: URL for the file we want to download.
122d60882f21c28087da2b33aad1670fe717388ba4almr    @param expected_hash: Hash string that we expect the file downloaded to
123d60882f21c28087da2b33aad1670fe717388ba4almr            have.
124d60882f21c28087da2b33aad1670fe717388ba4almr    @param method: Method used to calculate the hash string (md5, sha1).
1250afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
1260afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # Let's convert cachedir to a canonical path, if it's not already
1270afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    cachedir = os.path.realpath(cachedir)
1280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if not os.path.isdir(cachedir):
1290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        try:
130d60882f21c28087da2b33aad1670fe717388ba4almr            os.makedirs(cachedir)
1310afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        except:
1320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            raise ValueError('Could not create cache directory %s' % cachedir)
1330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    file_from_url = os.path.basename(url)
1340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    file_local_path = os.path.join(cachedir, file_from_url)
135d60882f21c28087da2b33aad1670fe717388ba4almr
136d60882f21c28087da2b33aad1670fe717388ba4almr    file_hash = None
137d60882f21c28087da2b33aad1670fe717388ba4almr    failure_counter = 0
138d60882f21c28087da2b33aad1670fe717388ba4almr    while not file_hash == expected_hash:
139d60882f21c28087da2b33aad1670fe717388ba4almr        if os.path.isfile(file_local_path):
140d60882f21c28087da2b33aad1670fe717388ba4almr            file_hash = hash_file(file_local_path, method)
141d60882f21c28087da2b33aad1670fe717388ba4almr            if file_hash == expected_hash:
142d60882f21c28087da2b33aad1670fe717388ba4almr                # File is already at the expected position and ready to go
143d60882f21c28087da2b33aad1670fe717388ba4almr                src = file_from_url
144d60882f21c28087da2b33aad1670fe717388ba4almr            else:
145d60882f21c28087da2b33aad1670fe717388ba4almr                # Let's download the package again, it's corrupted...
146d60882f21c28087da2b33aad1670fe717388ba4almr                logging.error("Seems that file %s is corrupted, trying to "
147f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz                              "download it again", file_from_url)
148d60882f21c28087da2b33aad1670fe717388ba4almr                src = url
149d60882f21c28087da2b33aad1670fe717388ba4almr                failure_counter += 1
1500afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        else:
151d60882f21c28087da2b33aad1670fe717388ba4almr            # File is not there, let's download it
1520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            src = url
153d60882f21c28087da2b33aad1670fe717388ba4almr        if failure_counter > 1:
154d60882f21c28087da2b33aad1670fe717388ba4almr            raise EnvironmentError("Consistently failed to download the "
155d60882f21c28087da2b33aad1670fe717388ba4almr                                   "package %s. Aborting further download "
156d60882f21c28087da2b33aad1670fe717388ba4almr                                   "attempts. This might mean either the "
157d60882f21c28087da2b33aad1670fe717388ba4almr                                   "network connection has problems or the "
158d60882f21c28087da2b33aad1670fe717388ba4almr                                   "expected hash string that was determined "
159f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz                                   "for this file is wrong", file_from_url)
160d60882f21c28087da2b33aad1670fe717388ba4almr        file_path = utils.unmap_url(cachedir, src, cachedir)
161d60882f21c28087da2b33aad1670fe717388ba4almr
162d60882f21c28087da2b33aad1670fe717388ba4almr    return file_path
163ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh
164ea30c8a19ee292ee57b5223ca079f7a311195b41mbligh
165f4c35322b200d65f41a8332b4f3503beb497840dmblighdef force_copy(src, dest):
1660afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Replace dest with a new copy of src, even if it exists"""
1670afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isfile(dest):
1680afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        os.remove(dest)
1690afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isdir(dest):
1700afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        dest = os.path.join(dest, os.path.basename(src))
1710afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    shutil.copyfile(src, dest)
1720afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return dest
173f4c35322b200d65f41a8332b4f3503beb497840dmbligh
174f4c35322b200d65f41a8332b4f3503beb497840dmbligh
175fdbcaec15092d8b4af80970c495038bdf9b0e63fmblighdef force_link(src, dest):
1760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Link src to dest, overwriting it if it exists"""
1772da4d885be334f7db795c3f017daa06ff8ea703dmbligh    return utils.system("ln -sf %s %s" % (src, dest))
178fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
179fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
180cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmblighdef file_contains_pattern(file, pattern):
1810afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return true if file contains the specified egrep pattern"""
1820afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if not os.path.isfile(file):
1830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise NameError('file %s does not exist' % file)
1842da4d885be334f7db795c3f017daa06ff8ea703dmbligh    return not utils.system('egrep -q "' + pattern + '" ' + file, ignore_status=True)
185cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
186cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
187cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmblighdef list_grep(list, pattern):
1880afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """True if any item in list matches the specified pattern."""
1890afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    compiled = re.compile(pattern)
1900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for line in list:
1910afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        match = compiled.search(line)
1920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if (match):
1930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return 1
1940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return 0
195cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
196987071e1fba830910658ce987bb803d142480c03mbligh
19742b81ca63a0ab336b844e9c5cce6fe30dae85357mblighdef get_os_vendor():
1980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Try to guess what's the os vendor
1990afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
20090b97ff1834d2c65df82d9b830be7ebb1dbf2167mbligh    if os.path.isfile('/etc/SuSE-release'):
20190b97ff1834d2c65df82d9b830be7ebb1dbf2167mbligh        return 'SUSE'
20290b97ff1834d2c65df82d9b830be7ebb1dbf2167mbligh
2030afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    issue = '/etc/issue'
2040afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
2050afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if not os.path.isfile(issue):
2060afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Unknown'
2070afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
2080afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if file_contains_pattern(issue, 'Red Hat'):
2090afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Red Hat'
2102f29c19882287b5533312b1c4367819bf3a53f91mbligh    elif file_contains_pattern(issue, 'Fedora'):
2110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Fedora Core'
2120afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif file_contains_pattern(issue, 'SUSE'):
2130afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'SUSE'
2140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif file_contains_pattern(issue, 'Ubuntu'):
2150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Ubuntu'
2160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif file_contains_pattern(issue, 'Debian'):
2170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Debian'
2180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
2190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'Unknown'
220af4efc23471265a3bfa7fef0146fbc0cbb54515bmbligh
221cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
2228a12e800f05f6862fc39c6a45c9c57d9051b795eEric Lidef get_cc():
2238a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li    try:
2248a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li        return os.environ['CC']
2258a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li    except KeyError:
2268a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li        return 'gcc'
2278a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li
2288a12e800f05f6862fc39c6a45c9c57d9051b795eEric Li
229f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmblighdef get_vmlinux():
2300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the full path to vmlinux
231c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
2320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Ahem. This is crap. Pray harder. Bad Martin.
2330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
2342da4d885be334f7db795c3f017daa06ff8ea703dmbligh    vmlinux = '/boot/vmlinux-%s' % utils.system_output('uname -r')
2350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isfile(vmlinux):
2360afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return vmlinux
2372da4d885be334f7db795c3f017daa06ff8ea703dmbligh    vmlinux = '/lib/modules/%s/build/vmlinux' % utils.system_output('uname -r')
2380afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isfile(vmlinux):
2390afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return vmlinux
2400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return None
241f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
242f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
243f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmblighdef get_systemmap():
2440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the full path to System.map
245c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
2460afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Ahem. This is crap. Pray harder. Bad Martin.
2470afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
2482da4d885be334f7db795c3f017daa06ff8ea703dmbligh    map = '/boot/System.map-%s' % utils.system_output('uname -r')
2490afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isfile(map):
2500afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return map
2512da4d885be334f7db795c3f017daa06ff8ea703dmbligh    map = '/lib/modules/%s/build/System.map' % utils.system_output('uname -r')
2520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.path.isfile(map):
2530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return map
2540afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return None
25567b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh
25667b5ece7667fc71429ee05b07ac7654ed5a05df7mbligh
25767b5ece7667fc71429ee05b07ac7654ed5a05df7mblighdef get_modules_dir():
2580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the modules dir for the running kernel version"""
2592da4d885be334f7db795c3f017daa06ff8ea703dmbligh    kernel_version = utils.system_output('uname -r')
2600afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return '/lib/modules/%s/kernel' % kernel_version
261f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
262f49d5cfa9fc49a34b3b5e5e1cb97ce2c0a77dd0cmbligh
263eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp_CPUINFO_RE = re.compile(r'^(?P<key>[^\t]*)\t*: ?(?P<value>.*)$')
264eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp
265f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
266eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharpdef get_cpuinfo():
267eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    """Read /proc/cpuinfo and convert to a list of dicts."""
268eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    cpuinfo = []
269eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    with open('/proc/cpuinfo', 'r') as f:
270eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp        cpu = {}
271eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp        for line in f:
272eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp            line = line.strip()
273eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp            if not line:
274eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp                cpuinfo.append(cpu)
275eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp                cpu = {}
276eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp                continue
277eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp            match = _CPUINFO_RE.match(line)
278eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp            cpu[match.group('key')] = match.group('value')
279eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp        if cpu:
280eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp            # cpuinfo usually ends in a blank line, so this shouldn't happen.
281eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp            cpuinfo.append(cpu)
282eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    return cpuinfo
283eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp
284f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
2855970cf057674accdb00a7742eae50e40c57e52d0mblighdef get_cpu_arch():
2860afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Work out which CPU architecture we're running on"""
2870afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    f = open('/proc/cpuinfo', 'r')
2880afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    cpuinfo = f.readlines()
2890afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    f.close()
2900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if list_grep(cpuinfo, '^cpu.*(RS64|POWER3|Broadband Engine)'):
2910afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'power'
2920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif list_grep(cpuinfo, '^cpu.*POWER4'):
2930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'power4'
2940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif list_grep(cpuinfo, '^cpu.*POWER5'):
2950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'power5'
2960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif list_grep(cpuinfo, '^cpu.*POWER6'):
2970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'power6'
2980758c82ce9ef641b746b5b9a2d0ce409ba6169c7mbligh    elif list_grep(cpuinfo, '^cpu.*POWER7'):
2990758c82ce9ef641b746b5b9a2d0ce409ba6169c7mbligh        return 'power7'
3000afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif list_grep(cpuinfo, '^cpu.*PPC970'):
3010afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'power970'
302f23fd920c08ca1734e2dd2827a494619f53694c2mbligh    elif list_grep(cpuinfo, 'ARM'):
303f23fd920c08ca1734e2dd2827a494619f53694c2mbligh        return 'arm'
30412e8b89ac5a26bf29bc89c4d19f2771fa715f52dmbligh    elif list_grep(cpuinfo, '^flags.*:.* lm .*'):
3050afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'x86_64'
306d24bc85e876a2bbd009c5079ac7b1c1386ea2c5aHS Liao    elif list_grep(cpuinfo, 'CPU.*implementer.*0x41'):
307d24bc85e876a2bbd009c5079ac7b1c1386ea2c5aHS Liao        return 'arm'
3080afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
3090afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'i386'
310f4c35322b200d65f41a8332b4f3503beb497840dmbligh
311f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
31282dd904be8244d3d5933742bddfe5293734c7207Haixia Shidef get_arm_soc_family_from_devicetree():
31382dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    """
31482dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    Work out which ARM SoC we're running on based on the 'compatible' property
31582dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    of the base node of devicetree, if it exists.
31682dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    """
31782dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    devicetree_compatible = '/sys/firmware/devicetree/base/compatible'
31882dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    if not os.path.isfile(devicetree_compatible):
31982dd904be8244d3d5933742bddfe5293734c7207Haixia Shi        return None
32082dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    f = open(devicetree_compatible, 'r')
32182dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    compatible = f.readlines()
32282dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    f.close()
32382dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    if list_grep(compatible, 'rk3399'):
32482dd904be8244d3d5933742bddfe5293734c7207Haixia Shi        return 'rockchip'
32582dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    elif list_grep(compatible, 'mt8173'):
32682dd904be8244d3d5933742bddfe5293734c7207Haixia Shi        return 'mediatek'
32782dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    return None
32882dd904be8244d3d5933742bddfe5293734c7207Haixia Shi
32982dd904be8244d3d5933742bddfe5293734c7207Haixia Shi
3307c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtzdef get_arm_soc_family():
3317c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    """Work out which ARM SoC we're running on"""
33282dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    family = get_arm_soc_family_from_devicetree()
33382dd904be8244d3d5933742bddfe5293734c7207Haixia Shi    if family is not None:
33482dd904be8244d3d5933742bddfe5293734c7207Haixia Shi        return family
33582dd904be8244d3d5933742bddfe5293734c7207Haixia Shi
3367c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    f = open('/proc/cpuinfo', 'r')
3377c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    cpuinfo = f.readlines()
3387c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    f.close()
3397c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    if list_grep(cpuinfo, 'EXYNOS5'):
3407c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz        return 'exynos5'
3417c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    elif list_grep(cpuinfo, 'Tegra'):
3427c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz        return 'tegra'
343aec3bf5a657ad9e111e2c337446fbac49707c65dZhengShunQian    elif list_grep(cpuinfo, 'Rockchip'):
344aec3bf5a657ad9e111e2c337446fbac49707c65dZhengShunQian        return 'rockchip'
3457c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    return 'arm'
3467c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz
347f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
348171137407ec2d93db48123a4331929c8e9290cbbDaniel Kurtzdef get_cpu_soc_family():
3497c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    """Like get_cpu_arch, but for ARM, returns the SoC family name"""
3508a25e3fbab199b040beb5e44876aaf69a8510b3dSatyajit Sahu    f = open('/proc/cpuinfo', 'r')
3518a25e3fbab199b040beb5e44876aaf69a8510b3dSatyajit Sahu    cpuinfo = f.readlines()
3528a25e3fbab199b040beb5e44876aaf69a8510b3dSatyajit Sahu    f.close()
3537c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    family = get_cpu_arch()
3547c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    if family == 'arm':
35559b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel        family = get_arm_soc_family()
3568a25e3fbab199b040beb5e44876aaf69a8510b3dSatyajit Sahu    if list_grep(cpuinfo, '^vendor_id.*:.*AMD'):
3578a25e3fbab199b040beb5e44876aaf69a8510b3dSatyajit Sahu        family = 'amd'
3587c6ee7899f011215eea6d57181f58b8bf43d3b85Daniel Kurtz    return family
359f4c35322b200d65f41a8332b4f3503beb497840dmbligh
360f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
361eb5e7a3ea391cbf48e8990937a1cb96e20e52715David SharpINTEL_UARCH_TABLE = {
362eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    '06_1C': 'Atom',
36359b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_26': 'Atom',
36459b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_36': 'Atom',
36559b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_4C': 'Braswell',
366eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    '06_3D': 'Broadwell',
36759b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_0D': 'Dothan',
36859b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_3A': 'IvyBridge',
36959b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_3E': 'IvyBridge',
370eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    '06_3C': 'Haswell',
37159b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_3F': 'Haswell',
372eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    '06_45': 'Haswell',
37359b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_46': 'Haswell',
374eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    '06_0F': 'Merom',
37559b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_16': 'Merom',
37659b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_17': 'Nehalem',
37759b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_1A': 'Nehalem',
37859b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_1D': 'Nehalem',
37959b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_1E': 'Nehalem',
38059b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_1F': 'Nehalem',
38159b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_2E': 'Nehalem',
38259b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_2A': 'SandyBridge',
38359b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_2D': 'SandyBridge',
38459b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_4E': 'Skylake',
385eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    '0F_03': 'Prescott',
38659b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '0F_04': 'Prescott',
38759b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '0F_06': 'Presler',
38859b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_25': 'Westmere',
38959b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_2C': 'Westmere',
39059b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel    '06_2F': 'Westmere',
391eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp}
392eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp
393f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
394eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharpdef get_intel_cpu_uarch(numeric=False):
395eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    """Return the Intel microarchitecture we're running on, or None.
396eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp
397eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    Returns None if this is not an Intel CPU. Returns the family and model as
398eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    underscore-separated hex (per Intel manual convention) if the uarch is not
399eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    known, or if numeric is True.
400eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    """
401eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    if not get_current_kernel_arch().startswith('x86'):
402eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp        return None
403eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    cpuinfo = get_cpuinfo()[0]
404eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    if cpuinfo['vendor_id'] != 'GenuineIntel':
405eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp        return None
406eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    family_model = '%02X_%02X' % (int(cpuinfo['cpu family']),
407eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp                                  int(cpuinfo['model']))
408eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    if numeric:
409eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp        return family_model
410eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp    return INTEL_UARCH_TABLE.get(family_model, family_model)
411eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp
412eb5e7a3ea391cbf48e8990937a1cb96e20e52715David Sharp
413548f29af9e38f87c3609838f5aabeac94bb69f13mblighdef get_current_kernel_arch():
4140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Get the machine architecture, now just a wrap of 'uname -m'."""
4150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return os.popen('uname -m').read().rstrip()
416cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
417cdf02a40b97d0570b0e8f8a74a2ede7a868bb1edmbligh
418fdbcaec15092d8b4af80970c495038bdf9b0e63fmblighdef get_file_arch(filename):
4190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # -L means follow symlinks
4202da4d885be334f7db795c3f017daa06ff8ea703dmbligh    file_data = utils.system_output('file -L ' + filename)
4210afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if file_data.count('80386'):
4220afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return 'i386'
4230afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return None
424fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
425fdbcaec15092d8b4af80970c495038bdf9b0e63fmbligh
426f4c35322b200d65f41a8332b4f3503beb497840dmblighdef count_cpus():
4270afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """number of CPUs in the local machine according to /proc/cpuinfo"""
42846589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang    try:
42959b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel       return multiprocessing.cpu_count()
43046589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang    except Exception as e:
43159b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel       logging.exception('can not get cpu count from'
43246589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang                        ' multiprocessing.cpu_count()')
433f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    cpuinfo = get_cpuinfo()
43446589b1ec97d5780c7853a67d9b5173e87cc29c0cychiang    # Returns at least one cpu. Check comment #1 in crosbug.com/p/9582.
435f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    return len(cpuinfo) or 1
436f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
437f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
438f948379fcf6caa1987df14b3963efaf59eaa0834David Sharpdef cpu_online_map():
439f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    """
440f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    Check out the available cpu online map
441f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    """
442f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    cpuinfo = get_cpuinfo()
443f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    cpus = []
444f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    for cpu in cpuinfo:
44559b3bc78f615866d97a9569964af7b380189cdc7Ilja H. Friedel        cpus.append(cpu['processor'])  # grab cpu number
446f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    return cpus
447f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
448f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
449f948379fcf6caa1987df14b3963efaf59eaa0834David Sharpdef get_cpu_family():
450f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    cpuinfo = get_cpuinfo()[0]
451f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    return int(cpuinfo['cpu_family'])
452f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
453f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
454f948379fcf6caa1987df14b3963efaf59eaa0834David Sharpdef get_cpu_vendor():
455f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    cpuinfo = get_cpuinfo()
456f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    vendors = [cpu['vendor_id'] for cpu in cpuinfo]
457f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    for v in vendors[1:]:
458f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp        if v != vendors[0]:
459f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp            raise error.TestError('multiple cpu vendors found: ' + str(vendors))
460f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    return vendors[0]
461f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
462f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp
463f948379fcf6caa1987df14b3963efaf59eaa0834David Sharpdef probe_cpus():
464f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    """
465f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    This routine returns a list of cpu devices found under
466f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    /sys/devices/system/cpu.
467f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    """
468f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    cmd = 'find /sys/devices/system/cpu/ -maxdepth 1 -type d -name cpu*'
469f948379fcf6caa1987df14b3963efaf59eaa0834David Sharp    return utils.system_output(cmd).splitlines()
470f4c35322b200d65f41a8332b4f3503beb497840dmbligh
471e7a170fb097da48af81ca598e29643f3e7cca584mbligh
472e7a170fb097da48af81ca598e29643f3e7cca584mbligh# Returns total memory in kb
473558885e290e3fa847b6a77b6dd66cac33ec6f65cmblighdef read_from_meminfo(key):
4742da4d885be334f7db795c3f017daa06ff8ea703dmbligh    meminfo = utils.system_output('grep %s /proc/meminfo' % key)
4750afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return int(re.search(r'\d+', meminfo).group(0))
476558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
477558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
478e7a170fb097da48af81ca598e29643f3e7cca584mblighdef memtotal():
4790afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return read_from_meminfo('MemTotal')
480558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
481558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
482558885e290e3fa847b6a77b6dd66cac33ec6f65cmblighdef freememtotal():
4830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return read_from_meminfo('MemFree')
484558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
485b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivatdef usable_memtotal():
486dca8dc6fdda4b7b5066685fd460210d3aa302d52Puthikorn Voravootivat    # Reserved 5% for OS use
487dca8dc6fdda4b7b5066685fd460210d3aa302d52Puthikorn Voravootivat    return int(read_from_meminfo('MemFree') * 0.95)
488b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat
489558885e290e3fa847b6a77b6dd66cac33ec6f65cmbligh
4908493be44f65668c6ebad5d1bee3b97b76abdebbdmblighdef rounded_memtotal():
49153da18eddf69243ca175d9a4603cba5b55300726mbligh    # Get total of all physical mem, in kbytes
49253da18eddf69243ca175d9a4603cba5b55300726mbligh    usable_kbytes = memtotal()
49353da18eddf69243ca175d9a4603cba5b55300726mbligh    # usable_kbytes is system's usable DRAM in kbytes,
4948493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   as reported by memtotal() from device /proc/meminfo memtotal
4958493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   after Linux deducts 1.5% to 5.1% for system table overhead
4968493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # Undo the unknown actual deduction by rounding up
4978493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   to next small multiple of a big power-of-two
4988493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   eg  12GB - 5.1% gets rounded back up to 12GB
4998493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    mindeduct = 0.015  # 1.5 percent
5008493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    maxdeduct = 0.055  # 5.5 percent
5018493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # deduction range 1.5% .. 5.5% supports physical mem sizes
5028493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #    6GB .. 12GB in steps of .5GB
5038493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   12GB .. 24GB in steps of 1 GB
5048493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   24GB .. 48GB in steps of 2 GB ...
5058493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # Finer granularity in physical mem sizes would require
5068493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    #   tighter spread between min and max possible deductions
5078493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh
5088493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # increase mem size by at least min deduction, without rounding
509b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat    min_kbytes = int(usable_kbytes / (1.0 - mindeduct))
5108493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # increase mem size further by 2**n rounding, by 0..roundKb or more
51153da18eddf69243ca175d9a4603cba5b55300726mbligh    round_kbytes = int(usable_kbytes / (1.0 - maxdeduct)) - min_kbytes
5128493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh    # find least binary roundup 2**n that covers worst-cast roundKb
51353da18eddf69243ca175d9a4603cba5b55300726mbligh    mod2n = 1 << int(math.ceil(math.log(round_kbytes, 2)))
51453da18eddf69243ca175d9a4603cba5b55300726mbligh    # have round_kbytes <= mod2n < round_kbytes*2
51553da18eddf69243ca175d9a4603cba5b55300726mbligh    # round min_kbytes up to next multiple of mod2n
51653da18eddf69243ca175d9a4603cba5b55300726mbligh    phys_kbytes = min_kbytes + mod2n - 1
51753da18eddf69243ca175d9a4603cba5b55300726mbligh    phys_kbytes = phys_kbytes - (phys_kbytes % mod2n)  # clear low bits
51853da18eddf69243ca175d9a4603cba5b55300726mbligh    return phys_kbytes
5198493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh
5208493be44f65668c6ebad5d1bee3b97b76abdebbdmbligh
521f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanskidef sysctl(key, value=None):
522f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    """Generic implementation of sysctl, to read and write.
523f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
524f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    @param key: A location under /proc/sys
525f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    @param value: If not None, a value to write into the sysctl.
526f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
527f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    @return The single-line sysctl value as a string.
528f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    """
529f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    path = '/proc/sys/%s' % key
530f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    if value is not None:
531f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski        utils.write_one_line(path, str(value))
532f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    return utils.read_one_line(path)
533f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
534f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski
535558885e290e3fa847b6a77b6dd66cac33ec6f65cmblighdef sysctl_kernel(key, value=None):
5360afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """(Very) partial implementation of sysctl, for kernel params"""
537f432516b6b3d274a6fe93cd39022081ebd6aeafcjadmanski    if value is not None:
5380afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # write
5392da4d885be334f7db795c3f017daa06ff8ea703dmbligh        utils.write_one_line('/proc/sys/kernel/%s' % key, str(value))
5400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
5410afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # read
5422da4d885be334f7db795c3f017daa06ff8ea703dmbligh        out = utils.read_one_line('/proc/sys/kernel/%s' % key)
5430afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return int(re.search(r'\d+', out).group(0))
544e7a170fb097da48af81ca598e29643f3e7cca584mbligh
545e7a170fb097da48af81ca598e29643f3e7cca584mbligh
5465285a2dc3c5edbc010825e6d64ecdb219b3ad52cmblighdef _convert_exit_status(sts):
5470afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if os.WIFSIGNALED(sts):
5480afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return -os.WTERMSIG(sts)
5490afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    elif os.WIFEXITED(sts):
5500afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return os.WEXITSTATUS(sts)
5510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
5520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # impossible?
5530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise RuntimeError("Unknown exit status %d!" % sts)
5545285a2dc3c5edbc010825e6d64ecdb219b3ad52cmbligh
5555285a2dc3c5edbc010825e6d64ecdb219b3ad52cmbligh
556f4c35322b200d65f41a8332b4f3503beb497840dmblighdef where_art_thy_filehandles():
5570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Dump the current list of filehandles"""
5580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    os.system("ls -l /proc/%d/fd >> /dev/tty" % os.getpid())
559f4c35322b200d65f41a8332b4f3503beb497840dmbligh
560f4c35322b200d65f41a8332b4f3503beb497840dmbligh
561f4c35322b200d65f41a8332b4f3503beb497840dmblighdef print_to_tty(string):
5620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Output string straight to the tty"""
5630afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    open('/dev/tty', 'w').write(string + '\n')
564f4c35322b200d65f41a8332b4f3503beb497840dmbligh
565f4c35322b200d65f41a8332b4f3503beb497840dmbligh
566b8a14e358b611f2d97c06e863be9b53ab2bedeefmblighdef dump_object(object):
5670afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Dump an object's attributes and methods
568c86b0b45cd0198d99d271a79f8b6de29feb98cd5mbligh
5690afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    kind of like dir()
5700afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
5710afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for item in object.__dict__.iteritems():
5720afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        print item
5730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        try:
574b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat            (key, value) = item
5750afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            dump_object(value)
5760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        except:
5770afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            continue
578b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh
579b8a14e358b611f2d97c06e863be9b53ab2bedeefmbligh
5804b089663460063b638124ff665f38d2fe7427648mblighdef environ(env_key):
5810afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """return the requested environment variable, or '' if unset"""
5820afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if (os.environ.has_key(env_key)):
5830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return os.environ[env_key]
5840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
5850afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return ''
5864b089663460063b638124ff665f38d2fe7427648mbligh
5874b089663460063b638124ff665f38d2fe7427648mbligh
5884b089663460063b638124ff665f38d2fe7427648mblighdef prepend_path(newpath, oldpath):
5890afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """prepend newpath to oldpath"""
5900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if (oldpath):
5910afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return newpath + ':' + oldpath
5920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
5930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return newpath
5944b089663460063b638124ff665f38d2fe7427648mbligh
5954b089663460063b638124ff665f38d2fe7427648mbligh
5964b089663460063b638124ff665f38d2fe7427648mblighdef append_path(oldpath, newpath):
5970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """append newpath to oldpath"""
5980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if (oldpath):
5990afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return oldpath + ':' + newpath
6000afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
6010afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return newpath
6024b089663460063b638124ff665f38d2fe7427648mbligh
6034b089663460063b638124ff665f38d2fe7427648mbligh
60477e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp_TIME_OUTPUT_RE = re.compile(
60577e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp        r'([\d\.]*)user ([\d\.]*)system '
60677e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp        r'(\d*):([\d\.]*)elapsed (\d*)%CPU')
60777e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
60877e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
6094e75b0d3b020f901456217fb8ff0d7d4391fa869mblighdef avgtime_print(dir):
6100afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """ Calculate some benchmarking statistics.
6110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        Input is a directory containing a file called 'time'.
6120afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        File contains one-per-line results of /usr/bin/time.
6130afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        Output is average Elapsed, User, and System time in seconds,
6140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski          and average CPU percentage.
6150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
6160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    user = system = elapsed = cpu = count = 0
61777e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    with open(dir + "/time") as f:
61877e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp        for line in f:
61977e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp            try:
62077e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp                m = _TIME_OUTPUT_RE.match(line);
62177e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp                user += float(m.group(1))
62277e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp                system += float(m.group(2))
62377e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp                elapsed += (float(m.group(3)) * 60) + float(m.group(4))
62477e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp                cpu += float(m.group(5))
62577e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp                count += 1
62677e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp            except:
62777e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp                raise ValueError("badly formatted times")
6280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
6290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return "Elapsed: %0.2fs User: %0.2fs System: %0.2fs CPU: %0.0f%%" % \
630b7f4c2e8f344d9dbff16b2d39dafc2590436bd88Puthikorn Voravootivat          (elapsed / count, user / count, system / count, cpu / count)
6314e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh
6324e75b0d3b020f901456217fb8ff0d7d4391fa869mbligh
63377e0121a0d2a878433b96f4757a44db541530c3cDavid Sharpdef to_seconds(time_string):
63477e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    """Converts a string in M+:SS.SS format to S+.SS"""
63577e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    elts = time_string.split(':')
63677e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    if len(elts) == 1:
63777e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp        return time_string
63877e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    return str(int(elts[0]) * 60 + float(elts[1]))
63977e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
64077e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
64177e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp_TIME_OUTPUT_RE_2 = re.compile(r'(.*?)user (.*?)system (.*?)elapsed')
64277e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
64377e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
64477e0121a0d2a878433b96f4757a44db541530c3cDavid Sharpdef extract_all_time_results(results_string):
64577e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    """Extract user, system, and elapsed times into a list of tuples"""
64677e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    results = []
64777e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    for result in _TIME_OUTPUT_RE_2.findall(results_string):
64877e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp        results.append(tuple([to_seconds(elt) for elt in result]))
64977e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    return results
65077e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
65177e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
652f06db0f9b381737b9c85bef1c23ea1a1ca73c559mblighdef running_config():
6530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
6540afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Return path of config file of the currently running kernel
6550afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
6562da4d885be334f7db795c3f017daa06ff8ea703dmbligh    version = utils.system_output('uname -r')
6570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for config in ('/proc/config.gz', \
6580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   '/boot/config-%s' % version,
6590afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   '/lib/modules/%s/build/.config' % version):
6600afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if os.path.isfile(config):
6610afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return config
6620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return None
6639ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh
6649ec8acc50c0fe06a40353db0df8e135cebb2ec58mbligh
665a1bef1f2774b539df11c134d9a9a177304c34f3cmblighdef check_for_kernel_feature(feature):
6660afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    config = running_config()
667a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
6680afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if not config:
6690afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise TypeError("Can't find kernel config file")
670a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
671959e8162836703848f8e1801f74e7117b850e889lmr    if magic.guess_type(config) == 'application/x-gzip':
6720afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        grep = 'zgrep'
6730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    else:
6740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        grep = 'grep'
6750afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    grep += ' ^CONFIG_%s= %s' % (feature, config)
676a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
6772da4d885be334f7db795c3f017daa06ff8ea703dmbligh    if not utils.system_output(grep, ignore_status=True):
6780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        raise ValueError("Kernel doesn't have a %s feature" % (feature))
679a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
680a1bef1f2774b539df11c134d9a9a177304c34f3cmbligh
681663e4f664465dbaa9e86c5c20d035ad9bd1e65edmblighdef check_glibc_ver(ver):
6820afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    glibc_ver = commands.getoutput('ldd --version').splitlines()[0]
6830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    glibc_ver = re.search(r'(\d+\.\d+(\.\d+)?)', glibc_ver).group()
6840fab1e986e36dd9addaa075c6c73e71fbd756652lmr    if utils.compare_versions(glibc_ver, ver) == -1:
6850fab1e986e36dd9addaa075c6c73e71fbd756652lmr        raise error.TestError("Glibc too old (%s). Glibc >= %s is needed." %
6860fab1e986e36dd9addaa075c6c73e71fbd756652lmr                              (glibc_ver, ver))
6870763522bf0dcd6297385a7db965086ed8ba18adambligh
6880763522bf0dcd6297385a7db965086ed8ba18adamblighdef check_kernel_ver(ver):
6892da4d885be334f7db795c3f017daa06ff8ea703dmbligh    kernel_ver = utils.system_output('uname -r')
6900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    kv_tmp = re.split(r'[-]', kernel_ver)[0:3]
69142b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr    # In compare_versions, if v1 < v2, return value == -1
69242b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr    if utils.compare_versions(kv_tmp[0], ver) == -1:
69342b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr        raise error.TestError("Kernel too old (%s). Kernel > %s is needed." %
69442b7a5d85e9467ae6f3408f20bfee5de93afcf45lmr                              (kernel_ver, ver))
69560418bb82d1734a7f73a5e4c8870d06799795397mbligh
6969061a273dfd2e522c15f6dd77cfed1e2815e4e9embligh
697264cd8f4889cea73fa5fb7873e3243c1c770a1bcmblighdef human_format(number):
6980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # Convert number to kilo / mega / giga format.
6990afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if number < 1024:
7000afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return "%d" % number
7010afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    kilo = float(number) / 1024.0
7020afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if kilo < 1024:
7030afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return "%.2fk" % kilo
7040afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    meg = kilo / 1024.0
7050afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if meg < 1024:
7060afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return "%.2fM" % meg
7070afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    gig = meg / 1024.0
7080afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return "%.2fG" % gig
709264cd8f4889cea73fa5fb7873e3243c1c770a1bcmbligh
7108eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
7118eca3a98728afabc7fc761c08dbb8e91260c7de4mblighdef numa_nodes():
7120afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    node_paths = glob.glob('/sys/devices/system/node/node*')
7130afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    nodes = [int(re.sub(r'.*node(\d+)', r'\1', x)) for x in node_paths]
7140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return (sorted(nodes))
7158eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
7168eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
7178eca3a98728afabc7fc761c08dbb8e91260c7de4mblighdef node_size():
7180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    nodes = max(len(numa_nodes()), 1)
7190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return ((memtotal() * 1024) / nodes)
7208eca3a98728afabc7fc761c08dbb8e91260c7de4mbligh
72132bcff3382844181eaf3d74e0fb252d88edfc8fbmbligh
722c421164e16db7233ef8fcc4ecfd83f2979aec16amblighdef pickle_load(filename):
7230afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return pickle.load(open(filename, 'r'))
724c421164e16db7233ef8fcc4ecfd83f2979aec16ambligh
725237bed32e0110ccd0db10823df742534dd7dc50dmbligh
726237bed32e0110ccd0db10823df742534dd7dc50dmbligh# Return the kernel version and build timestamp.
727237bed32e0110ccd0db10823df742534dd7dc50dmblighdef running_os_release():
7280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return os.uname()[2:4]
729237bed32e0110ccd0db10823df742534dd7dc50dmbligh
730237bed32e0110ccd0db10823df742534dd7dc50dmbligh
731237bed32e0110ccd0db10823df742534dd7dc50dmblighdef running_os_ident():
7320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    (version, timestamp) = running_os_release()
7330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return version + '::' + timestamp
734b830e28297dca51aed2c4b57469a3e04845e54e7mbligh
735b830e28297dca51aed2c4b57469a3e04845e54e7mbligh
7363bf79ca4d5490f9af09e1ddc39b8df5343b34d06mblighdef running_os_full_version():
7373bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh    (version, timestamp) = running_os_release()
7383bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh    return version
7393bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh
7403bf79ca4d5490f9af09e1ddc39b8df5343b34d06mbligh
741523a19b532a778dd9e752e507ac75d3ffc5c701ambligh# much like find . -name 'pattern'
742523a19b532a778dd9e752e507ac75d3ffc5c701amblighdef locate(pattern, root=os.getcwd()):
7430afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for path, dirs, files in os.walk(root):
744987071e1fba830910658ce987bb803d142480c03mbligh        for f in files:
745987071e1fba830910658ce987bb803d142480c03mbligh            if fnmatch.fnmatch(f, pattern):
7467076b192936caad193898cff194e82f83dd13d63mbligh                yield os.path.abspath(os.path.join(path, f))
747523a19b532a778dd9e752e507ac75d3ffc5c701ambligh
748523a19b532a778dd9e752e507ac75d3ffc5c701ambligh
74925bb1e1fbb67950ac480f6500138c19647472889mblighdef freespace(path):
7500afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the disk free space, in bytes"""
7510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    s = os.statvfs(path)
7520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return s.f_bavail * s.f_bsize
7538415f966acaaa3aa3ca6a651d9a190081edbb0eejadmanski
7548415f966acaaa3aa3ca6a651d9a190081edbb0eejadmanski
7558415f966acaaa3aa3ca6a651d9a190081edbb0eejadmanskidef disk_block_size(path):
7560afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Return the disk block size, in bytes"""
7570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return os.statvfs(path).f_bsize
7586de9cdfe8ce95c1d87b01aa768526a64755090cambligh
7596de9cdfe8ce95c1d87b01aa768526a64755090cambligh
76077e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp_DISK_PARTITION_3_RE = re.compile(r'^(/dev/hd[a-z]+)3', re.M)
76177e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
7622316e52c84ac8799330c52359bc4dd5e7f7324d5mblighdef get_disks():
7632da4d885be334f7db795c3f017daa06ff8ea703dmbligh    df_output = utils.system_output('df')
76477e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    return _DISK_PARTITION_3_RE.findall(df_output)
7656de9cdfe8ce95c1d87b01aa768526a64755090cambligh
7663e9062e854a920eead8e250c4e79838c30a0657cmbligh
7678b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivatdef get_disk_size(disk_name):
7688b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
7698b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    Return size of disk in byte. Return 0 in Error Case
7708b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7718b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    @param disk_name: disk name to find size
7728b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
7738b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    device = os.path.basename(disk_name)
7748b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    for line in file('/proc/partitions'):
7758b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat        try:
77610e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            _, _, blocks, name = re.split(r' +', line.strip())
7778b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat        except ValueError:
7788b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat            continue
7798b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat        if name == device:
7808b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat            return 1024 * int(blocks)
7818b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    return 0
7828b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7838b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7848b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivatdef get_disk_size_gb(disk_name):
7858b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
7868b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    Return size of disk in GB (10^9). Return 0 in Error Case
7878b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7888b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    @param disk_name: disk name to find size
7898b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
7908b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    return int(get_disk_size(disk_name) / (10.0 ** 9) + 0.5)
7918b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7928b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7938b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivatdef get_disk_model(disk_name):
7948b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
7958b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    Return model name for internal storage device
7968b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
7978b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    @param disk_name: disk name to find model
7988b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    """
7998b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    cmd1 = 'udevadm info --query=property --name=%s' % disk_name
8008b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    cmd2 = 'grep -E "ID_(NAME|MODEL)="'
8018b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    cmd3 = 'cut -f 2 -d"="'
8028b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    cmd = ' | '.join([cmd1, cmd2, cmd3])
8038b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat    return utils.system_output(cmd)
8048b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
8058b811e05e984afbdbdba57d0695279e3f28430dePuthikorn Voravootivat
806a409c80507d68befd00d3e9aa20cf378f11c1fb9Gwendal Grignou_DISK_DEV_RE = re.compile(r'/dev/sd[a-z]|/dev/mmcblk[0-9]*|/dev/nvme[0-9]*')
80777e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
80877e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp
80910e71e69c71002f312f7282b3180dda3db5854adGwendal Grignoudef get_disk_from_filename(filename):
81010e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    """
81110e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    Return the disk device the filename is on.
81210e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    If the file is on tmpfs or other special file systems,
81310e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    return None.
81410e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
81510e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    @param filename: name of file, full path.
81610e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    """
81710e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
81830dcb3bde6125708b4d58aebfdceac1b35810c39Gwendal Grignou    if not os.path.exists(filename):
81910e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        raise error.TestError('file %s missing' % filename)
82010e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
82110e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    if filename[0] != '/':
82210e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        raise error.TestError('This code works only with full path')
82310e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
82477e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp    m = _DISK_DEV_RE.match(filename)
82510e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    while not m:
82610e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        if filename[0] != '/':
82710e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            return None
82810e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        if filename == '/dev/root':
82910e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            cmd = 'rootdev -d -s'
83010e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        elif filename.startswith('/dev/mapper'):
83110e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            cmd = 'dmsetup table "%s"' % os.path.basename(filename)
83210e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            dmsetup_output = utils.system_output(cmd).split(' ')
83310e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            if dmsetup_output[2] == 'verity':
83410e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou                maj_min = dmsetup_output[4]
83510e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            elif dmsetup_output[2] == 'crypt':
83610e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou                maj_min = dmsetup_output[6]
83710e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            cmd = 'realpath "/dev/block/%s"' % maj_min
83810e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        elif filename.startswith('/dev/loop'):
83910e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            cmd = 'losetup -O BACK-FILE "%s" | tail -1' % filename
84010e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        else:
84110e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou            cmd = 'df "%s" | tail -1 | cut -f 1 -d" "' % filename
84210e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou        filename = utils.system_output(cmd)
84377e0121a0d2a878433b96f4757a44db541530c3cDavid Sharp        m = _DISK_DEV_RE.match(filename)
84410e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou    return m.group(0)
84510e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
84610e71e69c71002f312f7282b3180dda3db5854adGwendal Grignou
8478ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivatdef get_disk_firmware_version(disk_name):
8488ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8498ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    Return firmware version for internal storage device. (empty string for eMMC)
8508ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8518ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param disk_name: disk name to find model
8528ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8538ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd1 = 'udevadm info --query=property --name=%s' % disk_name
8548ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd2 = 'grep -E "ID_REVISION="'
8558ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd3 = 'cut -f 2 -d"="'
8568ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd = ' | '.join([cmd1, cmd2, cmd3])
8578ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    return utils.system_output(cmd)
8588ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8598ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8608ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivatdef is_disk_scsi(disk_name):
8618ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8628ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    Return true if disk is a scsi device, return false otherwise
8638ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8648ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param disk_name: disk name check
8658ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8668ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    return re.match('/dev/sd[a-z]+', disk_name)
8678ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8688ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8698ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivatdef is_disk_harddisk(disk_name):
8708ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8718ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    Return true if disk is a harddisk, return false otherwise
8728ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8738ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param disk_name: disk name check
8748ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8758ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd1 = 'udevadm info --query=property --name=%s' % disk_name
8768ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd2 = 'grep -E "ID_ATA_ROTATION_RATE_RPM="'
8778ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd3 = 'cut -f 2 -d"="'
8788ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd = ' | '.join([cmd1, cmd2, cmd3])
8798ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8808ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    rtt = utils.system_output(cmd)
8818ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8828ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    # eMMC will not have this field; rtt == ''
8838ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    # SSD will have zero rotation rate; rtt == '0'
8848ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    # For harddisk rtt > 0
8858ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    return rtt and int(rtt) > 0
8868ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8878ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8888ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivatdef verify_hdparm_feature(disk_name, feature):
8898ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8908ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    Check for feature support for SCSI disk using hdparm
8918ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
8928ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param disk_name: target disk
8938ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param feature: hdparm output string of the feature
8948ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
8958ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    cmd = 'hdparm -I %s | grep -q "%s"' % (disk_name, feature)
8968ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    ret = utils.system(cmd, ignore_status=True)
8978ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    if ret == 0:
8988ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat        return True
8998ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    elif ret == 1:
9008ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat        return False
9018ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    else:
9028ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat        raise error.TestFail('Error running command %s' % cmd)
9038ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
9048ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
9058ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivatdef get_storage_error_msg(disk_name, reason):
9068ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
9078ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    Get Error message for storage test which include disk model.
9088ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    and also include the firmware version for the SCSI disk
9098ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
9108ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param disk_name: target disk
9118ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    @param reason: Reason of the error.
9128ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    """
9138ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
9148ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    msg = reason
9158ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
9168ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    model = get_disk_model(disk_name)
9178ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    msg += ' Disk model: %s' % model
9188ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
9198ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    if is_disk_scsi(disk_name):
9208ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat        fw = get_disk_firmware_version(disk_name)
9218ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat        msg += ' firmware: %s' % fw
9228ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
9238ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat    return msg
9248ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
9258ba770dc9bcf2e60bf2db1b7128d7502df6e8e60Puthikorn Voravootivat
926570152be2c6a576fb22da1e1f2b6226fd8284358Brian Norrisdef load_module(module_name, params=None):
9270afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    # Checks if a module has already been loaded
9280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if module_is_loaded(module_name):
9290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return False
930af4efc23471265a3bfa7fef0146fbc0cbb54515bmbligh
931570152be2c6a576fb22da1e1f2b6226fd8284358Brian Norris    cmd = '/sbin/modprobe ' + module_name
932570152be2c6a576fb22da1e1f2b6226fd8284358Brian Norris    if params:
933570152be2c6a576fb22da1e1f2b6226fd8284358Brian Norris        cmd += ' ' + params
934570152be2c6a576fb22da1e1f2b6226fd8284358Brian Norris    utils.system(cmd)
9350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return True
9363e9062e854a920eead8e250c4e79838c30a0657cmbligh
9373e9062e854a920eead8e250c4e79838c30a0657cmbligh
9383e9062e854a920eead8e250c4e79838c30a0657cmblighdef unload_module(module_name):
939b923fc2a01db6e4548ffd541d86f9be49bc5805almr    """
940b923fc2a01db6e4548ffd541d86f9be49bc5805almr    Removes a module. Handles dependencies. If even then it's not possible
941b923fc2a01db6e4548ffd541d86f9be49bc5805almr    to remove one of the modules, it will trhow an error.CmdError exception.
942b923fc2a01db6e4548ffd541d86f9be49bc5805almr
943b923fc2a01db6e4548ffd541d86f9be49bc5805almr    @param module_name: Name of the module we want to remove.
944b923fc2a01db6e4548ffd541d86f9be49bc5805almr    """
945abbd237f6e10e469e11682669bd49ed8f61e42b8Henrik Kjellander    l_raw = utils.system_output("/bin/lsmod").splitlines()
946b923fc2a01db6e4548ffd541d86f9be49bc5805almr    lsmod = [x for x in l_raw if x.split()[0] == module_name]
947b923fc2a01db6e4548ffd541d86f9be49bc5805almr    if len(lsmod) > 0:
948b923fc2a01db6e4548ffd541d86f9be49bc5805almr        line_parts = lsmod[0].split()
949b923fc2a01db6e4548ffd541d86f9be49bc5805almr        if len(line_parts) == 4:
950b923fc2a01db6e4548ffd541d86f9be49bc5805almr            submodules = line_parts[3].split(",")
951b923fc2a01db6e4548ffd541d86f9be49bc5805almr            for submodule in submodules:
952b923fc2a01db6e4548ffd541d86f9be49bc5805almr                unload_module(submodule)
953b923fc2a01db6e4548ffd541d86f9be49bc5805almr        utils.system("/sbin/modprobe -r %s" % module_name)
954f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz        logging.info("Module %s unloaded", module_name)
955b923fc2a01db6e4548ffd541d86f9be49bc5805almr    else:
956f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz        logging.info("Module %s is already unloaded", module_name)
9573e9062e854a920eead8e250c4e79838c30a0657cmbligh
9583e9062e854a920eead8e250c4e79838c30a0657cmbligh
9593e9062e854a920eead8e250c4e79838c30a0657cmblighdef module_is_loaded(module_name):
9600afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    module_name = module_name.replace('-', '_')
961abbd237f6e10e469e11682669bd49ed8f61e42b8Henrik Kjellander    modules = utils.system_output('/bin/lsmod').splitlines()
9620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    for module in modules:
9630afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        if module.startswith(module_name) and module[len(module_name)] == ' ':
9640afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return True
9650afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return False
9663e9062e854a920eead8e250c4e79838c30a0657cmbligh
9673e9062e854a920eead8e250c4e79838c30a0657cmbligh
9686b34c4cc34bebd20def94c0191ef1e46dd6a1cdemblighdef get_loaded_modules():
969abbd237f6e10e469e11682669bd49ed8f61e42b8Henrik Kjellander    lsmod_output = utils.system_output('/bin/lsmod').splitlines()[1:]
9700afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return [line.split(None, 1)[0] for line in lsmod_output]
9716b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
9726b34c4cc34bebd20def94c0191ef1e46dd6a1cdembligh
9733e9062e854a920eead8e250c4e79838c30a0657cmblighdef get_huge_page_size():
9742da4d885be334f7db795c3f017daa06ff8ea703dmbligh    output = utils.system_output('grep Hugepagesize /proc/meminfo')
9750afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return int(output.split()[1]) # Assumes units always in kB. :(
9763e9062e854a920eead8e250c4e79838c30a0657cmbligh
9773e9062e854a920eead8e250c4e79838c30a0657cmbligh
9783e9062e854a920eead8e250c4e79838c30a0657cmblighdef get_num_huge_pages():
9792da4d885be334f7db795c3f017daa06ff8ea703dmbligh    raw_hugepages = utils.system_output('/sbin/sysctl vm.nr_hugepages')
9800afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    return int(raw_hugepages.split()[2])
9813e9062e854a920eead8e250c4e79838c30a0657cmbligh
9823e9062e854a920eead8e250c4e79838c30a0657cmbligh
9833e9062e854a920eead8e250c4e79838c30a0657cmblighdef set_num_huge_pages(num):
9842da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system('/sbin/sysctl vm.nr_hugepages=%d' % num)
9853e9062e854a920eead8e250c4e79838c30a0657cmbligh
9863e9062e854a920eead8e250c4e79838c30a0657cmbligh
98770c50ad0eec36f4678374040031da84150a75997mblighdef ping_default_gateway():
9880afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """Ping the default gateway."""
98970c50ad0eec36f4678374040031da84150a75997mbligh
9900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    network = open('/etc/sysconfig/network')
9910afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    m = re.search('GATEWAY=(\S+)', network.read())
9920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
9930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    if m:
9940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        gw = m.group(1)
9950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        cmd = 'ping %s -c 5 > /dev/null' % gw
9962da4d885be334f7db795c3f017daa06ff8ea703dmbligh        return utils.system(cmd, ignore_status=True)
9970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski
9980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    raise error.TestError('Unable to find default gateway')
99970c50ad0eec36f4678374040031da84150a75997mbligh
100070c50ad0eec36f4678374040031da84150a75997mbligh
1001115feb2fee75e8cb75873905f07763fbfafc8f6ejadmanskidef drop_caches():
1002115feb2fee75e8cb75873905f07763fbfafc8f6ejadmanski    """Writes back all dirty pages to disk and clears all the caches."""
10032da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system("sync")
1004115feb2fee75e8cb75873905f07763fbfafc8f6ejadmanski    # We ignore failures here as this will fail on 2.6.11 kernels.
10052da4d885be334f7db795c3f017daa06ff8ea703dmbligh    utils.system("echo 3 > /proc/sys/vm/drop_caches", ignore_status=True)
1006a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh
1007a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh
1008e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mblighdef process_is_alive(name_pattern):
1009a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    """
1010a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    'pgrep name' misses all python processes and also long process names.
1011a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    'pgrep -f name' gets all shell commands with name in args.
1012e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mbligh    So look only for command whose initial pathname ends with name.
1013e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mbligh    Name itself is an egrep pattern, so it can use | etc for variations.
1014a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh    """
1015e6bc5b9ab0fdd65f131948143ee2eb97e1352d74mbligh    return utils.system("pgrep -f '^([^ /]*/)*(%s)([ ]|$)'" % name_pattern,
1016a3c17fc206d34ae196e8d3df4eb99a3ccd249136mbligh                        ignore_status=True) == 0
101788f602c1cfa54a0085737817a1a477c833e10837mbligh
101888f602c1cfa54a0085737817a1a477c833e10837mbligh
1019a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef get_hwclock_seconds(utc=True):
1020a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1021a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Return the hardware clock in seconds as a floating point value.
1022a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Use Coordinated Universal Time if utc is True, local time otherwise.
1023a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Raise a ValueError if unable to read the hardware clock.
1024a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1025a82dc35ef721720e73db887d895bbd5cb835291cEric Li    cmd = '/sbin/hwclock --debug'
1026a82dc35ef721720e73db887d895bbd5cb835291cEric Li    if utc:
1027a82dc35ef721720e73db887d895bbd5cb835291cEric Li        cmd += ' --utc'
1028a82dc35ef721720e73db887d895bbd5cb835291cEric Li    hwclock_output = utils.system_output(cmd, ignore_status=True)
1029a82dc35ef721720e73db887d895bbd5cb835291cEric Li    match = re.search(r'= ([0-9]+) seconds since .+ (-?[0-9.]+) seconds$',
1030a82dc35ef721720e73db887d895bbd5cb835291cEric Li                      hwclock_output, re.DOTALL)
1031a82dc35ef721720e73db887d895bbd5cb835291cEric Li    if match:
1032a82dc35ef721720e73db887d895bbd5cb835291cEric Li        seconds = int(match.group(1)) + float(match.group(2))
1033f278e8591fdcee2bad05416c0a6d30f31e08598bDaniel Kurtz        logging.debug('hwclock seconds = %f', seconds)
1034a82dc35ef721720e73db887d895bbd5cb835291cEric Li        return seconds
1035a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1036a82dc35ef721720e73db887d895bbd5cb835291cEric Li    raise ValueError('Unable to read the hardware clock -- ' +
1037a82dc35ef721720e73db887d895bbd5cb835291cEric Li                     hwclock_output)
1038a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1039a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1040a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef set_wake_alarm(alarm_time):
1041a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1042a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Set the hardware RTC-based wake alarm to 'alarm_time'.
1043a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1044a82dc35ef721720e73db887d895bbd5cb835291cEric Li    utils.write_one_line('/sys/class/rtc/rtc0/wakealarm', str(alarm_time))
1045a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1046a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1047a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef set_power_state(state):
1048a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1049a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Set the system power state to 'state'.
1050a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1051a82dc35ef721720e73db887d895bbd5cb835291cEric Li    utils.write_one_line('/sys/power/state', state)
1052a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1053a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1054a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef standby():
1055a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1056a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Power-on suspend (S1)
1057a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1058a82dc35ef721720e73db887d895bbd5cb835291cEric Li    set_power_state('standby')
1059a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1060a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1061a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef suspend_to_ram():
1062a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1063a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Suspend the system to RAM (S3)
1064a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1065a82dc35ef721720e73db887d895bbd5cb835291cEric Li    set_power_state('mem')
1066a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1067a82dc35ef721720e73db887d895bbd5cb835291cEric Li
1068a82dc35ef721720e73db887d895bbd5cb835291cEric Lidef suspend_to_disk():
1069a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1070a82dc35ef721720e73db887d895bbd5cb835291cEric Li    Suspend the system to disk (S4)
1071a82dc35ef721720e73db887d895bbd5cb835291cEric Li    """
1072a82dc35ef721720e73db887d895bbd5cb835291cEric Li    set_power_state('disk')
1073