From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: Sanidhya Kashyap <sanidhya.iiith@gmail.com>
Cc: qemu list <qemu-devel@nongnu.org>, Juan Quintela <quintela@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v5 6/6] BitmapLog: python script for extracting bitmap from a binary file
Date: Tue, 12 Aug 2014 15:04:25 +0100 [thread overview]
Message-ID: <20140812140425.GB3255@work-vm> (raw)
In-Reply-To: <20140812123623.GA3255@work-vm>
* Dr. David Alan Gilbert (dgilbert@redhat.com) wrote:
> * Sanidhya Kashyap (sanidhya.iiith@gmail.com) wrote:
> > The file not only extracts the bitmap from the file but also draws the figure
> > if required. Currently, figure is drawn for all the bitmaps. Later, I'll make
> > the change to draw for different blocks.
> >
> > The picture is drawn by generating a matrix of 0s and 1s from the bitmap. The
> > dimensions are calculated on the basis of total bitmap pages which is represented
> > as sqrt(total pages) X (sqrt(total pages) + 1). The white parts indicate non dirtied
> > region while the black - dirtied region.
> >
> > The python code requires some libraries such as numpy, pylab and math to generate
> > the images.
>
> This is interesting; I've tried this out with a Fedora boot and recorded about 240
> frames; the script has problems when trying to convert that big a recording to images;
> 1) It loads it all into memory - so it used about 2GB of RAM
> 2) It opens each image as a window - so I then had to close about 240 windows
>
> I fiddled with it a bit and created .png files, and then stiched these together
> with imagemagick to create an animation. It's quite interesting watch the OS boot
> and then see me login and start google's stress apptest which suddenly changes
> the whole of memory.
>
> I suggest making it dump each image to a file in a similar way and making it free the
> python image data after each frame, then there shouldn't be a size limit.
> (I did try and upload the image, but QEMU's wiki didn't like the size)
and here's the (scaled down for size) looping gif:
http://wiki.qemu-project.org/images/9/9a/Fedboot50.gif
Dave
>
> Dave
>
>
> >
> > Signed-off-by: Sanidhya Kashyap <sanidhya.iiith@gmail.com>
> > ---
> > scripts/extract-bitmap.py | 144 ++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 144 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..942deca
> > --- /dev/null
> > +++ b/scripts/extract-bitmap.py
> > @@ -0,0 +1,144 @@
> > +#!/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
> > +from math import sqrt
> > +from numpy import array
> > +from pylab import figure,imshow,show,gray
> > +
> > +long_bytes = 8
> > +byte_size = 8
> > +int_bytes = 4
> > +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 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 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_images():
> > + r = 0
> > + for list in complete_bitmap_list:
> > + all_digits = ""
> > + for element in list:
> > + all_digits += dec2bin(element)
> > + l = len(all_digits)
> > + sqrtvalue = int(sqrt(l))
> > + for i in range(sqrtvalue * (sqrtvalue+1)-l):
> > + all_digits+="0"
> > +
> > + v = []
> > + l = len(all_digits)
> > + for i in range(sqrtvalue+1):
> > + v1 = []
> > + for j in range(sqrtvalue):
> > + v1.append(int(all_digits[i*sqrtvalue+j]))
> > + v.append(v1)
> > +
> > + im_array = array(v)
> > + figure(r)
> > + imshow(im_array, cmap=gray())
> > + r += 1
> > + show()
> > +
> > +def dump_bitmap(infile, draw):
> > + marker = 'M'
> > + count = 0
> > + value = ' '
> > + current_ram_bitmap_pages = 0
> > + prev_ram_bitmap_pages = 0
> > + 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)
> > +
> > + bitmap_length = get_bitmap_length(current_ram_bitmap_pages)
> > + bitmap_list = []
> > + bitmap_raw_value = infile.read(long_bytes * bitmap_length)
> > + if not bitmap_raw_value:
> > + break
> > + count+=1
> > + for i in range(bitmap_length):
> > + mark = i * long_bytes
> > + bitmap_list.append((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)
> > + if draw is True:
> > + generate_images()
> > + else:
> > + 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')
> > + extracter.add_argument('-d', action='store_true', dest='draw', default=False,
> > + help='Draw a black and white image of the processed dirty bitmap')
> > + args = extracter.parse_args()
> > + print 'The filename is {}'.format(args.infile)
> > +
> > + infile = open(format(args.infile), 'rb')
> > +
> > + dump_bitmap(infile, args.draw);
> > +
> > + infile.close()
> > +
> > +if __name__ == '__main__':
> > + main()
> > --
> > 1.9.3
> >
> >
> --
> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
prev parent reply other threads:[~2014-08-12 14:04 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-01 3:12 [Qemu-devel] [PATCH v5 0/6] Obtain dirty bitmap via VM logging Sanidhya Kashyap
2014-08-01 3:12 ` [Qemu-devel] [PATCH v5 1/6] generic function between migration and bitmap dump Sanidhya Kashyap
2014-08-12 10:37 ` Dr. David Alan Gilbert
2014-08-01 3:12 ` [Qemu-devel] [PATCH v5 2/6] BitmapLog: bitmap dump code Sanidhya Kashyap
2014-08-12 11:15 ` Dr. David Alan Gilbert
2014-08-12 13:12 ` Eric Blake
2014-08-01 3:12 ` [Qemu-devel] [PATCH v5 3/6] BitmapLog: get the information about the parameters Sanidhya Kashyap
2014-08-12 11:20 ` Dr. David Alan Gilbert
2014-08-12 13:53 ` Eric Blake
2014-08-01 3:12 ` [Qemu-devel] [PATCH v5 4/6] BitmapLog: cancel mechanism for an already running dump bitmap process Sanidhya Kashyap
2014-08-12 13:55 ` Eric Blake
2014-08-01 3:12 ` [Qemu-devel] [PATCH v5 5/6] BitmapLog: set the period of the " Sanidhya Kashyap
2014-08-12 13:57 ` Eric Blake
2014-08-01 3:12 ` [Qemu-devel] [PATCH v5 6/6] BitmapLog: python script for extracting bitmap from a binary file Sanidhya Kashyap
2014-08-12 12:36 ` Dr. David Alan Gilbert
2014-08-12 14:04 ` Dr. David Alan Gilbert [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140812140425.GB3255@work-vm \
--to=dgilbert@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=sanidhya.iiith@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).