From nobody Fri Dec 19 19:02:58 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 205.139.110.120 as permitted sender) client-ip=205.139.110.120; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1592241082; cv=none; d=zohomail.com; s=zohoarc; b=Euvw6Nt+J9T4+DpHwGmYHMyJNHwtvBaw9C9HCdbt4n2vrze8UaIYWXetIlJX1w13WYacXQL7Imjp/6E4aF4EvEMse9kpgQjzVIHtpO1MwDWaNLDf1dYViXvvk7Y2rllj0/nYVG3wEFLeEMperWcqH18k5zjNywA4eh9aH0Z/MM8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592241082; h=Content-Type:Content-Transfer-Encoding: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=6rTBim5wH6yj4G0r03UIaSfya6OmXJXRI1StBAlDWmk=; b=Zi8RlS/baussVsO0ygyW6/eG5ydW66NQkARTohdwne3814XnQM6fgGzuxxT6uwmz3OixWSZAdYwaZtW7U8O0JXwLtDHYw9Eb3U+2BceEuVgIIF5Sir7KTxIgJ+LJPHz9joadPIdeb7S3gAlrk9UEKyB137+SIQW/xKB4VX5uFUk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by mx.zohomail.com with SMTPS id 1592241082960487.7286586995066; Mon, 15 Jun 2020 10:11:22 -0700 (PDT) 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-502-DHH5m22LOLuS2kTKc2ypww-1; Mon, 15 Jun 2020 13:11:19 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D8DC91138305; Mon, 15 Jun 2020 17:11:08 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B9B8790342; Mon, 15 Jun 2020 17:11:08 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 895F71806B0A; Mon, 15 Jun 2020 17:11:08 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 05FHB3eI005014 for ; Mon, 15 Jun 2020 13:11:04 -0400 Received: by smtp.corp.redhat.com (Postfix) id EFA6F100164D; Mon, 15 Jun 2020 17:11:03 +0000 (UTC) Received: from speedmetal.redhat.com (unknown [10.40.208.90]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6AE1A100238D for ; Mon, 15 Jun 2020 17:11:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1592241081; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=6rTBim5wH6yj4G0r03UIaSfya6OmXJXRI1StBAlDWmk=; b=hevaBWE9SPkZ+GttzP5OGtaucokoZDnqZ7UIwVrQsedPgrflcE0enV7lja08fQKwEKYgB5 Yo6QdH4O7NrpXtzB+Wd88NmmFdzo2RGQJQzRvBv2WSr9FX9fUKWw3bZzgcahq4Imt8pfUy OAK0+SymVM1URL6ll5lnKyX85VC3xsg= X-MC-Unique: DHH5m22LOLuS2kTKc2ypww-1 From: Peter Krempa To: libvir-list@redhat.com Subject: [PATCH 30/32] qemu: Rewrite bitmap handling for block copy Date: Mon, 15 Jun 2020 19:10:17 +0200 Message-Id: <42db2ffc289e51e05707f3a1b345a4dbb8733b11.1592240635.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" Reuse qemuBlockGetBitmapMergeActions which allows to remove the ad-hoc implementatio of bitmap merging for block copy. Signed-off-by: Peter Krempa Reviewed-by: Eric Blake --- src/qemu/qemu_block.c | 113 ++------------------------------------- src/qemu/qemu_blockjob.c | 40 ++++++++++++++ src/qemu/qemu_driver.c | 13 ++--- tests/qemublocktest.c | 6 ++- 4 files changed, 57 insertions(+), 115 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index e958fb71fa..0480f6b97d 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3068,38 +3068,6 @@ qemuBlockBitmapChainIsValid(virStorageSourcePtr src, } -struct qemuBlockBitmapsHandleBlockcopyConcatData { - virHashTablePtr bitmaps_merge; - virJSONValuePtr actions; - const char *mirrornodeformat; - bool has_bitmaps; -}; - - -static int -qemuBlockBitmapsHandleBlockcopyConcatActions(void *payload, - const void *name, - void *opaque) -{ - struct qemuBlockBitmapsHandleBlockcopyConcatData *data =3D opaque; - virJSONValuePtr createactions =3D payload; - const char *bitmapname =3D name; - g_autoptr(virJSONValue) mergebitmaps =3D virHashSteal(data->bitmaps_me= rge, bitmapname); - - data->has_bitmaps =3D true; - - virJSONValueArrayConcat(data->actions, createactions); - - if (qemuMonitorTransactionBitmapMerge(data->actions, - data->mirrornodeformat, - bitmapname, - &mergebitmaps) < 0) - return -1; - - return 0; -} - - /** * qemuBlockBitmapsHandleBlockcopy: * @src: disk source @@ -3122,86 +3090,15 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr= src, bool shallow, virJSONValuePtr *actions) { - g_autoptr(virHashTable) bitmaps =3D virHashNew(virJSONValueHashFree); - g_autoptr(virHashTable) bitmaps_merge =3D virHashNew(virJSONValueHashF= ree); - g_autoptr(virHashTable) bitmaps_skip =3D virHashNew(NULL); - g_autoptr(virJSONValue) tmpactions =3D virJSONValueNewArray(); - qemuBlockNamedNodeDataPtr entry; - virStorageSourcePtr n; - size_t i; - struct qemuBlockBitmapsHandleBlockcopyConcatData data =3D { .bitmaps_m= erge =3D bitmaps_merge, - .actions =3D= tmpactions, - .mirrornodef= ormat =3D mirror->nodeformat, - .has_bitmaps= =3D false, }; - - for (n =3D src; n; n =3D n->backingStore) { - if (!(entry =3D virHashLookup(blockNamedNodeData, n->nodeformat))) - continue; - - for (i =3D 0; i < entry->nbitmaps; i++) { - qemuBlockNamedNodeDataBitmapPtr bitmap =3D entry->bitmaps[i]; - virJSONValuePtr bitmap_merge; - - if (virHashHasEntry(bitmaps_skip, bitmap->name)) - continue; - - if (!(bitmap_merge =3D virHashLookup(bitmaps_merge, bitmap->na= me))) { - g_autoptr(virJSONValue) tmp =3D NULL; - bool disabled =3D !bitmap->recording; - - /* disable any non top-layer bitmaps */ - if (n !=3D src) - disabled =3D true; - - if (!bitmap->persistent || - !(qemuBlockBitmapChainIsValid(n, bitmap->name, - blockNamedNodeData))) { - ignore_value(virHashAddEntry(bitmaps_skip, bitmap->nam= e, NULL)); - continue; - } - - /* prepare the data for adding the bitmap to the mirror */ - tmp =3D virJSONValueNewArray(); - - if (qemuMonitorTransactionBitmapAdd(tmp, - mirror->nodeformat, - bitmap->name, - true, - disabled, - bitmap->granularity) <= 0) - return -1; + virStorageSourcePtr base =3D NULL; - if (virHashAddEntry(bitmaps, bitmap->name, tmp) < 0) - return -1; - - tmp =3D NULL; - - /* prepare array for merging all the bitmaps from the orig= inal chain */ - tmp =3D virJSONValueNewArray(); - - if (virHashAddEntry(bitmaps_merge, bitmap->name, tmp) < 0) - return -1; - - bitmap_merge =3D g_steal_pointer(&tmp); - } + if (shallow) + base =3D src->backingStore; - if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(bitmap_me= rge, - n->nodefo= rmat, - bitmap->n= ame) < 0) - return -1; - } - - if (shallow) - break; - } - - if (virHashForEach(bitmaps, qemuBlockBitmapsHandleBlockcopyConcatActio= ns, - &data) < 0) + if (qemuBlockGetBitmapMergeActions(src, base, mirror, NULL, NULL, mirr= or, actions, + blockNamedNodeData) < 0) return -1; - if (data.has_bitmaps) - *actions =3D g_steal_pointer(&tmpactions); - return 0; } diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 58ba3e6e96..7e4530f48b 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -1282,6 +1282,43 @@ qemuBlockJobProcessEventCompletedActiveCommit(virQEM= UDriverPtr driver, } +static int +qemuBlockJobProcessEventCompletedCopyBitmaps(virDomainObjPtr vm, + qemuBlockJobDataPtr job, + qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivatePtr priv =3D vm->privateData; + g_autoptr(virHashTable) blockNamedNodeData =3D NULL; + g_autoptr(virJSONValue) actions =3D NULL; + bool shallow =3D job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW; + + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) + return 0; + + if (!(blockNamedNodeData =3D qemuBlockGetNamedNodeData(vm, asyncJob))) + return -1; + + if (qemuBlockBitmapsHandleBlockcopy(job->disk->src, + job->disk->mirror, + blockNamedNodeData, + shallow, + &actions) < 0) + return 0; + + if (!actions) + return 0; + + if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0) + return -1; + + qemuMonitorTransaction(priv->mon, &actions); + + if (qemuDomainObjExitMonitor(priv->driver, vm) < 0) + return -1; + + return 0; +} + static void qemuBlockJobProcessEventConcludedCopyPivot(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -1296,6 +1333,8 @@ qemuBlockJobProcessEventConcludedCopyPivot(virQEMUDri= verPtr driver, !job->disk->mirror) return; + qemuBlockJobProcessEventCompletedCopyBitmaps(vm, job, asyncJob); + /* for shallow copy without reusing external image the user can either= not * specify the backing chain in which case libvirt will open and use t= he * chain the user provided or not specify a chain in which case we'll @@ -1329,6 +1368,7 @@ qemuBlockJobProcessEventConcludedCopyAbort(virQEMUDri= verPtr driver, !job->disk->mirror) return; + /* activeWrite bitmap is removed automatically here */ qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, job= ->disk->mirror); virObjectUnref(job->disk->mirror); job->disk->mirror =3D NULL; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8cf3629a80..c4d8a13004 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17314,14 +17314,15 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver, if (blockdev && !job->jobflagsmissing) { bool shallow =3D job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW; bool reuse =3D job->jobflags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT; - g_autoptr(virHashTable) blockNamedNodeData =3D NULL; - if (!(blockNamedNodeData =3D qemuBlockGetNamedNodeData(vm, QEM= U_ASYNC_JOB_NONE))) - return -1; + actions =3D virJSONValueNewArray(); - if (qemuBlockBitmapsHandleBlockcopy(disk->src, disk->mirror, - blockNamedNodeData, - shallow, &actions) < 0) + if (qemuMonitorTransactionBitmapAdd(actions, + disk->mirror->nodeformat, + "libvirt-tmp-activewrite", + false, + false, + 0) < 0) return -1; /* Open and install the backing chain of 'mirror' late if we c= an use diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 4a737e19d3..1c6517646b 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -881,6 +881,7 @@ testQemuBlockBitmapBlockcopy(const void *opaque) g_autoptr(virJSONValue) nodedatajson =3D NULL; g_autoptr(virHashTable) nodedata =3D NULL; g_autoptr(virStorageSource) fakemirror =3D virStorageSourceNew(); + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; if (!fakemirror) return -1; @@ -903,10 +904,13 @@ testQemuBlockBitmapBlockcopy(const void *opaque) data->shallow, &actions) < 0) return -1; + if (actions && - !(actual =3D virJSONValueToString(actions, true))) + virJSONValueToBuffer(actions, &buf, true) < 0) return -1; + actual =3D virBufferContentAndReset(&buf); + return virTestCompareToFile(actual, expectpath); } --=20 2.26.2