qcow2_format.py: Dump bitmap table serialized entries
Add bitmap table information to the QCOW2 metadata dump. Bitmap name bitmap-1 ... Bitmap table type size offset 0 serialized 65536 10092544 1 all-zeroes 0 0 2 all-zeroes 0 0 Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-Id: <1596742557-320265-8-git-send-email-andrey.shinkevich@virtuozzo.com> Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
e3f5aad7be
commit
9427784124
@ -66,6 +66,8 @@ type 1
|
||||
granularity_bits 15
|
||||
name_size 8
|
||||
extra_data_size 0
|
||||
Bitmap table type size offset
|
||||
0 serialized 65536 10092544
|
||||
|
||||
Bitmap name bitmap-2
|
||||
bitmap_table_offset 0x9c0000
|
||||
@ -75,4 +77,6 @@ type 1
|
||||
granularity_bits 16
|
||||
name_size 8
|
||||
extra_data_size 0
|
||||
Bitmap table type size offset
|
||||
0 all-zeroes 0 0
|
||||
|
||||
|
@ -175,6 +175,10 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
|
||||
entry_raw_size = self.bitmap_dir_entry_raw_size()
|
||||
padding = ((entry_raw_size + 7) & ~7) - entry_raw_size
|
||||
fd.seek(padding, 1)
|
||||
self.bitmap_table = Qcow2BitmapTable(fd=fd,
|
||||
offset=self.bitmap_table_offset,
|
||||
nb_entries=self.bitmap_table_size,
|
||||
cluster_size=self.cluster_size)
|
||||
|
||||
def bitmap_dir_entry_raw_size(self):
|
||||
return struct.calcsize(self.fmt) + self.name_size + \
|
||||
@ -183,6 +187,52 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
|
||||
def dump(self):
|
||||
print(f'{"Bitmap name":<25} {self.name}')
|
||||
super(Qcow2BitmapDirEntry, self).dump()
|
||||
self.bitmap_table.dump()
|
||||
|
||||
|
||||
class Qcow2BitmapTableEntry(Qcow2Struct):
|
||||
|
||||
fields = (
|
||||
('u64', '{}', 'entry'),
|
||||
)
|
||||
|
||||
BME_TABLE_ENTRY_RESERVED_MASK = 0xff000000000001fe
|
||||
BME_TABLE_ENTRY_OFFSET_MASK = 0x00fffffffffffe00
|
||||
BME_TABLE_ENTRY_FLAG_ALL_ONES = 1
|
||||
|
||||
def __init__(self, fd):
|
||||
super().__init__(fd=fd)
|
||||
self.reserved = self.entry & self.BME_TABLE_ENTRY_RESERVED_MASK
|
||||
self.offset = self.entry & self.BME_TABLE_ENTRY_OFFSET_MASK
|
||||
if self.offset:
|
||||
if self.entry & self.BME_TABLE_ENTRY_FLAG_ALL_ONES:
|
||||
self.type = 'invalid'
|
||||
else:
|
||||
self.type = 'serialized'
|
||||
elif self.entry & self.BME_TABLE_ENTRY_FLAG_ALL_ONES:
|
||||
self.type = 'all-ones'
|
||||
else:
|
||||
self.type = 'all-zeroes'
|
||||
|
||||
|
||||
class Qcow2BitmapTable:
|
||||
|
||||
def __init__(self, fd, offset, nb_entries, cluster_size):
|
||||
self.cluster_size = cluster_size
|
||||
position = fd.tell()
|
||||
fd.seek(offset)
|
||||
self.entries = [Qcow2BitmapTableEntry(fd) for _ in range(nb_entries)]
|
||||
fd.seek(position)
|
||||
|
||||
def dump(self):
|
||||
bitmap_table = enumerate(self.entries)
|
||||
print(f'{"Bitmap table":<14} {"type":<15} {"size":<12} {"offset"}')
|
||||
for i, entry in bitmap_table:
|
||||
if entry.type == 'serialized':
|
||||
size = self.cluster_size
|
||||
else:
|
||||
size = 0
|
||||
print(f'{i:<14} {entry.type:<15} {size:<12} {entry.offset}')
|
||||
|
||||
|
||||
QCOW2_EXT_MAGIC_BITMAPS = 0x23852875
|
||||
|
Loading…
x
Reference in New Issue
Block a user