qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] scripts/analyze-migration: Support mapped-ram snapshot format
@ 2025-11-26 15:50 Pawel Zmarzly
  2025-12-01 21:51 ` Peter Xu
  0 siblings, 1 reply; 2+ messages in thread
From: Pawel Zmarzly @ 2025-11-26 15:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: peterx, farosas

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 <pzmarzly0@gmail.com>
---
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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] scripts/analyze-migration: Support mapped-ram snapshot format
  2025-11-26 15:50 [PATCH v2] scripts/analyze-migration: Support mapped-ram snapshot format Pawel Zmarzly
@ 2025-12-01 21:51 ` Peter Xu
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Xu @ 2025-12-01 21:51 UTC (permalink / raw)
  To: Pawel Zmarzly; +Cc: qemu-devel, farosas

On Wed, Nov 26, 2025 at 03:50:15PM +0000, Pawel Zmarzly wrote:
> 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 <pzmarzly0@gmail.com>

queued, thanks.

-- 
Peter Xu



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-12-01 21:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-26 15:50 [PATCH v2] scripts/analyze-migration: Support mapped-ram snapshot format Pawel Zmarzly
2025-12-01 21:51 ` Peter Xu

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).