diff mbox

[v4,8/8] BitmapLog: python script for extracting bitmap from a binary file

Message ID 1405596081-29701-9-git-send-email-sanidhya.iiith@gmail.com
State New
Headers show

Commit Message

Sanidhya Kashyap July 17, 2014, 11:21 a.m. UTC
Signed-off-by: Sanidhya Kashyap <sanidhya.iiith@gmail.com>
---
 scripts/extract-bitmap.py | 97 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100755 scripts/extract-bitmap.py

Comments

Dr. David Alan Gilbert July 18, 2014, 11:17 a.m. UTC | #1
* Sanidhya Kashyap (sanidhya.iiith@gmail.com) wrote:
> Signed-off-by: Sanidhya Kashyap <sanidhya.iiith@gmail.com>

I'm not really a python-person, but one observation:

> +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]

Would it have been easier for you to format the strings in the stream
the same way the migration does it; i.e. a length byte followed by the text
of the string?

Dave

> +
> +def dump_ram_block_info(infile):
> +	total_blocks = get_integer(infile.read(int_bytes))
> +	for i in range(total_blocks):
> +		block_name = get_string(infile.read(string_bytes), string_bytes)
> +		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))
> +	print block_list
> +
> +def dump_bitmap(infile, bitmap_length):
> +	marker = 'M'
> +	count = 0
> +	value = ' '
> +	while True:
> +		if len(value) == 0  or marker != 'M':
> +			print len(complete_bitmap_list)
> +			print "issue with the dump"
> +			return
> +		bitmap_list = []
> +		bitmap_raw_value = infile.read(long_bytes * bitmap_length)
> +		if not bitmap_raw_value:
> +			print len(bitmap_raw_value)
> +			break
> +		count+=1
> +		for i in range(bitmap_length):
> +			mark = i * long_bytes
> +			bitmap_list.append(hex(get_unsigned_long_integer(bitmap_raw_value[mark:mark+long_bytes])))
> +		complete_bitmap_list.append(bitmap_list)
> +		value = infile.read(1)
> +		marker = get_char(value)
> +	print complete_bitmap_list
> +
> +def main():
> +	extracter = argparse.ArgumentParser(description='Extract dirty bitmap from binary file.')
> +	extracter.add_argument('infile', help='Input file to extract the bitmap')
> +	args = extracter.parse_args()
> +	print 'The filename is {}'.format(args.infile)
> +
> +	infile = open(format(args.infile), 'rb')
> +
> +	ram_bitmap_pages = get_long_integer(infile.read(long_bytes))
> +	print ram_bitmap_pages
> +	dump_ram_block_info(infile)
> +	bitmap_length = ram_bitmap_pages / (long_bytes * byte_size)
> +	if ram_bitmap_pages % (long_bytes * byte_size) != 0:
> +		bitmap_length += 1
> +	print bitmap_length
> +
> +	dump_bitmap(infile, bitmap_length);
> +
> +	infile.close()
> +
> +if __name__ == '__main__':
> +	main()
> -- 
> 1.9.3
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
diff mbox

Patch

diff --git a/scripts/extract-bitmap.py b/scripts/extract-bitmap.py
new file mode 100755
index 0000000..5edc49d
--- /dev/null
+++ b/scripts/extract-bitmap.py
@@ -0,0 +1,97 @@ 
+#!/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 <sanidhya.iiith@gmail.com>
+#
+# 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
+
+long_bytes = 8
+byte_size = 8
+int_bytes = 4
+string_bytes = 256
+complete_bitmap_list = []
+block_list = []
+
+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 dump_ram_block_info(infile):
+	total_blocks = get_integer(infile.read(int_bytes))
+	for i in range(total_blocks):
+		block_name = get_string(infile.read(string_bytes), string_bytes)
+		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))
+	print block_list
+
+def dump_bitmap(infile, bitmap_length):
+	marker = 'M'
+	count = 0
+	value = ' '
+	while True:
+		if len(value) == 0  or marker != 'M':
+			print len(complete_bitmap_list)
+			print "issue with the dump"
+			return
+		bitmap_list = []
+		bitmap_raw_value = infile.read(long_bytes * bitmap_length)
+		if not bitmap_raw_value:
+			print len(bitmap_raw_value)
+			break
+		count+=1
+		for i in range(bitmap_length):
+			mark = i * long_bytes
+			bitmap_list.append(hex(get_unsigned_long_integer(bitmap_raw_value[mark:mark+long_bytes])))
+		complete_bitmap_list.append(bitmap_list)
+		value = infile.read(1)
+		marker = get_char(value)
+	print complete_bitmap_list
+
+def main():
+	extracter = argparse.ArgumentParser(description='Extract dirty bitmap from binary file.')
+	extracter.add_argument('infile', help='Input file to extract the bitmap')
+	args = extracter.parse_args()
+	print 'The filename is {}'.format(args.infile)
+
+	infile = open(format(args.infile), 'rb')
+
+	ram_bitmap_pages = get_long_integer(infile.read(long_bytes))
+	print ram_bitmap_pages
+	dump_ram_block_info(infile)
+	bitmap_length = ram_bitmap_pages / (long_bytes * byte_size)
+	if ram_bitmap_pages % (long_bytes * byte_size) != 0:
+		bitmap_length += 1
+	print bitmap_length
+
+	dump_bitmap(infile, bitmap_length);
+
+	infile.close()
+
+if __name__ == '__main__':
+	main()