[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v6 6/6] BitmapLog: python script for extracting bitm
From: |
Sanidhya Kashyap |
Subject: |
[Qemu-devel] [PATCH v6 6/6] BitmapLog: python script for extracting bitmap from a binary file |
Date: |
Sat, 13 Sep 2014 10:00:14 -0400 |
I have modified the script to support the dump of the images to the file.
Earlier,
everything was saved to the memory and later the processing was taking place.
Now,
I have tried to solve that issue with only using the required memory.
After discussion with David, I have tried to select a base 2 matrix dimension
like
512 X 512 or 1024 X 512 etc for the dumping of the bitmap. But, I am still
supporting
the default square root based method of dimension selection.
Signed-off-by: Sanidhya Kashyap <address@hidden>
---
scripts/extract-bitmap.py | 213 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 213 insertions(+)
create mode 100755 scripts/extract-bitmap.py
diff --git a/scripts/extract-bitmap.py b/scripts/extract-bitmap.py
new file mode 100755
index 0000000..9a5a481
--- /dev/null
+++ b/scripts/extract-bitmap.py
@@ -0,0 +1,213 @@
+#!/usr/bin/python
+# This python script helps in extracting the dirty bitmap present
+# in the file after executing the log-dirty-bitmap command either
+# from the qmp or hmp interface. This file only processes binary
+# file obtained via command.
+#
+# Copyright (C) 2014 Sanidhya Kashyap <address@hidden>
+#
+# Authors:
+# Sanidhya Kashyap
+#
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+
+import struct
+import argparse
+from functools import partial
+from math import sqrt
+from numpy import array
+from pylab import figure, imshow, savefig, gray, xlim, ylim
+from os import path, makedirs
+
+long_bytes = 8
+byte_size = 8
+int_bytes = 4
+block_list = []
+total_blocks = 0
+
+def get_unsigned_long_integer(value):
+ return struct.unpack('<Q', value)[0]
+
+def get_long_integer(value):
+ return struct.unpack('<q', value)[0]
+
+def get_integer(value):
+ return struct.unpack('<i', value)[0]
+
+def get_char(value):
+ return struct.unpack('<c', value)[0]
+
+def get_string(value, length):
+ name = struct.unpack('<'+str(length)+'s', value)[0]
+ for i in range(len(name)):
+ if name[i] == '\x00':
+ return name[:i]
+
+def dec2bin(decimal):
+ bin_value = bin(decimal)[2:]
+ if len(bin_value) < long_bytes * byte_size:
+ add_zeroes = long_bytes * byte_size - len(bin_value)
+ for i in range(add_zeroes):
+ bin_value += "0"
+ return str(bin_value)
+
+def get_bitmap_length(ram_bitmap_pages):
+ bitmap_length = ram_bitmap_pages / (long_bytes * byte_size)
+ if ram_bitmap_pages % (long_bytes * byte_size) != 0:
+ bitmap_length += 1
+ return bitmap_length
+
+def get_block_info():
+ print "Select any one of the following:"
+ for i in range(len(block_list)):
+ print str(i) + " " + block_list[i]['name']
+ return int(raw_input('Enter the number: '))
+
+def get_matrix(all_digits, y, x):
+ v = []
+ xlim(xmin = 0, xmax = x)
+ ylim(ymin = 0, ymax = y)
+ for i in range(y):
+ v1 = []
+ for j in range(x):
+ v1.append(int(all_digits[i * x + j]))
+ v.append(v1)
+ return v
+
+def get_matrix_base2(all_digits):
+ l = len(all_digits)
+ sqrtvalue = int(sqrt(l))
+ x = 2 ** (sqrtvalue.bit_length() - 1)
+ y = x * 2
+ if (x * y - l < 0):
+ x = y
+ for i in range(x * y - l):
+ all_digits += "0"
+
+ return get_matrix(all_digits, x, y);
+
+def get_matrix_sqrt(all_digits):
+ l = len(all_digits)
+ sqrtvalue = int(sqrt(l))
+ for i in range(sqrtvalue * (sqrtvalue + 1) - l):
+ all_digits += "0"
+
+ if sqrtvalue * sqrtvalue == l:
+ return get_matrix(all_digits, sqrtvalue, sqrtvalue)
+ else:
+ return get_matrix(all_digits, sqrtvalue, sqrtvalue + 1)
+
+def dump_ram_block_info(infile):
+ total_blocks = get_integer(infile.read(int_bytes))
+ for i in range(total_blocks):
+ block_name_length = get_integer(infile.read(int_bytes))
+ block_name = get_string(infile.read(block_name_length),
block_name_length)
+ block_offset = get_unsigned_long_integer(infile.read(long_bytes))
+ block_length = get_unsigned_long_integer(infile.read(long_bytes))
+ block_list.append(dict(name=block_name, offset=block_offset,
length=block_length))
+
+def generate_image(all_digits, num, debug, dir, base):
+ v = []
+
+ if base is False:
+ v = get_matrix_sqrt(all_digits)
+ else:
+ v = get_matrix_base2(all_digits)
+
+ im_array = array(v)
+ figure(num)
+ imshow(im_array, cmap=gray())
+
+ filename=dir + "/" + "out_" + str(num) + ".png"
+ del v
+ savefig(filename)
+ if debug is True:
+ print 'file ' + filename + ' dumped'
+
+
+def dump_bitmap(args):
+ marker = 'M'
+ count = 0
+ value = ' '
+ block_offset = 0
+ block_length = 0
+ block_num = 0
+ current_ram_bitmap_pages = 0
+ prev_ram_bitmap_pages = 0
+ infile = open(format(args.infile), 'rb')
+ debug = args.debug
+ dump_all = args.dump_all
+ dir = args.dir
+ base = args.base
+
+ if not path.exists(dir):
+ makedirs(dir)
+
+ while True:
+ if len(value) == 0 or marker != 'M':
+ print "issue with the dump"
+ return
+ bitmap_page_raw_value = infile.read(long_bytes)
+ if not bitmap_page_raw_value:
+ break
+ current_ram_bitmap_pages = get_long_integer(bitmap_page_raw_value)
+ if current_ram_bitmap_pages != prev_ram_bitmap_pages:
+ prev_ram_bitmap_pages = current_ram_bitmap_pages
+ dump_ram_block_info(infile)
+ # asking what should be printed
+ if dump_all is False:
+ if count == 0:
+ block_num = get_block_info()
+ if debug is True:
+ print block_list[block_num]['name'] + ' selected'
+ else:
+ x = block_num
+ y = len(block_list) / total_blocks
+ block_num = total_blocks * (y-1) + x
+ block_offset = block_list[block_num]['offset']
+ block_length = block_list[block_num]['length']
+ if debug is True:
+ print 'total ram bitmap pages: ' +
str(current_ram_bitmap_pages)
+ print block_list[block_num]['name'] + ' offset: ' +
str(block_offset)
+ print block_list[block_num]['name'] + ' length: ' +
str(block_length)
+
+ bitmap_length = get_bitmap_length(current_ram_bitmap_pages)
+ bitmap_raw_value = infile.read(long_bytes * bitmap_length)
+ if not bitmap_raw_value:
+ break
+
+ count+=1
+ all_digits=""
+ for i in range(bitmap_length):
+ mark = i * long_bytes
+ all_digits +=
dec2bin(get_unsigned_long_integer(bitmap_raw_value[mark : mark + long_bytes]))
+
+ if dump_all is False:
+ generate_image(all_digits[block_offset : block_offset +
block_length], count, debug, dir, base)
+ else:
+ generate_image(all_digits, count, debug, dir, base)
+ value = infile.read(1)
+ marker = get_char(value)
+ infile.close()
+
+def main():
+ extracter = argparse.ArgumentParser(description='Extract dirty bitmap from
binary file.')
+ extracter.add_argument('-f', '--file', dest='infile',
+ help='Input file to extract the bitmap', metavar='FILE')
+ extracter.add_argument('-a', '--all', action='store_true',
dest='dump_all', default=False,
+ help='Use all memory blocks for the figure')
+ extracter.add_argument('-d', '--debug', action='store_true', dest='debug',
default=False,
+ help='print the debug info')
+ extracter.add_argument('-dir', dest='dir', default='.',
+ help='directory to store the image files')
+ extracter.add_argument('-b', '--base2', dest='base', action='store_true',
default=False,
+ help='dump the bitmap array in powers of 2')
+
+ args = extracter.parse_args()
+ print 'The filename is {}'.format(args.infile)
+
+ dump_bitmap(args)
+
+if __name__ == '__main__':
+ main()
--
1.9.1
- [Qemu-devel] [PATCH v6 0/6] Obtain dirty bitmap via VM logging, Sanidhya Kashyap, 2014/09/13
- [Qemu-devel] [PATCH v6 2/6] BitmapLog: bitmap dump code, Sanidhya Kashyap, 2014/09/13
- [Qemu-devel] [PATCH v6 4/6] BitmapLog: cancel mechanism for an already running dump bitmap process, Sanidhya Kashyap, 2014/09/13
- [Qemu-devel] [PATCH v6 5/6] BitmapLog: set the period of the dump bitmap process, Sanidhya Kashyap, 2014/09/13
- [Qemu-devel] [PATCH v6 3/6] BitmapLog: get the information about the parameters, Sanidhya Kashyap, 2014/09/13
- [Qemu-devel] [PATCH v6 6/6] BitmapLog: python script for extracting bitmap from a binary file,
Sanidhya Kashyap <=
- [Qemu-devel] [PATCH v6 1/6] generic function between migration and bitmap dump, Sanidhya Kashyap, 2014/09/13