[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH v1 05/26] migration: Initial support of fixed-ram feature for
From: |
Fabiano Rosas |
Subject: |
[RFC PATCH v1 05/26] migration: Initial support of fixed-ram feature for analyze-migration.py |
Date: |
Thu, 30 Mar 2023 15:03:15 -0300 |
From: Nikolay Borisov <nborisov@suse.com>
In order to allow analyze-migration.py script to work with migration
streams that have the 'fixed-ram' capability, it's required to have
access to the stream's configuration object. This commit enables this
by making migration json writer part of MigrationState struct,
allowing the configuration object be serialized to json.
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 1 +
migration/savevm.c | 18 ++++++++++---
scripts/analyze-migration.py | 51 +++++++++++++++++++++++++++++++++---
3 files changed, 62 insertions(+), 8 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 5408d87453..177fb0de0f 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2260,6 +2260,7 @@ void migrate_init(MigrationState *s)
error_free(s->error);
s->error = NULL;
s->hostname = NULL;
+ s->vmdesc = NULL;
migrate_set_state(&s->state, MIGRATION_STATUS_NONE,
MIGRATION_STATUS_SETUP);
diff --git a/migration/savevm.c b/migration/savevm.c
index aa54a67fda..92102c1fe5 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1206,13 +1206,25 @@ void qemu_savevm_non_migratable_list(strList **reasons)
void qemu_savevm_state_header(QEMUFile *f)
{
+ MigrationState *s = migrate_get_current();
+
+ s->vmdesc = json_writer_new(false);
+
trace_savevm_state_header();
qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
qemu_put_be32(f, QEMU_VM_FILE_VERSION);
- if (migrate_get_current()->send_configuration) {
+ if (s->send_configuration) {
qemu_put_byte(f, QEMU_VM_CONFIGURATION);
- vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0);
+ /*
+ * This starts the main json object and is paired with the
+ * json_writer_end_object in
+ * qemu_savevm_state_complete_precopy_non_iterable
+ */
+ json_writer_start_object(s->vmdesc, NULL);
+ json_writer_start_object(s->vmdesc, "configuration");
+ vmstate_save_state(f, &vmstate_configuration, &savevm_state,
s->vmdesc);
+ json_writer_end_object(s->vmdesc);
}
}
@@ -1237,8 +1249,6 @@ void qemu_savevm_state_setup(QEMUFile *f)
Error *local_err = NULL;
int ret;
- ms->vmdesc = json_writer_new(false);
- json_writer_start_object(ms->vmdesc, NULL);
json_writer_int64(ms->vmdesc, "page_size", qemu_target_page_size());
json_writer_start_array(ms->vmdesc, "devices");
diff --git a/scripts/analyze-migration.py b/scripts/analyze-migration.py
index b82a1b0c58..05af9efd2f 100755
--- a/scripts/analyze-migration.py
+++ b/scripts/analyze-migration.py
@@ -23,7 +23,7 @@
import collections
import struct
import sys
-
+import math
def mkdir_p(path):
try:
@@ -119,11 +119,16 @@ def __init__(self, file, version_id, ramargs,
section_key):
self.file = file
self.section_key = section_key
self.TARGET_PAGE_SIZE = ramargs['page_size']
+ self.TARGET_PAGE_BITS = math.log2(self.TARGET_PAGE_SIZE)
self.dump_memory = ramargs['dump_memory']
self.write_memory = ramargs['write_memory']
+ self.fixed_ram = ramargs['fixed-ram']
self.sizeinfo = collections.OrderedDict()
+ self.bitmap_offset = collections.OrderedDict()
+ self.pages_offset = collections.OrderedDict()
self.data = collections.OrderedDict()
self.data['section sizes'] = self.sizeinfo
+ self.ram_read = False
self.name = ''
if self.write_memory:
self.files = { }
@@ -140,7 +145,13 @@ def __str__(self):
def getDict(self):
return self.data
+ def write_or_dump_fixed_ram(self):
+ pass
+
def read(self):
+ if self.fixed_ram and self.ram_read:
+ return
+
# Read all RAM sections
while True:
addr = self.file.read64()
@@ -167,7 +178,26 @@ def read(self):
f.truncate(0)
f.truncate(len)
self.files[self.name] = f
+
+ if self.fixed_ram:
+ bitmap_len = self.file.read32()
+ # skip the pages_offset which we don't need
+ offset = self.file.tell() + 8
+ self.bitmap_offset[self.name] = offset
+ offset = ((offset + bitmap_len + self.TARGET_PAGE_SIZE
- 1) //
+ self.TARGET_PAGE_SIZE) *
self.TARGET_PAGE_SIZE
+ self.pages_offset[self.name] = offset
+ self.file.file.seek(offset + len)
+
flags &= ~self.RAM_SAVE_FLAG_MEM_SIZE
+ if self.fixed_ram:
+ self.ram_read = True
+ # now we should rewind to the ram page offset of the first
+ # ram section
+ if self.fixed_ram:
+ if self.write_memory or self.dump_memory:
+ self.write_or_dump_fixed_ram()
+ return
if flags & self.RAM_SAVE_FLAG_COMPRESS:
if flags & self.RAM_SAVE_FLAG_CONTINUE:
@@ -208,7 +238,7 @@ def read(self):
# End of RAM section
if flags & self.RAM_SAVE_FLAG_EOS:
- break
+ return
if flags != 0:
raise Exception("Unknown RAM flags: %x" % flags)
@@ -521,6 +551,7 @@ def read(self, desc_only = False, dump_memory = False,
write_memory = False):
ramargs['page_size'] = self.vmsd_desc['page_size']
ramargs['dump_memory'] = dump_memory
ramargs['write_memory'] = write_memory
+ ramargs['fixed-ram'] = False
self.section_classes[('ram',0)][1] = ramargs
while True:
@@ -528,8 +559,20 @@ def read(self, desc_only = False, dump_memory = False,
write_memory = False):
if section_type == self.QEMU_VM_EOF:
break
elif section_type == self.QEMU_VM_CONFIGURATION:
- section = ConfigurationSection(file)
- section.read()
+ config_desc = self.vmsd_desc.get('configuration')
+ if config_desc is not None:
+ config = VMSDSection(file, 1, config_desc, 'configuration')
+ config.read()
+ caps = config.data.get("configuration/capabilities")
+ if caps is not None:
+ caps = caps.data["capabilities"]
+ if type(caps) != list:
+ caps = [caps]
+ for i in caps:
+ # chomp out string length
+ cap = i.data[1:].decode("utf8")
+ if cap == "fixed-ram":
+ ramargs['fixed-ram'] = True
elif section_type == self.QEMU_VM_SECTION_START or section_type ==
self.QEMU_VM_SECTION_FULL:
section_id = file.read32()
name = file.readstr()
--
2.35.3
- [RFC PATCH v1 00/26] migration: File based migration with multifd and fixed-ram, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 02/26] migration: Add support for 'file:' uri for incoming migration, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 04/26] tests/qtest: migration-test: Add tests for file-based migration, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 01/26] migration: Add support for 'file:' uri for source migration, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 03/26] tests/qtest: migration: Add migrate_incoming_qmp helper, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 05/26] migration: Initial support of fixed-ram feature for analyze-migration.py,
Fabiano Rosas <=
- [RFC PATCH v1 06/26] io: add and implement QIO_CHANNEL_FEATURE_SEEKABLE for channel file, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 08/26] io: implement io_pwritev/preadv for QIOChannelFile, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 07/26] io: Add generic pwritev/preadv interface, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 09/26] migration/qemu-file: add utility methods for working with seekable channels, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 10/26] migration/ram: Introduce 'fixed-ram' migration stream capability, Fabiano Rosas, 2023/03/30