The script has not been updated to read mapped-ram snapshots and is currently
crashing when trying to read such a file.
With this commit, it can now read a snapshot created with:
(qemu) migrate_set_capability x-ignore-shared on
(qemu) migrate_set_capability mapped-ram on
(qemu) migrate -d file:vm.state
Signed-off-by: Pawel Zmarzly <[email protected]>
---
V2: Added support for format change in my other patch "migration: Fix writing
mapped_ram + ignore_shared snapshots". You can see whole stack at
https://gitlab.com/pzmarzly/qemu/-/commits/pzmarzly?ref_type=heads
---
scripts/analyze-migration.py | 48 ++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/scripts/analyze-migration.py b/scripts/analyze-migration.py
index 3303c05358..b6694bbd23 100755
--- a/scripts/analyze-migration.py
+++ b/scripts/analyze-migration.py
@@ -19,6 +19,7 @@
import json
import os
+import math
import argparse
import collections
import struct
@@ -127,6 +128,7 @@ def __init__(self, file, version_id, ramargs, section_key):
self.dump_memory = ramargs['dump_memory']
self.write_memory = ramargs['write_memory']
self.ignore_shared = ramargs['ignore_shared']
+ self.mapped_ram = ramargs['mapped_ram']
self.sizeinfo = collections.OrderedDict()
self.data = collections.OrderedDict()
self.data['section sizes'] = self.sizeinfo
@@ -170,6 +172,50 @@ def read(self):
self.files[self.name] = f
if self.ignore_shared:
mr_addr = self.file.read64()
+ if self.mapped_ram:
+ version = self.file.read32()
+ if version != 1:
+ raise Exception("Unsupported MappedRamHeader
version %s" % version)
+
+ page_size = self.file.read64()
+ if page_size != self.TARGET_PAGE_SIZE:
+ raise Exception("Page size mismatch in
MappedRamHeader")
+
+ bitmap_offset = self.file.read64()
+ pages_offset = self.file.read64()
+
+ if self.ignore_shared and bitmap_offset == 0 and
pages_offset == 0:
+ continue
+
+ if self.dump_memory or self.write_memory:
+ num_pages = len // page_size
+
+ self.file.seek(bitmap_offset, os.SEEK_SET)
+ bitmap_len = int(math.ceil(num_pages / 8))
+ bitmap = self.file.readvar(size=bitmap_len)
+
+ self.file.seek(pages_offset, os.SEEK_SET)
+ for page_num in range(num_pages):
+ page_addr = page_num * page_size
+
+ is_filled = (bitmap[page_num // 8] >> page_num
% 8) & 1
+ if is_filled:
+ data =
self.file.readvar(size=self.TARGET_PAGE_SIZE)
+ if self.write_memory:
+ self.files[self.name].seek(page_addr,
os.SEEK_SET)
+ self.files[self.name].write(data)
+ if self.dump_memory:
+ hexdata = " ".join("{0:02x}".format(c)
for c in data)
+ self.memory['%s (0x%016x)' %
(self.name, page_addr)] = hexdata
+ else:
+ self.file.seek(self.TARGET_PAGE_SIZE,
os.SEEK_CUR)
+ if self.write_memory:
+ self.files[self.name].seek(page_addr,
os.SEEK_SET)
+ self.files[self.name].write(b'\x00' *
self.TARGET_PAGE_SIZE)
+ if self.dump_memory:
+ self.memory['%s (0x%016x)' %
(self.name, page_addr)] = 'Filled with 0x00'
+
+ self.file.seek(pages_offset + len, os.SEEK_SET)
flags &= ~self.RAM_SAVE_FLAG_MEM_SIZE
if flags & self.RAM_SAVE_FLAG_COMPRESS:
@@ -663,6 +709,7 @@ def read(self, desc_only = False, dump_memory = False,
ramargs['dump_memory'] = dump_memory
ramargs['write_memory'] = write_memory
ramargs['ignore_shared'] = False
+ ramargs['mapped_ram'] = False
self.section_classes[('ram',0)][1] = ramargs
while True:
@@ -674,6 +721,7 @@ def read(self, desc_only = False, dump_memory = False,
section = ConfigurationSection(file, config_desc)
section.read()
ramargs['ignore_shared'] =
section.has_capability('x-ignore-shared')
+ ramargs['mapped_ram'] = section.has_capability('mapped-ram')
elif section_type == self.QEMU_VM_SECTION_START or section_type ==
self.QEMU_VM_SECTION_FULL:
section_id = file.read32()
name = file.readstr()
--
2.52.0