blob: d52be5b0ed7765a1bd9147c75b9f605abb15dea2 [file] [log] [blame]
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Auxiliary script used to allocate memory on guests.
@copyright: 2008-2009 Red Hat Inc.
@author: Jiri Zupka (jzupka@redhat.com)
"""
import os, array, sys, random, copy, tempfile, datetime, math
PAGE_SIZE = 4096 # machine page size
TMPFS_OVERHEAD = 0.0022 # overhead on 1MB of write data
class MemFill(object):
"""
Fills guest memory according to certain patterns.
"""
def __init__(self, mem, static_value, random_key):
"""
Constructor of MemFill class.
@param mem: Amount of test memory in MB.
@param random_key: Seed of random series used for fill up memory.
@param static_value: Value used to fill all memory.
"""
if (static_value < 0 or static_value > 255):
print ("FAIL: Initialization static value"
"can be only in range (0..255)")
return
self.tmpdp = tempfile.mkdtemp()
ret_code = os.system("mount -o size=%dM tmpfs %s -t tmpfs" %
((mem+math.ceil(mem*TMPFS_OVERHEAD)),
self.tmpdp))
if ret_code != 0:
if os.getuid() != 0:
print ("FAIL: Unable to mount tmpfs "
"(likely cause: you are not root)")
else:
print "FAIL: Unable to mount tmpfs"
else:
self.f = tempfile.TemporaryFile(prefix='mem', dir=self.tmpdp)
self.allocate_by = 'L'
self.npages = ((mem * 1024 * 1024) / PAGE_SIZE)
self.random_key = random_key
self.static_value = static_value
print "PASS: Initialization"
def __del__(self):
if os.path.ismount(self.tmpdp):
self.f.close()
os.system("umount %s" % (self.tmpdp))
def compare_page(self, original, inmem):
"""
Compare pages of memory and print the differences found.
@param original: Data that was expected to be in memory.
@param inmem: Data in memory.
"""
for ip in range(PAGE_SIZE / original.itemsize):
if (not original[ip] == inmem[ip]): # find which item is wrong
originalp = array.array("B")
inmemp = array.array("B")
originalp.fromstring(original[ip:ip+1].tostring())
inmemp.fromstring(inmem[ip:ip+1].tostring())
for ib in range(len(originalp)): # find wrong byte in item
if not (originalp[ib] == inmemp[ib]):
position = (self.f.tell() - PAGE_SIZE + ip *
original.itemsize + ib)
print ("Mem error on position %d wanted 0x%Lx and is "
"0x%Lx" % (position, originalp[ib], inmemp[ib]))
def value_page(self, value):
"""
Create page filled by value.
@param value: String we want to fill the page with.
@return: return array of bytes size PAGE_SIZE.
"""
a = array.array("B")
for i in range((PAGE_SIZE / a.itemsize)):
try:
a.append(value)
except:
print "FAIL: Value can be only in range (0..255)"
return a
def random_page(self, seed):
"""
Create page filled by static random series.
@param seed: Seed of random series.
@return: Static random array series.
"""
random.seed(seed)
a = array.array(self.allocate_by)
for i in range(PAGE_SIZE / a.itemsize):
a.append(random.randrange(0, sys.maxint))
return a
def value_fill(self, value=None):
"""
Fill memory page by page, with value generated with value_page.
@param value: Parameter to be passed to value_page. None to just use
what's on the attribute static_value.
"""
self.f.seek(0)
if value is None:
value = self.static_value
page = self.value_page(value)
for pages in range(self.npages):
page.tofile(self.f)
print "PASS: Mem value fill"
def value_check(self, value=None):
"""
Check memory to see if data is correct.
@param value: Parameter to be passed to value_page. None to just use
what's on the attribute static_value.
@return: if data in memory is correct return PASS
else print some wrong data and return FAIL
"""
self.f.seek(0)
e = 2
failure = False
if value is None:
value = self.static_value
page = self.value_page(value)
for pages in range(self.npages):
pf = array.array("B")
pf.fromfile(self.f, PAGE_SIZE / pf.itemsize)
if not (page == pf):
failure = True
self.compare_page(page, pf)
e = e - 1
if e == 0:
break
if failure:
print "FAIL: value verification"
else:
print "PASS: value verification"
def static_random_fill(self, n_bytes_on_end=PAGE_SIZE):
"""
Fill memory by page with static random series with added special value
on random place in pages.
@param n_bytes_on_end: how many bytes on the end of page can be changed.
@return: PASS.
"""
self.f.seek(0)
page = self.random_page(self.random_key)
random.seed(self.random_key)
p = copy.copy(page)
t_start = datetime.datetime.now()
for pages in range(self.npages):
rand = random.randint(((PAGE_SIZE / page.itemsize) - 1) -
(n_bytes_on_end / page.itemsize),
(PAGE_SIZE/page.itemsize) - 1)
p[rand] = pages
p.tofile(self.f)
p[rand] = page[rand]
t_end = datetime.datetime.now()
delta = t_end - t_start
milisec = delta.microseconds / 1e3 + delta.seconds * 1e3
print "PASS: filling duration = %Ld ms" % milisec
def static_random_verify(self, n_bytes_on_end=PAGE_SIZE):
"""
Check memory to see if it contains correct contents.
@return: if data in memory is correct return PASS
else print some wrong data and return FAIL.
"""
self.f.seek(0)
e = 2
page = self.random_page(self.random_key)
random.seed(self.random_key)
p = copy.copy(page)
failure = False
for pages in range(self.npages):
rand = random.randint(((PAGE_SIZE/page.itemsize) - 1) -
(n_bytes_on_end/page.itemsize),
(PAGE_SIZE/page.itemsize) - 1)
p[rand] = pages
pf = array.array(self.allocate_by)
pf.fromfile(self.f, PAGE_SIZE / pf.itemsize)
if not (p == pf):
failure = True
self.compare_page(p, pf)
e = e - 1
if e == 0:
break
p[rand] = page[rand]
if failure:
print "FAIL: Random series verification"
else:
print "PASS: Random series verification"
def die():
"""
Quit allocator.
"""
exit(0)
def main():
"""
Main (infinite) loop of allocator.
"""
print "PASS: Start"
end = False
while not end:
str = raw_input()
exec str
if __name__ == "__main__":
main()