From nobody Wed Feb 11 06:00:03 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=suse.de ARC-Seal: i=1; a=rsa-sha256; t=1680199725; cv=none; d=zohomail.com; s=zohoarc; b=iaxdl2qTsueaidwBp1ddwUoI7SdyWz8rp3xWIRzMaAkj6ynG6su0iwZG0bc790OaZG9aiYJVMIvFYDakq20lqrYr5Q1knqvPuUk0AuQOhit7PVUcjuTc31cb1lVbAitPpN83UedsN9AILznys8G5kr9cobJOM0kTGbbXDjok6fo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1680199725; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=aMxFafmyez7g9sXkEaSgJKRvOg914CYHM/M+GAElHpQ=; b=SuCHMOY8qCziD7XEjSLBihXTUgBczz0CxcWumqqrkV7NGJnyfgfLTq5pCAsHxjWx5ixht6zkxhtqLb3nrN7zkIjaihm+h9HirxdXZfbBvw3nQYje41lErh5C7yxgfdDQBnDX1htc+v/z3QfZtvlA2Wb6olM/HHlxUEqNJJx0tkc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1680199725463923.9976956914438; Thu, 30 Mar 2023 11:08:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1phwd5-0003DH-Lp; Thu, 30 Mar 2023 14:04:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1phwd4-0003CT-Am for qemu-devel@nongnu.org; Thu, 30 Mar 2023 14:04:06 -0400 Received: from smtp-out1.suse.de ([195.135.220.28]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1phwcx-00021x-1b for qemu-devel@nongnu.org; Thu, 30 Mar 2023 14:04:01 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id D4B12219E8; Thu, 30 Mar 2023 18:03:56 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 180961348E; Thu, 30 Mar 2023 18:03:53 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 2PLnMwnPJWQ5GwAAMHmgww (envelope-from ); Thu, 30 Mar 2023 18:03:53 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1680199436; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aMxFafmyez7g9sXkEaSgJKRvOg914CYHM/M+GAElHpQ=; b=1Pnf9G9/hku7NMHwGoswjnbWpLz9J17VEbWd4Z+IWLCGVHPvbRwYYWE/B8m5VPqxNGgX6B sdDkUqNEpb9dCqSwrCUJbcitSbgICbaKcvF4M+biYnoz8vz16/NOOAkrmRF1Ec4fbdzmEa U5JvdiaCatmJV8WZlcIL172TlxVE0MU= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1680199436; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aMxFafmyez7g9sXkEaSgJKRvOg914CYHM/M+GAElHpQ=; b=czxCkFBvWPzPBfYwSs661LS6GlGga6tLdh80I9fcfcAWN5JAu+lYU7NjbFh+4pzuneUXB6 iRr4du8558DWjXAw== From: Fabiano Rosas To: qemu-devel@nongnu.org Cc: Claudio Fontana , jfehlig@suse.com, dfaggioli@suse.com, dgilbert@redhat.com, =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= , Juan Quintela , Nikolay Borisov , John Snow , Cleber Rosa 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 Message-Id: <20230330180336.2791-6-farosas@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230330180336.2791-1-farosas@suse.de> References: <20230330180336.2791-1-farosas@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.28; envelope-from=farosas@suse.de; helo=smtp-out1.suse.de X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @suse.de) X-ZM-MESSAGEID: 1680199725749100003 Content-Type: text/plain; charset="utf-8" From: Nikolay Borisov 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 Signed-off-by: Fabiano Rosas --- 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 =3D NULL; s->hostname =3D NULL; + s->vmdesc =3D NULL; =20 migrate_set_state(&s->state, MIGRATION_STATUS_NONE, MIGRATION_STATUS_S= ETUP); =20 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 **reas= ons) =20 void qemu_savevm_state_header(QEMUFile *f) { + MigrationState *s =3D migrate_get_current(); + + s->vmdesc =3D json_writer_new(false); + trace_savevm_state_header(); qemu_put_be32(f, QEMU_VM_FILE_MAGIC); qemu_put_be32(f, QEMU_VM_FILE_VERSION); =20 - 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->vm= desc); + json_writer_end_object(s->vmdesc); } } =20 @@ -1237,8 +1249,6 @@ void qemu_savevm_state_setup(QEMUFile *f) Error *local_err =3D NULL; int ret; =20 - ms->vmdesc =3D 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"); =20 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 =20 def mkdir_p(path): try: @@ -119,11 +119,16 @@ def __init__(self, file, version_id, ramargs, section= _key): self.file =3D file self.section_key =3D section_key self.TARGET_PAGE_SIZE =3D ramargs['page_size'] + self.TARGET_PAGE_BITS =3D math.log2(self.TARGET_PAGE_SIZE) self.dump_memory =3D ramargs['dump_memory'] self.write_memory =3D ramargs['write_memory'] + self.fixed_ram =3D ramargs['fixed-ram'] self.sizeinfo =3D collections.OrderedDict() + self.bitmap_offset =3D collections.OrderedDict() + self.pages_offset =3D collections.OrderedDict() self.data =3D collections.OrderedDict() self.data['section sizes'] =3D self.sizeinfo + self.ram_read =3D False self.name =3D '' if self.write_memory: self.files =3D { } @@ -140,7 +145,13 @@ def __str__(self): def getDict(self): return self.data =20 + 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 =3D self.file.read64() @@ -167,7 +178,26 @@ def read(self): f.truncate(0) f.truncate(len) self.files[self.name] =3D f + + if self.fixed_ram: + bitmap_len =3D self.file.read32() + # skip the pages_offset which we don't need + offset =3D self.file.tell() + 8 + self.bitmap_offset[self.name] =3D offset + offset =3D ((offset + bitmap_len + self.TARGET_PAG= E_SIZE - 1) // + self.TARGET_PAGE_SIZE) * self.TARGET_PAG= E_SIZE + self.pages_offset[self.name] =3D offset + self.file.file.seek(offset + len) + flags &=3D ~self.RAM_SAVE_FLAG_MEM_SIZE + if self.fixed_ram: + self.ram_read =3D 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 =20 if flags & self.RAM_SAVE_FLAG_COMPRESS: if flags & self.RAM_SAVE_FLAG_CONTINUE: @@ -208,7 +238,7 @@ def read(self): =20 # End of RAM section if flags & self.RAM_SAVE_FLAG_EOS: - break + return =20 if flags !=3D 0: raise Exception("Unknown RAM flags: %x" % flags) @@ -521,6 +551,7 @@ def read(self, desc_only =3D False, dump_memory =3D Fal= se, write_memory =3D False): ramargs['page_size'] =3D self.vmsd_desc['page_size'] ramargs['dump_memory'] =3D dump_memory ramargs['write_memory'] =3D write_memory + ramargs['fixed-ram'] =3D False self.section_classes[('ram',0)][1] =3D ramargs =20 while True: @@ -528,8 +559,20 @@ def read(self, desc_only =3D False, dump_memory =3D Fa= lse, write_memory =3D False): if section_type =3D=3D self.QEMU_VM_EOF: break elif section_type =3D=3D self.QEMU_VM_CONFIGURATION: - section =3D ConfigurationSection(file) - section.read() + config_desc =3D self.vmsd_desc.get('configuration') + if config_desc is not None: + config =3D VMSDSection(file, 1, config_desc, 'configur= ation') + config.read() + caps =3D config.data.get("configuration/capabilities") + if caps is not None: + caps =3D caps.data["capabilities"] + if type(caps) !=3D list: + caps =3D [caps] + for i in caps: + # chomp out string length + cap =3D i.data[1:].decode("utf8") + if cap =3D=3D "fixed-ram": + ramargs['fixed-ram'] =3D True elif section_type =3D=3D self.QEMU_VM_SECTION_START or section= _type =3D=3D self.QEMU_VM_SECTION_FULL: section_id =3D file.read32() name =3D file.readstr() --=20 2.35.3