From nobody Thu Mar 28 10:44:37 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1589381490; cv=none; d=zohomail.com; s=zohoarc; b=AQbGzbqTCHnmUhMQpMatmBSQ746blgkl/noZZ0kP90a2hYt+xJGQIjY5FzjKIPL0r26KTL2IAuhRXRrn2m0VHK4YkOcLLGemSZkbUdRqeDCV/odx5or3CEVVK7oxO8ECclPnlOz1yp85QjnbuwFMbDznw0WAoSLYqERhEG6ARuI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589381490; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=KUcrD3c8mrxQR9hwuNwAclZ3iYvjlWPS1OOl3SMATVs=; b=PeZax66871jjQC9qhuWpB24yuyAOoGGaa9EaKg7ZCY+HBYV3c8Mpg66eGuz6EY3U06SWEPBewU1jCm0SYlqjTyBTVSQH2+UfmmSBw4ju1zUIUHHOMX9ixS6W4OVE8aAcAN+IG7T0fMOJ81kkPqM2jdnay4C6i4qtXHhxUfYuGJs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; 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=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1589381490515101.82784812626983; Wed, 13 May 2020 07:51:30 -0700 (PDT) Received: from localhost ([::1]:39908 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jYsjI-0001JM-7W for importer@patchew.org; Wed, 13 May 2020 10:51:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58880) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jYsi2-0008QT-Du for qemu-devel@nongnu.org; Wed, 13 May 2020 10:50:10 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:35251 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jYsi0-0007N2-4l for qemu-devel@nongnu.org; Wed, 13 May 2020 10:50:09 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-144-1mqyXG0OPeiBExmYjP97Rg-1; Wed, 13 May 2020 10:49:44 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BFB141005510; Wed, 13 May 2020 14:49:43 +0000 (UTC) Received: from localhost (unknown [10.40.193.218]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 229FE648DB; Wed, 13 May 2020 14:49:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589381406; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=KUcrD3c8mrxQR9hwuNwAclZ3iYvjlWPS1OOl3SMATVs=; b=gQ+fGgCXiAsJcKEuR2PUSRqME3NZoUO8HoTg9bk/xMi3KxXv/GELDnBDIY2ygxibwNzWkU mdtlm4upsJdayjeyG2lE6eZOuPoS1jBOjSIPd9U+iHgeQDGUNOBW528tCqHXzIWcLiU1+X Hmtd9/CyVDpvNQ7H5jZiQfJzCwCN7n0= X-MC-Unique: 1mqyXG0OPeiBExmYjP97Rg-1 From: Max Reitz To: qemu-block@nongnu.org Subject: [RFC] migration: Add migrate-set-bitmap-node-mapping Date: Wed, 13 May 2020 16:49:41 +0200 Message-Id: <20200513144941.1469447-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" 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=205.139.110.120; envelope-from=mreitz@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/13 01:56:38 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vladimir Sementsov-Ogievskiy , Juan Quintela , Markus Armbruster , qemu-devel@nongnu.org, "Dr . David Alan Gilbert" , Peter Krempa , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) This command allows mapping block node names to aliases for the purpose of block dirty bitmap migration. This way, management tools can use different node names on the source and destination and pass the mapping of how bitmaps are to be transferred to qemu (on the source, the destination, or even both with arbitrary aliases in the migration stream). Suggested-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Max Reitz --- Branch: https://github.com/XanClic/qemu.git migration-bitmap-mapping-rfc Branch: https://git.xanclic.moe/XanClic/qemu.git migration-bitmap-mapping-r= fc Vladimir has proposed something like this in April: https://lists.nongnu.org/archive/html/qemu-block/2020-04/msg00171.html Now I=E2=80=99ve been asked by my manager to look at this, so I decided to = just write a patch to see how it=E2=80=99d play out. This is an RFC, because I=E2=80=99d like to tack on tests to the final vers= ion, but I=E2=80=99m not sure whether I can come up with something before the en= d of the week (and I=E2=80=99ll be on PTO for the next two weeks). Also, I don=E2=80=99t know whether migration/block-dirty-bitmap.c is the be= st place to put qmp_migrate_set_bitmap_mapping(), but it appears we already have some QMP handlers in migration/, so I suppose it isn=E2=80=99t too bad. --- qapi/migration.json | 36 ++++++++++++++++++++ migration/block-dirty-bitmap.c | 60 ++++++++++++++++++++++++++++++++-- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/qapi/migration.json b/qapi/migration.json index d5000558c6..94aec8d194 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -1621,3 +1621,39 @@ ## { 'event': 'UNPLUG_PRIMARY', 'data': { 'device-id': 'str' } } + +## +# @MigrationBlockNodeMapping: +# +# Maps a block node name to an alias for migration. +# +# @node-name: A block node name. +# +# @alias: An alias name for migration (for example the node name on +# the opposite site). +# +# Since: 5.1 +## +{ 'struct': 'MigrationBitmapMapping', + 'data': { + 'node-name': 'str', + 'alias': 'str' + } } + +## +# @migrate-set-bitmap-node-mapping: +# +# Maps block node names to arbitrary aliases for the purpose of dirty +# bitmap migration. Such aliases may for example be the corresponding +# node names on the opposite site. +# +# By default, every node name is mapped to itself. +# +# @mapping: The mapping; must be one-to-one, but not necessarily +# complete. Any mapping not given will be reset to the +# default (i.e. the identity mapping). +# +# Since: 5.1 +## +{ 'command': 'migrate-set-bitmap-node-mapping', + 'data': { 'mapping': ['MigrationBlockNodeMapping'] } } diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index 7eafface61..8b434f7011 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -73,6 +73,8 @@ #include "qemu/hbitmap.h" #include "qemu/cutils.h" #include "qapi/error.h" +#include "qapi/qapi-commands-migration.h" +#include "qapi/qmp/qdict.h" #include "trace.h" =20 #define CHUNK_SIZE (1 << 10) @@ -121,6 +123,9 @@ typedef struct DirtyBitmapMigState { bool bulk_completed; bool no_bitmaps; =20 + QDict *node_in_mapping; + QDict *node_out_mapping; + /* for send_bitmap_bits() */ BlockDriverState *prev_bs; BdrvDirtyBitmap *prev_bitmap; @@ -281,8 +286,13 @@ static int init_dirty_bitmap_migration(void) dirty_bitmap_mig_state.no_bitmaps =3D false; =20 for (bs =3D bdrv_next_all_states(NULL); bs; bs =3D bdrv_next_all_state= s(bs)) { + const QDict *map =3D dirty_bitmap_mig_state.node_out_mapping; const char *name =3D bdrv_get_device_or_node_name(bs); =20 + if (map) { + name =3D qdict_get_try_str(map, name) ?: name; + } + FOR_EACH_DIRTY_BITMAP(bs, bitmap) { if (!bdrv_dirty_bitmap_name(bitmap)) { continue; @@ -600,6 +610,8 @@ static int dirty_bitmap_load_bits(QEMUFile *f, DirtyBit= mapLoadState *s) =20 static int dirty_bitmap_load_header(QEMUFile *f, DirtyBitmapLoadState *s) { + const QDict *map =3D dirty_bitmap_mig_state.node_in_mapping; + const char *mapped_node =3D "(none)"; Error *local_err =3D NULL; bool nothing; s->flags =3D qemu_get_bitmap_flags(f); @@ -612,7 +624,13 @@ static int dirty_bitmap_load_header(QEMUFile *f, Dirty= BitmapLoadState *s) error_report("Unable to read node name string"); return -EINVAL; } - s->bs =3D bdrv_lookup_bs(s->node_name, s->node_name, &local_err); + + mapped_node =3D s->node_name; + if (map) { + mapped_node =3D qdict_get_try_str(map, mapped_node) ?: mapped_= node; + } + + s->bs =3D bdrv_lookup_bs(mapped_node, mapped_node, &local_err); if (!s->bs) { error_report_err(local_err); return -EINVAL; @@ -634,7 +652,7 @@ static int dirty_bitmap_load_header(QEMUFile *f, DirtyB= itmapLoadState *s) if (!s->bitmap && !(s->flags & DIRTY_BITMAP_MIG_FLAG_START)) { error_report("Error: unknown dirty bitmap " "'%s' for block device '%s'", - s->bitmap_name, s->node_name); + s->bitmap_name, mapped_node); return -EINVAL; } } else if (!s->bitmap && !nothing) { @@ -713,6 +731,44 @@ static bool dirty_bitmap_has_postcopy(void *opaque) return true; } =20 +void qmp_migrate_set_bitmap_mapping(MigrationBitmapMappingList *mapping, + Error **errp) +{ + QDict *in_mapping =3D qdict_new(); + QDict *out_mapping =3D qdict_new(); + + for (; mapping; mapping =3D mapping->next) { + MigrationBitmapMapping *entry =3D mapping->value; + + if (qdict_haskey(out_mapping, entry->node_name)) { + error_setg(errp, "Cannot map node name '%s' twice", + entry->node_name); + goto fail; + } + + if (qdict_haskey(in_mapping, entry->alias)) { + error_setg(errp, "Cannot use alias '%s' twice", + entry->alias); + goto fail; + } + + qdict_put_str(in_mapping, entry->alias, entry->node_name); + qdict_put_str(out_mapping, entry->node_name, entry->alias); + } + + qobject_unref(dirty_bitmap_mig_state.node_in_mapping); + qobject_unref(dirty_bitmap_mig_state.node_out_mapping); + + dirty_bitmap_mig_state.node_in_mapping =3D in_mapping; + dirty_bitmap_mig_state.node_out_mapping =3D out_mapping; + + return; + +fail: + qobject_unref(in_mapping); + qobject_unref(out_mapping); +} + static SaveVMHandlers savevm_dirty_bitmap_handlers =3D { .save_setup =3D dirty_bitmap_save_setup, .save_live_complete_postcopy =3D dirty_bitmap_save_complete, --=20 2.26.2