blob: 5384bdb806957d13d93a2408f445b2230edcd8f9 [file] [log] [blame]
mblighc86b0b42006-07-28 17:35:28 +00001"""
mbligh2da4d882009-01-21 19:05:40 +00002DO NOT import this file directly - import client/bin/utils.py,
3which will mix this in
4
mbligh53da18e2009-01-05 21:13:26 +00005Convenience functions for use by tests or whomever.
mblighc86b0b42006-07-28 17:35:28 +00006
mbligh2da4d882009-01-21 19:05:40 +00007Note that this file is mixed in by utils.py - note very carefully the
8precedence order defined there
mbligh53da18e2009-01-05 21:13:26 +00009"""
Daniel Kurtzf278e852014-03-04 21:57:30 -080010import os, shutil, commands, pickle, glob
11import math, re, fnmatch, logging, multiprocessing
lmr959e8162010-04-16 06:15:34 +000012from autotest_lib.client.common_lib import error, utils, magic
mblighea397bb2008-02-02 19:17:51 +000013
14
mblighf4c35322006-03-13 01:01:10 +000015def grep(pattern, file):
jadmanski0afbb632008-06-06 21:10:57 +000016 """
17 This is mainly to fix the return code inversion from grep
18 Also handles compressed files.
mbligh7bdbfbd2006-09-30 16:47:01 +000019
jadmanski0afbb632008-06-06 21:10:57 +000020 returns 1 if the pattern is present in the file, 0 if not.
21 """
22 command = 'grep "%s" > /dev/null' % pattern
23 ret = cat_file_to_cmd(file, command, ignore_status=True)
24 return not ret
mblighaf4efc22008-01-25 16:33:59 +000025
26
mblighc86b0b42006-07-28 17:35:28 +000027def difflist(list1, list2):
jadmanski0afbb632008-06-06 21:10:57 +000028 """returns items in list2 that are not in list1"""
29 diff = [];
30 for x in list2:
31 if x not in list1:
32 diff.append(x)
33 return diff
mblighf4c35322006-03-13 01:01:10 +000034
mblighc86b0b42006-07-28 17:35:28 +000035
mbligh8ea61e22008-05-09 18:09:37 +000036def cat_file_to_cmd(file, command, ignore_status=0, return_output=False):
jadmanski0afbb632008-06-06 21:10:57 +000037 """
38 equivalent to 'cat file | command' but knows to use
39 zcat or bzcat if appropriate
40 """
mblighf2fa4712008-09-10 20:36:29 +000041 if not os.path.isfile(file):
42 raise NameError('invalid file %s to cat to command %s'
43 % (file, command))
44
jadmanski0afbb632008-06-06 21:10:57 +000045 if return_output:
mbligh2da4d882009-01-21 19:05:40 +000046 run_cmd = utils.system_output
jadmanski0afbb632008-06-06 21:10:57 +000047 else:
mbligh2da4d882009-01-21 19:05:40 +000048 run_cmd = utils.system
mbligh96ffb9b2008-03-28 14:35:42 +000049
lmr959e8162010-04-16 06:15:34 +000050 if magic.guess_type(file) == 'application/x-bzip2':
mblighf2fa4712008-09-10 20:36:29 +000051 cat = 'bzcat'
lmr959e8162010-04-16 06:15:34 +000052 elif magic.guess_type(file) == 'application/x-gzip':
mblighf2fa4712008-09-10 20:36:29 +000053 cat = 'zcat'
jadmanski0afbb632008-06-06 21:10:57 +000054 else:
mblighf2fa4712008-09-10 20:36:29 +000055 cat = 'cat'
56 return run_cmd('%s %s | %s' % (cat, file, command),
57 ignore_status=ignore_status)
mblighf4c35322006-03-13 01:01:10 +000058
mblighc86b0b42006-07-28 17:35:28 +000059
mbligh712cd142006-04-22 18:57:50 +000060def extract_tarball_to_dir(tarball, dir):
jadmanski0afbb632008-06-06 21:10:57 +000061 """
62 Extract a tarball to a specified directory name instead of whatever
63 the top level of a tarball is - useful for versioned directory names, etc
64 """
65 if os.path.exists(dir):
lmr959e8162010-04-16 06:15:34 +000066 if os.path.isdir(dir):
67 shutil.rmtree(dir)
68 else:
69 os.remove(dir)
jadmanski0afbb632008-06-06 21:10:57 +000070 pwd = os.getcwd()
71 os.chdir(os.path.dirname(os.path.abspath(dir)))
72 newdir = extract_tarball(tarball)
73 os.rename(newdir, dir)
74 os.chdir(pwd)
mbligh712cd142006-04-22 18:57:50 +000075
76
mbligh712cd142006-04-22 18:57:50 +000077def extract_tarball(tarball):
jadmanski0afbb632008-06-06 21:10:57 +000078 """Returns the directory extracted by the tarball."""
79 extracted = cat_file_to_cmd(tarball, 'tar xvf - 2>/dev/null',
80 return_output=True).splitlines()
mbligh5d423ca2008-04-16 23:06:12 +000081
jadmanski0afbb632008-06-06 21:10:57 +000082 dir = None
mbligh5d423ca2008-04-16 23:06:12 +000083
jadmanski0afbb632008-06-06 21:10:57 +000084 for line in extracted:
85 line = re.sub(r'^./', '', line)
86 if not line or line == '.':
87 continue
88 topdir = line.split('/')[0]
89 if os.path.isdir(topdir):
90 if dir:
91 assert(dir == topdir)
92 else:
93 dir = topdir
94 if dir:
95 return dir
96 else:
97 raise NameError('extracting tarball produced no dir')
mbligh712cd142006-04-22 18:57:50 +000098
mblighcdf02a42006-04-23 02:22:49 +000099
lmrd60882f2010-02-04 03:26:36 +0000100def hash_file(filename, size=None, method="md5"):
101 """
102 Calculate the hash of filename.
103 If size is not None, limit to first size bytes.
104 Throw exception if something is wrong with filename.
105 Can be also implemented with bash one-liner (assuming size%1024==0):
106 dd if=filename bs=1024 count=size/1024 | sha1sum -
107
108 @param filename: Path of the file that will have its hash calculated.
109 @param method: Method used to calculate the hash. Supported methods:
110 * md5
111 * sha1
112 @returns: Hash of the file, if something goes wrong, return None.
113 """
114 chunksize = 4096
115 fsize = os.path.getsize(filename)
116
117 if not size or size > fsize:
118 size = fsize
119 f = open(filename, 'rb')
120
121 try:
122 hash = utils.hash(method)
123 except ValueError:
Daniel Kurtzf278e852014-03-04 21:57:30 -0800124 logging.error("Unknown hash type %s, returning None", method)
lmrd60882f2010-02-04 03:26:36 +0000125
126 while size > 0:
127 if chunksize > size:
128 chunksize = size
129 data = f.read(chunksize)
130 if len(data) == 0:
Daniel Kurtzf278e852014-03-04 21:57:30 -0800131 logging.debug("Nothing left to read but size=%d", size)
lmrd60882f2010-02-04 03:26:36 +0000132 break
133 hash.update(data)
134 size -= len(data)
135 f.close()
136 return hash.hexdigest()
mbligh60418bb2008-01-03 01:55:09 +0000137
138
lmrd60882f2010-02-04 03:26:36 +0000139def unmap_url_cache(cachedir, url, expected_hash, method="md5"):
mbligh53da18e2009-01-05 21:13:26 +0000140 """
jadmanski0afbb632008-06-06 21:10:57 +0000141 Downloads a file from a URL to a cache directory. If the file is already
lmrd60882f2010-02-04 03:26:36 +0000142 at the expected position and has the expected hash, let's not download it
143 again.
144
145 @param cachedir: Directory that might hold a copy of the file we want to
146 download.
147 @param url: URL for the file we want to download.
148 @param expected_hash: Hash string that we expect the file downloaded to
149 have.
150 @param method: Method used to calculate the hash string (md5, sha1).
jadmanski0afbb632008-06-06 21:10:57 +0000151 """
152 # Let's convert cachedir to a canonical path, if it's not already
153 cachedir = os.path.realpath(cachedir)
154 if not os.path.isdir(cachedir):
155 try:
lmrd60882f2010-02-04 03:26:36 +0000156 os.makedirs(cachedir)
jadmanski0afbb632008-06-06 21:10:57 +0000157 except:
158 raise ValueError('Could not create cache directory %s' % cachedir)
159 file_from_url = os.path.basename(url)
160 file_local_path = os.path.join(cachedir, file_from_url)
lmrd60882f2010-02-04 03:26:36 +0000161
162 file_hash = None
163 failure_counter = 0
164 while not file_hash == expected_hash:
165 if os.path.isfile(file_local_path):
166 file_hash = hash_file(file_local_path, method)
167 if file_hash == expected_hash:
168 # File is already at the expected position and ready to go
169 src = file_from_url
170 else:
171 # Let's download the package again, it's corrupted...
172 logging.error("Seems that file %s is corrupted, trying to "
Daniel Kurtzf278e852014-03-04 21:57:30 -0800173 "download it again", file_from_url)
lmrd60882f2010-02-04 03:26:36 +0000174 src = url
175 failure_counter += 1
jadmanski0afbb632008-06-06 21:10:57 +0000176 else:
lmrd60882f2010-02-04 03:26:36 +0000177 # File is not there, let's download it
jadmanski0afbb632008-06-06 21:10:57 +0000178 src = url
lmrd60882f2010-02-04 03:26:36 +0000179 if failure_counter > 1:
180 raise EnvironmentError("Consistently failed to download the "
181 "package %s. Aborting further download "
182 "attempts. This might mean either the "
183 "network connection has problems or the "
184 "expected hash string that was determined "
Daniel Kurtzf278e852014-03-04 21:57:30 -0800185 "for this file is wrong", file_from_url)
lmrd60882f2010-02-04 03:26:36 +0000186 file_path = utils.unmap_url(cachedir, src, cachedir)
187
188 return file_path
mblighea30c8a2006-04-22 22:24:25 +0000189
190
mblighf4c35322006-03-13 01:01:10 +0000191def force_copy(src, dest):
jadmanski0afbb632008-06-06 21:10:57 +0000192 """Replace dest with a new copy of src, even if it exists"""
193 if os.path.isfile(dest):
194 os.remove(dest)
195 if os.path.isdir(dest):
196 dest = os.path.join(dest, os.path.basename(src))
197 shutil.copyfile(src, dest)
198 return dest
mblighf4c35322006-03-13 01:01:10 +0000199
200
mblighfdbcaec2006-10-01 23:28:57 +0000201def force_link(src, dest):
jadmanski0afbb632008-06-06 21:10:57 +0000202 """Link src to dest, overwriting it if it exists"""
mbligh2da4d882009-01-21 19:05:40 +0000203 return utils.system("ln -sf %s %s" % (src, dest))
mblighfdbcaec2006-10-01 23:28:57 +0000204
205
mblighcdf02a42006-04-23 02:22:49 +0000206def file_contains_pattern(file, pattern):
jadmanski0afbb632008-06-06 21:10:57 +0000207 """Return true if file contains the specified egrep pattern"""
208 if not os.path.isfile(file):
209 raise NameError('file %s does not exist' % file)
mbligh2da4d882009-01-21 19:05:40 +0000210 return not utils.system('egrep -q "' + pattern + '" ' + file, ignore_status=True)
mblighcdf02a42006-04-23 02:22:49 +0000211
212
213def list_grep(list, pattern):
jadmanski0afbb632008-06-06 21:10:57 +0000214 """True if any item in list matches the specified pattern."""
215 compiled = re.compile(pattern)
216 for line in list:
217 match = compiled.search(line)
218 if (match):
219 return 1
220 return 0
mblighcdf02a42006-04-23 02:22:49 +0000221
mbligh987071e2008-06-13 16:39:12 +0000222
mbligh42b81ca2006-09-30 22:10:01 +0000223def get_os_vendor():
jadmanski0afbb632008-06-06 21:10:57 +0000224 """Try to guess what's the os vendor
225 """
mbligh90b97ff2009-03-10 20:29:01 +0000226 if os.path.isfile('/etc/SuSE-release'):
227 return 'SUSE'
228
jadmanski0afbb632008-06-06 21:10:57 +0000229 issue = '/etc/issue'
mblighaf4efc22008-01-25 16:33:59 +0000230
jadmanski0afbb632008-06-06 21:10:57 +0000231 if not os.path.isfile(issue):
232 return 'Unknown'
mblighaf4efc22008-01-25 16:33:59 +0000233
jadmanski0afbb632008-06-06 21:10:57 +0000234 if file_contains_pattern(issue, 'Red Hat'):
235 return 'Red Hat'
mbligh2f29c192009-01-12 20:39:17 +0000236 elif file_contains_pattern(issue, 'Fedora'):
jadmanski0afbb632008-06-06 21:10:57 +0000237 return 'Fedora Core'
238 elif file_contains_pattern(issue, 'SUSE'):
239 return 'SUSE'
240 elif file_contains_pattern(issue, 'Ubuntu'):
241 return 'Ubuntu'
242 elif file_contains_pattern(issue, 'Debian'):
243 return 'Debian'
244 else:
245 return 'Unknown'
mblighaf4efc22008-01-25 16:33:59 +0000246
mblighcdf02a42006-04-23 02:22:49 +0000247
Eric Li8a12e802011-02-17 14:24:13 -0800248def get_cc():
249 try:
250 return os.environ['CC']
251 except KeyError:
252 return 'gcc'
253
254
mblighf49d5cf2006-04-23 02:24:42 +0000255def get_vmlinux():
jadmanski0afbb632008-06-06 21:10:57 +0000256 """Return the full path to vmlinux
mblighc86b0b42006-07-28 17:35:28 +0000257
jadmanski0afbb632008-06-06 21:10:57 +0000258 Ahem. This is crap. Pray harder. Bad Martin.
259 """
mbligh2da4d882009-01-21 19:05:40 +0000260 vmlinux = '/boot/vmlinux-%s' % utils.system_output('uname -r')
jadmanski0afbb632008-06-06 21:10:57 +0000261 if os.path.isfile(vmlinux):
262 return vmlinux
mbligh2da4d882009-01-21 19:05:40 +0000263 vmlinux = '/lib/modules/%s/build/vmlinux' % utils.system_output('uname -r')
jadmanski0afbb632008-06-06 21:10:57 +0000264 if os.path.isfile(vmlinux):
265 return vmlinux
266 return None
mblighf49d5cf2006-04-23 02:24:42 +0000267
268
269def get_systemmap():
jadmanski0afbb632008-06-06 21:10:57 +0000270 """Return the full path to System.map
mblighc86b0b42006-07-28 17:35:28 +0000271
jadmanski0afbb632008-06-06 21:10:57 +0000272 Ahem. This is crap. Pray harder. Bad Martin.
273 """
mbligh2da4d882009-01-21 19:05:40 +0000274 map = '/boot/System.map-%s' % utils.system_output('uname -r')
jadmanski0afbb632008-06-06 21:10:57 +0000275 if os.path.isfile(map):
276 return map
mbligh2da4d882009-01-21 19:05:40 +0000277 map = '/lib/modules/%s/build/System.map' % utils.system_output('uname -r')
jadmanski0afbb632008-06-06 21:10:57 +0000278 if os.path.isfile(map):
279 return map
280 return None
mbligh67b5ece2006-04-23 02:53:12 +0000281
282
283def get_modules_dir():
jadmanski0afbb632008-06-06 21:10:57 +0000284 """Return the modules dir for the running kernel version"""
mbligh2da4d882009-01-21 19:05:40 +0000285 kernel_version = utils.system_output('uname -r')
jadmanski0afbb632008-06-06 21:10:57 +0000286 return '/lib/modules/%s/kernel' % kernel_version
mblighf49d5cf2006-04-23 02:24:42 +0000287
288
David Sharpeb5e7a32014-10-29 15:44:39 -0700289_CPUINFO_RE = re.compile(r'^(?P<key>[^\t]*)\t*: ?(?P<value>.*)$')
290
David Sharpf9483792015-03-06 13:56:39 -0800291
David Sharpeb5e7a32014-10-29 15:44:39 -0700292def get_cpuinfo():
293 """Read /proc/cpuinfo and convert to a list of dicts."""
294 cpuinfo = []
295 with open('/proc/cpuinfo', 'r') as f:
296 cpu = {}
297 for line in f:
298 line = line.strip()
299 if not line:
300 cpuinfo.append(cpu)
301 cpu = {}
302 continue
303 match = _CPUINFO_RE.match(line)
304 cpu[match.group('key')] = match.group('value')
305 if cpu:
306 # cpuinfo usually ends in a blank line, so this shouldn't happen.
307 cpuinfo.append(cpu)
308 return cpuinfo
309
David Sharpf9483792015-03-06 13:56:39 -0800310
mbligh5970cf02006-08-06 15:39:22 +0000311def get_cpu_arch():
jadmanski0afbb632008-06-06 21:10:57 +0000312 """Work out which CPU architecture we're running on"""
313 f = open('/proc/cpuinfo', 'r')
314 cpuinfo = f.readlines()
315 f.close()
316 if list_grep(cpuinfo, '^cpu.*(RS64|POWER3|Broadband Engine)'):
317 return 'power'
318 elif list_grep(cpuinfo, '^cpu.*POWER4'):
319 return 'power4'
320 elif list_grep(cpuinfo, '^cpu.*POWER5'):
321 return 'power5'
322 elif list_grep(cpuinfo, '^cpu.*POWER6'):
323 return 'power6'
mbligh0758c822009-09-18 19:37:35 +0000324 elif list_grep(cpuinfo, '^cpu.*POWER7'):
325 return 'power7'
jadmanski0afbb632008-06-06 21:10:57 +0000326 elif list_grep(cpuinfo, '^cpu.*PPC970'):
327 return 'power970'
mblighf23fd922010-02-25 18:45:45 +0000328 elif list_grep(cpuinfo, 'ARM'):
329 return 'arm'
mbligh12e8b892008-09-08 21:39:41 +0000330 elif list_grep(cpuinfo, '^flags.*:.* lm .*'):
jadmanski0afbb632008-06-06 21:10:57 +0000331 return 'x86_64'
332 else:
333 return 'i386'
mblighf4c35322006-03-13 01:01:10 +0000334
David Sharpf9483792015-03-06 13:56:39 -0800335
Daniel Kurtz7c6ee782014-03-03 18:14:33 -0800336def get_arm_soc_family():
337 """Work out which ARM SoC we're running on"""
338 f = open('/proc/cpuinfo', 'r')
339 cpuinfo = f.readlines()
340 f.close()
341 if list_grep(cpuinfo, 'EXYNOS5'):
342 return 'exynos5'
343 elif list_grep(cpuinfo, 'Tegra'):
344 return 'tegra'
ZhengShunQianaec3bf52014-09-24 15:14:41 +0800345 elif list_grep(cpuinfo, 'Rockchip'):
346 return 'rockchip'
Daniel Kurtz7c6ee782014-03-03 18:14:33 -0800347 return 'arm'
348
David Sharpf9483792015-03-06 13:56:39 -0800349
Daniel Kurtz17113742014-03-05 14:10:03 -0800350def get_cpu_soc_family():
Daniel Kurtz7c6ee782014-03-03 18:14:33 -0800351 """Like get_cpu_arch, but for ARM, returns the SoC family name"""
352 family = get_cpu_arch()
353 if family == 'arm':
354 family = get_arm_soc_family()
355 return family
mblighf4c35322006-03-13 01:01:10 +0000356
David Sharpf9483792015-03-06 13:56:39 -0800357
David Sharpeb5e7a32014-10-29 15:44:39 -0700358INTEL_UARCH_TABLE = {
359 '06_36': 'Atom',
360 '06_26': 'Atom',
361 '06_1C': 'Atom',
362 '06_3D': 'Broadwell',
363 '06_3F': 'Haswell',
364 '06_3C': 'Haswell',
365 '06_46': 'Haswell',
366 '06_45': 'Haswell',
367 '06_3E': 'IvyBridge',
368 '06_3A': 'IvyBridge',
369 '06_2D': 'SandyBridge',
370 '06_2A': 'SandyBridge',
371 '06_2F': 'Westmere',
372 '06_2C': 'Westmere',
373 '06_25': 'Westmere',
374 '06_2E': 'Nehalem',
375 '06_1F': 'Nehalem',
376 '06_1E': 'Nehalem',
377 '06_1D': 'Nehalem',
378 '06_1A': 'Nehalem',
379 '06_17': 'Nehalem',
380 '06_16': 'Merom',
381 '06_0F': 'Merom',
382 '0F_06': 'Presler',
383 '0F_04': 'Prescott',
384 '0F_03': 'Prescott',
385 '06_0D': 'Dothan',
386}
387
David Sharpf9483792015-03-06 13:56:39 -0800388
David Sharpeb5e7a32014-10-29 15:44:39 -0700389def get_intel_cpu_uarch(numeric=False):
390 """Return the Intel microarchitecture we're running on, or None.
391
392 Returns None if this is not an Intel CPU. Returns the family and model as
393 underscore-separated hex (per Intel manual convention) if the uarch is not
394 known, or if numeric is True.
395 """
396 if not get_current_kernel_arch().startswith('x86'):
397 return None
398 cpuinfo = get_cpuinfo()[0]
399 if cpuinfo['vendor_id'] != 'GenuineIntel':
400 return None
401 family_model = '%02X_%02X' % (int(cpuinfo['cpu family']),
402 int(cpuinfo['model']))
403 if numeric:
404 return family_model
405 return INTEL_UARCH_TABLE.get(family_model, family_model)
406
407
mbligh548f29a2006-10-17 04:55:12 +0000408def get_current_kernel_arch():
jadmanski0afbb632008-06-06 21:10:57 +0000409 """Get the machine architecture, now just a wrap of 'uname -m'."""
410 return os.popen('uname -m').read().rstrip()
mblighcdf02a42006-04-23 02:22:49 +0000411
412
mblighfdbcaec2006-10-01 23:28:57 +0000413def get_file_arch(filename):
jadmanski0afbb632008-06-06 21:10:57 +0000414 # -L means follow symlinks
mbligh2da4d882009-01-21 19:05:40 +0000415 file_data = utils.system_output('file -L ' + filename)
jadmanski0afbb632008-06-06 21:10:57 +0000416 if file_data.count('80386'):
417 return 'i386'
418 return None
mblighfdbcaec2006-10-01 23:28:57 +0000419
420
mblighf4c35322006-03-13 01:01:10 +0000421def count_cpus():
jadmanski0afbb632008-06-06 21:10:57 +0000422 """number of CPUs in the local machine according to /proc/cpuinfo"""
cychiang46589b12012-10-03 11:19:33 +0800423 try:
424 return multiprocessing.cpu_count()
425 except Exception as e:
426 logging.exception('can not get cpu count from'
427 ' multiprocessing.cpu_count()')
David Sharpf9483792015-03-06 13:56:39 -0800428 cpuinfo = get_cpuinfo()
cychiang46589b12012-10-03 11:19:33 +0800429 # Returns at least one cpu. Check comment #1 in crosbug.com/p/9582.
David Sharpf9483792015-03-06 13:56:39 -0800430 return len(cpuinfo) or 1
431
432
433def cpu_online_map():
434 """
435 Check out the available cpu online map
436 """
437 cpuinfo = get_cpuinfo()
438 cpus = []
439 for cpu in cpuinfo:
440 cpus.append(cpu['processor']) # grab cpu number
441 return cpus
442
443
444def get_cpu_family():
445 cpuinfo = get_cpuinfo()[0]
446 return int(cpuinfo['cpu_family'])
447
448
449def get_cpu_vendor():
450 cpuinfo = get_cpuinfo()
451 vendors = [cpu['vendor_id'] for cpu in cpuinfo]
452 for v in vendors[1:]:
453 if v != vendors[0]:
454 raise error.TestError('multiple cpu vendors found: ' + str(vendors))
455 return vendors[0]
456
457
458def probe_cpus():
459 """
460 This routine returns a list of cpu devices found under
461 /sys/devices/system/cpu.
462 """
463 cmd = 'find /sys/devices/system/cpu/ -maxdepth 1 -type d -name cpu*'
464 return utils.system_output(cmd).splitlines()
mblighf4c35322006-03-13 01:01:10 +0000465
mblighe7a170f2006-12-05 07:48:18 +0000466
467# Returns total memory in kb
mbligh558885e2008-04-01 20:41:38 +0000468def read_from_meminfo(key):
mbligh2da4d882009-01-21 19:05:40 +0000469 meminfo = utils.system_output('grep %s /proc/meminfo' % key)
jadmanski0afbb632008-06-06 21:10:57 +0000470 return int(re.search(r'\d+', meminfo).group(0))
mbligh558885e2008-04-01 20:41:38 +0000471
472
mblighe7a170f2006-12-05 07:48:18 +0000473def memtotal():
jadmanski0afbb632008-06-06 21:10:57 +0000474 return read_from_meminfo('MemTotal')
mbligh558885e2008-04-01 20:41:38 +0000475
476
477def freememtotal():
jadmanski0afbb632008-06-06 21:10:57 +0000478 return read_from_meminfo('MemFree')
mbligh558885e2008-04-01 20:41:38 +0000479
Puthikorn Voravootivatb7f4c2e2014-04-03 11:03:39 -0700480def usable_memtotal():
Puthikorn Voravootivatdca8dc62014-08-11 10:44:57 -0700481 # Reserved 5% for OS use
482 return int(read_from_meminfo('MemFree') * 0.95)
Puthikorn Voravootivatb7f4c2e2014-04-03 11:03:39 -0700483
mbligh558885e2008-04-01 20:41:38 +0000484
mbligh8493be42008-11-20 00:55:11 +0000485def rounded_memtotal():
mbligh53da18e2009-01-05 21:13:26 +0000486 # Get total of all physical mem, in kbytes
487 usable_kbytes = memtotal()
488 # usable_kbytes is system's usable DRAM in kbytes,
mbligh8493be42008-11-20 00:55:11 +0000489 # as reported by memtotal() from device /proc/meminfo memtotal
490 # after Linux deducts 1.5% to 5.1% for system table overhead
491 # Undo the unknown actual deduction by rounding up
492 # to next small multiple of a big power-of-two
493 # eg 12GB - 5.1% gets rounded back up to 12GB
494 mindeduct = 0.015 # 1.5 percent
495 maxdeduct = 0.055 # 5.5 percent
496 # deduction range 1.5% .. 5.5% supports physical mem sizes
497 # 6GB .. 12GB in steps of .5GB
498 # 12GB .. 24GB in steps of 1 GB
499 # 24GB .. 48GB in steps of 2 GB ...
500 # Finer granularity in physical mem sizes would require
501 # tighter spread between min and max possible deductions
502
503 # increase mem size by at least min deduction, without rounding
Puthikorn Voravootivatb7f4c2e2014-04-03 11:03:39 -0700504 min_kbytes = int(usable_kbytes / (1.0 - mindeduct))
mbligh8493be42008-11-20 00:55:11 +0000505 # increase mem size further by 2**n rounding, by 0..roundKb or more
mbligh53da18e2009-01-05 21:13:26 +0000506 round_kbytes = int(usable_kbytes / (1.0 - maxdeduct)) - min_kbytes
mbligh8493be42008-11-20 00:55:11 +0000507 # find least binary roundup 2**n that covers worst-cast roundKb
mbligh53da18e2009-01-05 21:13:26 +0000508 mod2n = 1 << int(math.ceil(math.log(round_kbytes, 2)))
509 # have round_kbytes <= mod2n < round_kbytes*2
510 # round min_kbytes up to next multiple of mod2n
511 phys_kbytes = min_kbytes + mod2n - 1
512 phys_kbytes = phys_kbytes - (phys_kbytes % mod2n) # clear low bits
513 return phys_kbytes
mbligh8493be42008-11-20 00:55:11 +0000514
515
jadmanskif4325162010-04-09 16:04:54 +0000516def sysctl(key, value=None):
517 """Generic implementation of sysctl, to read and write.
518
519 @param key: A location under /proc/sys
520 @param value: If not None, a value to write into the sysctl.
521
522 @return The single-line sysctl value as a string.
523 """
524 path = '/proc/sys/%s' % key
525 if value is not None:
526 utils.write_one_line(path, str(value))
527 return utils.read_one_line(path)
528
529
mbligh558885e2008-04-01 20:41:38 +0000530def sysctl_kernel(key, value=None):
jadmanski0afbb632008-06-06 21:10:57 +0000531 """(Very) partial implementation of sysctl, for kernel params"""
jadmanskif4325162010-04-09 16:04:54 +0000532 if value is not None:
jadmanski0afbb632008-06-06 21:10:57 +0000533 # write
mbligh2da4d882009-01-21 19:05:40 +0000534 utils.write_one_line('/proc/sys/kernel/%s' % key, str(value))
jadmanski0afbb632008-06-06 21:10:57 +0000535 else:
536 # read
mbligh2da4d882009-01-21 19:05:40 +0000537 out = utils.read_one_line('/proc/sys/kernel/%s' % key)
jadmanski0afbb632008-06-06 21:10:57 +0000538 return int(re.search(r'\d+', out).group(0))
mblighe7a170f2006-12-05 07:48:18 +0000539
540
mbligh5285a2d2008-03-10 20:28:08 +0000541def _convert_exit_status(sts):
jadmanski0afbb632008-06-06 21:10:57 +0000542 if os.WIFSIGNALED(sts):
543 return -os.WTERMSIG(sts)
544 elif os.WIFEXITED(sts):
545 return os.WEXITSTATUS(sts)
546 else:
547 # impossible?
548 raise RuntimeError("Unknown exit status %d!" % sts)
mbligh5285a2d2008-03-10 20:28:08 +0000549
550
mblighf4c35322006-03-13 01:01:10 +0000551def where_art_thy_filehandles():
jadmanski0afbb632008-06-06 21:10:57 +0000552 """Dump the current list of filehandles"""
553 os.system("ls -l /proc/%d/fd >> /dev/tty" % os.getpid())
mblighf4c35322006-03-13 01:01:10 +0000554
555
556def print_to_tty(string):
jadmanski0afbb632008-06-06 21:10:57 +0000557 """Output string straight to the tty"""
558 open('/dev/tty', 'w').write(string + '\n')
mblighf4c35322006-03-13 01:01:10 +0000559
560
mblighb8a14e32006-05-06 00:17:35 +0000561def dump_object(object):
jadmanski0afbb632008-06-06 21:10:57 +0000562 """Dump an object's attributes and methods
mblighc86b0b42006-07-28 17:35:28 +0000563
jadmanski0afbb632008-06-06 21:10:57 +0000564 kind of like dir()
565 """
566 for item in object.__dict__.iteritems():
567 print item
568 try:
Puthikorn Voravootivatb7f4c2e2014-04-03 11:03:39 -0700569 (key, value) = item
jadmanski0afbb632008-06-06 21:10:57 +0000570 dump_object(value)
571 except:
572 continue
mblighb8a14e32006-05-06 00:17:35 +0000573
574
mbligh4b089662006-06-14 22:34:58 +0000575def environ(env_key):
jadmanski0afbb632008-06-06 21:10:57 +0000576 """return the requested environment variable, or '' if unset"""
577 if (os.environ.has_key(env_key)):
578 return os.environ[env_key]
579 else:
580 return ''
mbligh4b089662006-06-14 22:34:58 +0000581
582
583def prepend_path(newpath, oldpath):
jadmanski0afbb632008-06-06 21:10:57 +0000584 """prepend newpath to oldpath"""
585 if (oldpath):
586 return newpath + ':' + oldpath
587 else:
588 return newpath
mbligh4b089662006-06-14 22:34:58 +0000589
590
591def append_path(oldpath, newpath):
jadmanski0afbb632008-06-06 21:10:57 +0000592 """append newpath to oldpath"""
593 if (oldpath):
594 return oldpath + ':' + newpath
595 else:
596 return newpath
mbligh4b089662006-06-14 22:34:58 +0000597
598
mbligh4e75b0d2006-08-29 15:22:44 +0000599def avgtime_print(dir):
jadmanski0afbb632008-06-06 21:10:57 +0000600 """ Calculate some benchmarking statistics.
601 Input is a directory containing a file called 'time'.
602 File contains one-per-line results of /usr/bin/time.
603 Output is average Elapsed, User, and System time in seconds,
604 and average CPU percentage.
605 """
606 f = open(dir + "/time")
607 user = system = elapsed = cpu = count = 0
608 r = re.compile('([\d\.]*)user ([\d\.]*)system (\d*):([\d\.]*)elapsed (\d*)%CPU')
609 for line in f.readlines():
610 try:
611 s = r.match(line);
612 user += float(s.group(1))
613 system += float(s.group(2))
614 elapsed += (float(s.group(3)) * 60) + float(s.group(4))
615 cpu += float(s.group(5))
616 count += 1
617 except:
618 raise ValueError("badly formatted times")
mblighaf4efc22008-01-25 16:33:59 +0000619
jadmanski0afbb632008-06-06 21:10:57 +0000620 f.close()
621 return "Elapsed: %0.2fs User: %0.2fs System: %0.2fs CPU: %0.0f%%" % \
Puthikorn Voravootivatb7f4c2e2014-04-03 11:03:39 -0700622 (elapsed / count, user / count, system / count, cpu / count)
mbligh4e75b0d2006-08-29 15:22:44 +0000623
624
mblighf06db0f2006-09-30 17:08:43 +0000625def running_config():
jadmanski0afbb632008-06-06 21:10:57 +0000626 """
627 Return path of config file of the currently running kernel
628 """
mbligh2da4d882009-01-21 19:05:40 +0000629 version = utils.system_output('uname -r')
jadmanski0afbb632008-06-06 21:10:57 +0000630 for config in ('/proc/config.gz', \
631 '/boot/config-%s' % version,
632 '/lib/modules/%s/build/.config' % version):
633 if os.path.isfile(config):
634 return config
635 return None
mbligh9ec8acc2006-10-05 06:52:33 +0000636
637
mbligha1bef1f2007-04-03 17:18:07 +0000638def check_for_kernel_feature(feature):
jadmanski0afbb632008-06-06 21:10:57 +0000639 config = running_config()
mbligha1bef1f2007-04-03 17:18:07 +0000640
jadmanski0afbb632008-06-06 21:10:57 +0000641 if not config:
642 raise TypeError("Can't find kernel config file")
mbligha1bef1f2007-04-03 17:18:07 +0000643
lmr959e8162010-04-16 06:15:34 +0000644 if magic.guess_type(config) == 'application/x-gzip':
jadmanski0afbb632008-06-06 21:10:57 +0000645 grep = 'zgrep'
646 else:
647 grep = 'grep'
648 grep += ' ^CONFIG_%s= %s' % (feature, config)
mbligha1bef1f2007-04-03 17:18:07 +0000649
mbligh2da4d882009-01-21 19:05:40 +0000650 if not utils.system_output(grep, ignore_status=True):
jadmanski0afbb632008-06-06 21:10:57 +0000651 raise ValueError("Kernel doesn't have a %s feature" % (feature))
mbligha1bef1f2007-04-03 17:18:07 +0000652
653
mbligh663e4f62006-10-11 05:03:40 +0000654def check_glibc_ver(ver):
jadmanski0afbb632008-06-06 21:10:57 +0000655 glibc_ver = commands.getoutput('ldd --version').splitlines()[0]
656 glibc_ver = re.search(r'(\d+\.\d+(\.\d+)?)', glibc_ver).group()
lmr0fab1e92010-05-21 18:25:36 +0000657 if utils.compare_versions(glibc_ver, ver) == -1:
658 raise error.TestError("Glibc too old (%s). Glibc >= %s is needed." %
659 (glibc_ver, ver))
mbligh07635222007-07-09 21:29:00 +0000660
661def check_kernel_ver(ver):
mbligh2da4d882009-01-21 19:05:40 +0000662 kernel_ver = utils.system_output('uname -r')
jadmanski0afbb632008-06-06 21:10:57 +0000663 kv_tmp = re.split(r'[-]', kernel_ver)[0:3]
lmr42b7a5d2010-05-21 12:52:08 +0000664 # In compare_versions, if v1 < v2, return value == -1
665 if utils.compare_versions(kv_tmp[0], ver) == -1:
666 raise error.TestError("Kernel too old (%s). Kernel > %s is needed." %
667 (kernel_ver, ver))
mbligh60418bb2008-01-03 01:55:09 +0000668
mbligh9061a272006-12-28 21:20:51 +0000669
mbligh264cd8f2007-02-02 23:57:43 +0000670def human_format(number):
jadmanski0afbb632008-06-06 21:10:57 +0000671 # Convert number to kilo / mega / giga format.
672 if number < 1024:
673 return "%d" % number
674 kilo = float(number) / 1024.0
675 if kilo < 1024:
676 return "%.2fk" % kilo
677 meg = kilo / 1024.0
678 if meg < 1024:
679 return "%.2fM" % meg
680 gig = meg / 1024.0
681 return "%.2fG" % gig
mbligh264cd8f2007-02-02 23:57:43 +0000682
mbligh8eca3a92007-02-03 20:59:39 +0000683
684def numa_nodes():
jadmanski0afbb632008-06-06 21:10:57 +0000685 node_paths = glob.glob('/sys/devices/system/node/node*')
686 nodes = [int(re.sub(r'.*node(\d+)', r'\1', x)) for x in node_paths]
687 return (sorted(nodes))
mbligh8eca3a92007-02-03 20:59:39 +0000688
689
690def node_size():
jadmanski0afbb632008-06-06 21:10:57 +0000691 nodes = max(len(numa_nodes()), 1)
692 return ((memtotal() * 1024) / nodes)
mbligh8eca3a92007-02-03 20:59:39 +0000693
mbligh32bcff32007-07-25 16:37:32 +0000694
695def to_seconds(time_string):
jadmanski0afbb632008-06-06 21:10:57 +0000696 """Converts a string in M+:SS.SS format to S+.SS"""
697 elts = time_string.split(':')
698 if len(elts) == 1:
699 return time_string
700 return str(int(elts[0]) * 60 + float(elts[1]))
mbligh32bcff32007-07-25 16:37:32 +0000701
702
703def extract_all_time_results(results_string):
jadmanski0afbb632008-06-06 21:10:57 +0000704 """Extract user, system, and elapsed times into a list of tuples"""
705 pattern = re.compile(r"(.*?)user (.*?)system (.*?)elapsed")
706 results = []
707 for result in pattern.findall(results_string):
708 results.append(tuple([to_seconds(elt) for elt in result]))
709 return results
mblighc4211642007-08-02 21:00:51 +0000710
711
712def pickle_load(filename):
jadmanski0afbb632008-06-06 21:10:57 +0000713 return pickle.load(open(filename, 'r'))
mblighc4211642007-08-02 21:00:51 +0000714
mbligh237bed32007-09-05 13:05:57 +0000715
716# Return the kernel version and build timestamp.
717def running_os_release():
jadmanski0afbb632008-06-06 21:10:57 +0000718 return os.uname()[2:4]
mbligh237bed32007-09-05 13:05:57 +0000719
720
721def running_os_ident():
jadmanski0afbb632008-06-06 21:10:57 +0000722 (version, timestamp) = running_os_release()
723 return version + '::' + timestamp
mblighb830e282007-10-02 16:35:03 +0000724
725
mbligh3bf79ca2009-01-21 19:02:40 +0000726def running_os_full_version():
727 (version, timestamp) = running_os_release()
728 return version
729
730
mbligh523a19b2007-12-04 22:50:14 +0000731# much like find . -name 'pattern'
732def locate(pattern, root=os.getcwd()):
jadmanski0afbb632008-06-06 21:10:57 +0000733 for path, dirs, files in os.walk(root):
mbligh987071e2008-06-13 16:39:12 +0000734 for f in files:
735 if fnmatch.fnmatch(f, pattern):
mbligh7076b192008-06-13 17:53:49 +0000736 yield os.path.abspath(os.path.join(path, f))
mbligh523a19b2007-12-04 22:50:14 +0000737
738
mbligh25bb1e12007-10-12 23:57:47 +0000739def freespace(path):
jadmanski0afbb632008-06-06 21:10:57 +0000740 """Return the disk free space, in bytes"""
741 s = os.statvfs(path)
742 return s.f_bavail * s.f_bsize
jadmanski8415f962008-05-06 20:38:53 +0000743
744
745def disk_block_size(path):
jadmanski0afbb632008-06-06 21:10:57 +0000746 """Return the disk block size, in bytes"""
747 return os.statvfs(path).f_bsize
mbligh6de9cdf2007-11-24 19:35:28 +0000748
749
mbligh2316e522007-11-24 19:39:52 +0000750def get_disks():
mbligh2da4d882009-01-21 19:05:40 +0000751 df_output = utils.system_output('df')
jadmanski0afbb632008-06-06 21:10:57 +0000752 disk_re = re.compile(r'^(/dev/hd[a-z]+)3', re.M)
753 return disk_re.findall(df_output)
mbligh6de9cdf2007-11-24 19:35:28 +0000754
mbligh3e9062e2007-11-29 15:57:02 +0000755
Puthikorn Voravootivat8b811e02014-06-02 14:13:45 -0700756def get_disk_size(disk_name):
757 """
758 Return size of disk in byte. Return 0 in Error Case
759
760 @param disk_name: disk name to find size
761 """
762 device = os.path.basename(disk_name)
763 for line in file('/proc/partitions'):
764 try:
Gwendal Grignou10e71e62014-06-12 11:25:19 -0700765 _, _, blocks, name = re.split(r' +', line.strip())
Puthikorn Voravootivat8b811e02014-06-02 14:13:45 -0700766 except ValueError:
767 continue
768 if name == device:
769 return 1024 * int(blocks)
770 return 0
771
772
773def get_disk_size_gb(disk_name):
774 """
775 Return size of disk in GB (10^9). Return 0 in Error Case
776
777 @param disk_name: disk name to find size
778 """
779 return int(get_disk_size(disk_name) / (10.0 ** 9) + 0.5)
780
781
782def get_disk_model(disk_name):
783 """
784 Return model name for internal storage device
785
786 @param disk_name: disk name to find model
787 """
788 cmd1 = 'udevadm info --query=property --name=%s' % disk_name
789 cmd2 = 'grep -E "ID_(NAME|MODEL)="'
790 cmd3 = 'cut -f 2 -d"="'
791 cmd = ' | '.join([cmd1, cmd2, cmd3])
792 return utils.system_output(cmd)
793
794
Gwendal Grignou10e71e62014-06-12 11:25:19 -0700795def get_disk_from_filename(filename):
796 """
797 Return the disk device the filename is on.
798 If the file is on tmpfs or other special file systems,
799 return None.
800
801 @param filename: name of file, full path.
802 """
803 re_disk = re.compile('/dev/sd[a-z]|/dev/mmcblk[0-9]*')
804
Gwendal Grignou30dcb3b2014-06-20 10:48:21 -0700805 if not os.path.exists(filename):
Gwendal Grignou10e71e62014-06-12 11:25:19 -0700806 raise error.TestError('file %s missing' % filename)
807
808 if filename[0] != '/':
809 raise error.TestError('This code works only with full path')
810
811 m = re_disk.match(filename)
812 while not m:
813 if filename[0] != '/':
814 return None
815 if filename == '/dev/root':
816 cmd = 'rootdev -d -s'
817 elif filename.startswith('/dev/mapper'):
818 cmd = 'dmsetup table "%s"' % os.path.basename(filename)
819 dmsetup_output = utils.system_output(cmd).split(' ')
820 if dmsetup_output[2] == 'verity':
821 maj_min = dmsetup_output[4]
822 elif dmsetup_output[2] == 'crypt':
823 maj_min = dmsetup_output[6]
824 cmd = 'realpath "/dev/block/%s"' % maj_min
825 elif filename.startswith('/dev/loop'):
826 cmd = 'losetup -O BACK-FILE "%s" | tail -1' % filename
827 else:
828 cmd = 'df "%s" | tail -1 | cut -f 1 -d" "' % filename
829 filename = utils.system_output(cmd)
830 m = re_disk.match(filename)
831 return m.group(0)
832
833
Puthikorn Voravootivat8ba770d2014-06-10 14:44:27 -0700834def get_disk_firmware_version(disk_name):
835 """
836 Return firmware version for internal storage device. (empty string for eMMC)
837
838 @param disk_name: disk name to find model
839 """
840 cmd1 = 'udevadm info --query=property --name=%s' % disk_name
841 cmd2 = 'grep -E "ID_REVISION="'
842 cmd3 = 'cut -f 2 -d"="'
843 cmd = ' | '.join([cmd1, cmd2, cmd3])
844 return utils.system_output(cmd)
845
846
847def is_disk_scsi(disk_name):
848 """
849 Return true if disk is a scsi device, return false otherwise
850
851 @param disk_name: disk name check
852 """
853 return re.match('/dev/sd[a-z]+', disk_name)
854
855
856def is_disk_harddisk(disk_name):
857 """
858 Return true if disk is a harddisk, return false otherwise
859
860 @param disk_name: disk name check
861 """
862 cmd1 = 'udevadm info --query=property --name=%s' % disk_name
863 cmd2 = 'grep -E "ID_ATA_ROTATION_RATE_RPM="'
864 cmd3 = 'cut -f 2 -d"="'
865 cmd = ' | '.join([cmd1, cmd2, cmd3])
866
867 rtt = utils.system_output(cmd)
868
869 # eMMC will not have this field; rtt == ''
870 # SSD will have zero rotation rate; rtt == '0'
871 # For harddisk rtt > 0
872 return rtt and int(rtt) > 0
873
874
875def verify_hdparm_feature(disk_name, feature):
876 """
877 Check for feature support for SCSI disk using hdparm
878
879 @param disk_name: target disk
880 @param feature: hdparm output string of the feature
881 """
882 cmd = 'hdparm -I %s | grep -q "%s"' % (disk_name, feature)
883 ret = utils.system(cmd, ignore_status=True)
884 if ret == 0:
885 return True
886 elif ret == 1:
887 return False
888 else:
889 raise error.TestFail('Error running command %s' % cmd)
890
891
892def get_storage_error_msg(disk_name, reason):
893 """
894 Get Error message for storage test which include disk model.
895 and also include the firmware version for the SCSI disk
896
897 @param disk_name: target disk
898 @param reason: Reason of the error.
899 """
900
901 msg = reason
902
903 model = get_disk_model(disk_name)
904 msg += ' Disk model: %s' % model
905
906 if is_disk_scsi(disk_name):
907 fw = get_disk_firmware_version(disk_name)
908 msg += ' firmware: %s' % fw
909
910 return msg
911
912
mbligh3e9062e2007-11-29 15:57:02 +0000913def load_module(module_name):
jadmanski0afbb632008-06-06 21:10:57 +0000914 # Checks if a module has already been loaded
915 if module_is_loaded(module_name):
916 return False
mblighaf4efc22008-01-25 16:33:59 +0000917
mbligh2da4d882009-01-21 19:05:40 +0000918 utils.system('/sbin/modprobe ' + module_name)
jadmanski0afbb632008-06-06 21:10:57 +0000919 return True
mbligh3e9062e2007-11-29 15:57:02 +0000920
921
922def unload_module(module_name):
lmrb923fc22009-06-08 17:27:59 +0000923 """
924 Removes a module. Handles dependencies. If even then it's not possible
925 to remove one of the modules, it will trhow an error.CmdError exception.
926
927 @param module_name: Name of the module we want to remove.
928 """
Henrik Kjellanderabbd2372013-04-04 14:06:57 +0200929 l_raw = utils.system_output("/bin/lsmod").splitlines()
lmrb923fc22009-06-08 17:27:59 +0000930 lsmod = [x for x in l_raw if x.split()[0] == module_name]
931 if len(lsmod) > 0:
932 line_parts = lsmod[0].split()
933 if len(line_parts) == 4:
934 submodules = line_parts[3].split(",")
935 for submodule in submodules:
936 unload_module(submodule)
937 utils.system("/sbin/modprobe -r %s" % module_name)
Daniel Kurtzf278e852014-03-04 21:57:30 -0800938 logging.info("Module %s unloaded", module_name)
lmrb923fc22009-06-08 17:27:59 +0000939 else:
Daniel Kurtzf278e852014-03-04 21:57:30 -0800940 logging.info("Module %s is already unloaded", module_name)
mbligh3e9062e2007-11-29 15:57:02 +0000941
942
943def module_is_loaded(module_name):
jadmanski0afbb632008-06-06 21:10:57 +0000944 module_name = module_name.replace('-', '_')
Henrik Kjellanderabbd2372013-04-04 14:06:57 +0200945 modules = utils.system_output('/bin/lsmod').splitlines()
jadmanski0afbb632008-06-06 21:10:57 +0000946 for module in modules:
947 if module.startswith(module_name) and module[len(module_name)] == ' ':
948 return True
949 return False
mbligh3e9062e2007-11-29 15:57:02 +0000950
951
mbligh6b34c4c2008-01-10 16:32:04 +0000952def get_loaded_modules():
Henrik Kjellanderabbd2372013-04-04 14:06:57 +0200953 lsmod_output = utils.system_output('/bin/lsmod').splitlines()[1:]
jadmanski0afbb632008-06-06 21:10:57 +0000954 return [line.split(None, 1)[0] for line in lsmod_output]
mbligh6b34c4c2008-01-10 16:32:04 +0000955
956
mbligh3e9062e2007-11-29 15:57:02 +0000957def get_huge_page_size():
mbligh2da4d882009-01-21 19:05:40 +0000958 output = utils.system_output('grep Hugepagesize /proc/meminfo')
jadmanski0afbb632008-06-06 21:10:57 +0000959 return int(output.split()[1]) # Assumes units always in kB. :(
mbligh3e9062e2007-11-29 15:57:02 +0000960
961
962def get_num_huge_pages():
mbligh2da4d882009-01-21 19:05:40 +0000963 raw_hugepages = utils.system_output('/sbin/sysctl vm.nr_hugepages')
jadmanski0afbb632008-06-06 21:10:57 +0000964 return int(raw_hugepages.split()[2])
mbligh3e9062e2007-11-29 15:57:02 +0000965
966
967def set_num_huge_pages(num):
mbligh2da4d882009-01-21 19:05:40 +0000968 utils.system('/sbin/sysctl vm.nr_hugepages=%d' % num)
mbligh3e9062e2007-11-29 15:57:02 +0000969
970
mbligh70c50ad2008-02-12 20:56:13 +0000971def ping_default_gateway():
jadmanski0afbb632008-06-06 21:10:57 +0000972 """Ping the default gateway."""
mbligh70c50ad2008-02-12 20:56:13 +0000973
jadmanski0afbb632008-06-06 21:10:57 +0000974 network = open('/etc/sysconfig/network')
975 m = re.search('GATEWAY=(\S+)', network.read())
976
977 if m:
978 gw = m.group(1)
979 cmd = 'ping %s -c 5 > /dev/null' % gw
mbligh2da4d882009-01-21 19:05:40 +0000980 return utils.system(cmd, ignore_status=True)
jadmanski0afbb632008-06-06 21:10:57 +0000981
982 raise error.TestError('Unable to find default gateway')
mbligh70c50ad2008-02-12 20:56:13 +0000983
984
jadmanski115feb22008-07-23 21:36:22 +0000985def drop_caches():
986 """Writes back all dirty pages to disk and clears all the caches."""
mbligh2da4d882009-01-21 19:05:40 +0000987 utils.system("sync")
jadmanski115feb22008-07-23 21:36:22 +0000988 # We ignore failures here as this will fail on 2.6.11 kernels.
mbligh2da4d882009-01-21 19:05:40 +0000989 utils.system("echo 3 > /proc/sys/vm/drop_caches", ignore_status=True)
mbligha3c17fc2009-08-24 22:34:41 +0000990
991
mblighe6bc5b92009-11-06 03:12:11 +0000992def process_is_alive(name_pattern):
mbligha3c17fc2009-08-24 22:34:41 +0000993 """
994 'pgrep name' misses all python processes and also long process names.
995 'pgrep -f name' gets all shell commands with name in args.
mblighe6bc5b92009-11-06 03:12:11 +0000996 So look only for command whose initial pathname ends with name.
997 Name itself is an egrep pattern, so it can use | etc for variations.
mbligha3c17fc2009-08-24 22:34:41 +0000998 """
mblighe6bc5b92009-11-06 03:12:11 +0000999 return utils.system("pgrep -f '^([^ /]*/)*(%s)([ ]|$)'" % name_pattern,
mbligha3c17fc2009-08-24 22:34:41 +00001000 ignore_status=True) == 0
mbligh88f602c2010-02-02 18:17:04 +00001001
1002
Eric Lia82dc352011-02-23 13:15:52 -08001003def get_hwclock_seconds(utc=True):
1004 """
1005 Return the hardware clock in seconds as a floating point value.
1006 Use Coordinated Universal Time if utc is True, local time otherwise.
1007 Raise a ValueError if unable to read the hardware clock.
1008 """
1009 cmd = '/sbin/hwclock --debug'
1010 if utc:
1011 cmd += ' --utc'
1012 hwclock_output = utils.system_output(cmd, ignore_status=True)
1013 match = re.search(r'= ([0-9]+) seconds since .+ (-?[0-9.]+) seconds$',
1014 hwclock_output, re.DOTALL)
1015 if match:
1016 seconds = int(match.group(1)) + float(match.group(2))
Daniel Kurtzf278e852014-03-04 21:57:30 -08001017 logging.debug('hwclock seconds = %f', seconds)
Eric Lia82dc352011-02-23 13:15:52 -08001018 return seconds
1019
1020 raise ValueError('Unable to read the hardware clock -- ' +
1021 hwclock_output)
1022
1023
1024def set_wake_alarm(alarm_time):
1025 """
1026 Set the hardware RTC-based wake alarm to 'alarm_time'.
1027 """
1028 utils.write_one_line('/sys/class/rtc/rtc0/wakealarm', str(alarm_time))
1029
1030
1031def set_power_state(state):
1032 """
1033 Set the system power state to 'state'.
1034 """
1035 utils.write_one_line('/sys/power/state', state)
1036
1037
1038def standby():
1039 """
1040 Power-on suspend (S1)
1041 """
1042 set_power_state('standby')
1043
1044
1045def suspend_to_ram():
1046 """
1047 Suspend the system to RAM (S3)
1048 """
1049 set_power_state('mem')
1050
1051
1052def suspend_to_disk():
1053 """
1054 Suspend the system to disk (S4)
1055 """
1056 set_power_state('disk')