[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v6 3/8] qcow2_format.py: Dump bitmap directory info
From: |
Andrey Shinkevich |
Subject: |
[PATCH v6 3/8] qcow2_format.py: Dump bitmap directory info |
Date: |
Fri, 12 Jun 2020 00:19:15 +0300 |
Read and dump entries from the bitmap directory of QCOW2 image with the
script qcow2.py.
Header extension:
magic 0x23852875 (Bitmaps)
...
Bitmap name bitmap-1
flag auto
table size 8 (bytes)
bitmap_table_offset 0x90000
bitmap_table_size 1
flags 0
type 1
granularity_bits 16
name_size 8
extra_data_size 0
Suggested-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
tests/qemu-iotests/qcow2_format.py | 75 ++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/tests/qemu-iotests/qcow2_format.py
b/tests/qemu-iotests/qcow2_format.py
index d4f0000..a7868a7 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -103,6 +103,10 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
print('{:<25} {}'.format(f[2], value_str))
+# seek relative to the current position in the file
+FROM_CURRENT = 1
+
+
class Qcow2BitmapExt(Qcow2Struct):
fields = (
@@ -112,6 +116,73 @@ class Qcow2BitmapExt(Qcow2Struct):
('u64', '{:#x}', 'bitmap_directory_offset')
)
+ def read_bitmap_directory(self, fd):
+ self.bitmaps = []
+ fd.seek(self.bitmap_directory_offset)
+ buf_size = struct.calcsize(Qcow2BitmapDirEntry.fmt)
+
+ for n in range(self.nb_bitmaps):
+ buf = fd.read(buf_size)
+ dir_entry = Qcow2BitmapDirEntry(data=buf)
+ fd.seek(dir_entry.extra_data_size, FROM_CURRENT)
+ bitmap_name = fd.read(dir_entry.name_size)
+ dir_entry.name = bitmap_name.decode('ascii')
+ self.bitmaps.append(dir_entry)
+ entry_raw_size = dir_entry.bitmap_dir_entry_raw_size()
+ shift = ((entry_raw_size + 7) & ~7) - entry_raw_size
+ fd.seek(shift, FROM_CURRENT)
+
+ def load(self, fd):
+ self.read_bitmap_directory(fd)
+
+ def dump(self):
+ super().dump()
+ for bm in self.bitmaps:
+ bm.dump_bitmap_dir_entry()
+
+
+BME_FLAG_IN_USE = 1 << 0
+BME_FLAG_AUTO = 1 << 1
+
+
+class Qcow2BitmapDirEntry(Qcow2Struct):
+
+ name = ''
+
+ fields = (
+ ('u64', '{:#x}', 'bitmap_table_offset'),
+ ('u32', '{}', 'bitmap_table_size'),
+ ('u32', '{}', 'flags'),
+ ('u8', '{}', 'type'),
+ ('u8', '{}', 'granularity_bits'),
+ ('u16', '{}', 'name_size'),
+ ('u32', '{}', 'extra_data_size')
+ )
+
+ def __init__(self, data):
+ super().__init__(data=data)
+
+ self.bitmap_table_bytes = self.bitmap_table_size \
+ * struct.calcsize('Q')
+
+ self.bitmap_flags = []
+ if (self.flags & BME_FLAG_IN_USE):
+ self.bitmap_flags.append("in-use")
+ if (self.flags & BME_FLAG_AUTO):
+ self.bitmap_flags.append("auto")
+
+ def bitmap_dir_entry_raw_size(self):
+ return struct.calcsize(self.fmt) + self.name_size + \
+ self.extra_data_size
+
+ def dump_bitmap_dir_entry(self):
+ print()
+ print(f'{"Bitmap name":<25} {self.name}')
+ for fl in self.bitmap_flags:
+ print(f'{"flag":<25} {fl}')
+ print(f'{"table size ":<25} {self.bitmap_table_bytes} {"(bytes)"}')
+ super().dump()
+
QCOW2_EXT_MAGIC_BITMAPS = 0x23852875
@@ -253,6 +324,10 @@ class QcowHeader(Qcow2Struct):
else:
self.extensions.append(ext)
+ for ext in self.extensions:
+ if ext.obj is not None:
+ ext.obj.load(fd)
+
def update_extensions(self, fd):
fd.seek(self.header_length)
--
1.8.3.1
- [PATCH v6 0/8] iotests: Dump QCOW2 dirty bitmaps metadata, Andrey Shinkevich, 2020/06/11
- [PATCH v6 7/8] qcow2_format.py: collect fields to dump in JSON format, Andrey Shinkevich, 2020/06/11
- [PATCH v6 2/8] qcow2_format.py: make printable data an extension class member, Andrey Shinkevich, 2020/06/11
- [PATCH v6 6/8] qcow2.py: Introduce '-j' key to dump in JSON format, Andrey Shinkevich, 2020/06/11
- [PATCH v6 3/8] qcow2_format.py: Dump bitmap directory info,
Andrey Shinkevich <=
- [PATCH v6 4/8] qcow2_format.py: pass cluster size to substructures, Andrey Shinkevich, 2020/06/11
- [PATCH v6 5/8] qcow2_format.py: Dump bitmap table serialized entries, Andrey Shinkevich, 2020/06/11
- [PATCH v6 8/8] qcow2_format.py: support dumping metadata in JSON format, Andrey Shinkevich, 2020/06/11
- [PATCH v6 1/8] qcow2: Fix capitalization of header extension constant., Andrey Shinkevich, 2020/06/11