From nobody Mon Feb 9 01:21:56 2026 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=1583342822; cv=none; d=zohomail.com; s=zohoarc; b=RU+IBqR/tVvnoK1GtZQ5hnWgydShIlSBhYsWCLKCcjyumDwAz3obZ/9w2kt8vr8fmAqdEYjoJZ83f/jI8PNkWp3QvvVpHbnl3rz+V4zXCub0F9iM7Ko2a1CclaukuXOo9CdpZWc0Ym414iUTX99GXFK12KjdA5nfJJ4w9qEYjzU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1583342822; h=Content-Type: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=bQIKSAB9dmLLj2+iQ9rOtsuoeX+ZEBB1U2atozbQITU=; b=cGnrAoF/58Z2zOJI+fNNZ4zqL1DAdYWN2BRDOsX+SZBAs1iBdrsooRmxxqjpefDHuIw+xMTQQ7E0uw6KxY61WnBIlMusVMOu8O9WT1csuxSkKLr104qQvT5hUBxwz3ww31ZlHidL4QeJLFFv2D72XC00tbUt+bMV3OCZa4KL0As= 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 1583342822733301.8674010670086; Wed, 4 Mar 2020 09:27:02 -0800 (PST) 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-316-AKDTZHr6ON-lAsXsRrw3KQ-1; Wed, 04 Mar 2020 12:26:59 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C13B91088389; Wed, 4 Mar 2020 17:26:53 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8FC5910027A7; Wed, 4 Mar 2020 17:26:53 +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 3D8DF860D7; Wed, 4 Mar 2020 17:26:53 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 024HQpki027331 for ; Wed, 4 Mar 2020 12:26:51 -0500 Received: by smtp.corp.redhat.com (Postfix) id 2ABC28B75C; Wed, 4 Mar 2020 17:26:51 +0000 (UTC) Received: from angien.redhat.com (unknown [10.43.2.48]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7D48F19E9C; Wed, 4 Mar 2020 17:26:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583342821; h=from:from:sender:sender: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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=bQIKSAB9dmLLj2+iQ9rOtsuoeX+ZEBB1U2atozbQITU=; b=LoW86ZyniIrJyJI2Xfd3AY7l7Q1tZ5FmL4Xqul4q+TAEtZjwODHKSX2/xtyP1pgOIaseU8 7y7MOM9b4c75SbE9HiiFF2vAtiov5h4WysU5M/VR624I0+f/dkqpKtT3wFMBy4lZ0IP7ew wHOWse9oc1eK9/EXr3OY1Qh+neT+ITg= X-MC-Unique: AKDTZHr6ON-lAsXsRrw3KQ-1 From: Peter Krempa To: libvir-list@redhat.com Subject: [PATCH 05/13] qemu: block: Implement helpers for dealing with bitmaps during block commit Date: Wed, 4 Mar 2020 18:26:33 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Cc: Peter Krempa 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.84 on 10.5.11.22 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" qemuBlockBitmapsHandleCommitStart prepares for disabling the bitmaps in the 'base' of the commit job so that the bitmaps are not dirtied by the commit job. This needs to be done prior to start of the commit job. qemuBlockBitmapsHandleCommitFinish then calculates the necessary merges that agregate all the bitmaps between the commited images and write them into the base bitmap. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 217 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_block.h | 14 +++ 2 files changed, 231 insertions(+) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 11df8eedd0..2467315563 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -2962,6 +2962,223 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr= src, } +/** + * @topsrc: virStorageSource representing 'top' of the job + * @basesrc: virStorageSource representing 'base' of the job + * @blockNamedNodeData: hash table containing data about bitmaps + * @actions: filled with arguments for a 'transaction' command + * @disabledBitmapsBase: filled with a list of bitmap names which must be = disabled + * + * Prepares data for correctly hanlding bitmaps during the start of a comm= it + * job. The bitmaps in the 'base' image must be disabled, so that the writ= es + * done by the blockjob don't dirty the enabled bitmaps. + * + * @actions and @disabledBitmapsBase are untouched if no bitmaps need + * to be disabled. + */ +int +qemuBlockBitmapsHandleCommitStart(virStorageSourcePtr top, + virStorageSourcePtr basesrc, + virHashTablePtr blockNamedNodeData, + virJSONValuePtr *actions, + char ***disabledBitmapsBase) +{ + g_autoptr(virJSONValue) act =3D virJSONValueNewArray(); + VIR_AUTOSTRINGLIST bitmaplist =3D NULL; + size_t curbitmapstr =3D 0; + qemuBlockNamedNodeDataPtr entry; + bool disable_bitmaps =3D true; + size_t i; + + if (!(entry =3D virHashLookup(blockNamedNodeData, basesrc->nodeformat)= )) + return 0; + + bitmaplist =3D g_new0(char *, entry->nbitmaps); + + for (i =3D 0; i < entry->nbitmaps; i++) { + qemuBlockNamedNodeDataBitmapPtr bitmap =3D entry->bitmaps[i]; + + if (!bitmap->recording || bitmap->inconsistent || + !qemuBlockBitmapChainIsValid(top, bitmap->name, blockNamedNode= Data)) + continue; + + disable_bitmaps =3D true; + + if (qemuMonitorTransactionBitmapDisable(act, basesrc->nodeformat, + bitmap->name) < 0) + return -1; + + bitmaplist[curbitmapstr++] =3D g_strdup(bitmap->name); + } + + if (disable_bitmaps) { + *actions =3D g_steal_pointer(&act); + *disabledBitmapsBase =3D g_steal_pointer(&bitmaplist); + } + + return 0; +} + + +struct qemuBlockBitmapsHandleCommitData { + bool skip; + bool create; + bool enable; + const char *basenode; + virJSONValuePtr merge; + unsigned long long granularity; + bool persistent; +}; + + +static void +qemuBlockBitmapsHandleCommitDataFree(void *opaque) +{ + struct qemuBlockBitmapsHandleCommitData *data =3D opaque; + + virJSONValueFree(data->merge); + g_free(data); +} + + +static int +qemuBlockBitmapsHandleCommitFinishIterate(void *payload, + const void *entryname, + void *opaque) +{ + struct qemuBlockBitmapsHandleCommitData *data =3D payload; + const char *bitmapname =3D entryname; + virJSONValuePtr actions =3D opaque; + + if (data->skip) + return 0; + + if (data->create) { + if (qemuMonitorTransactionBitmapAdd(actions, data->basenode, bitma= pname, + data->persistent, !data-> enab= le, + data->granularity) < 0) + return -1; + } else { + if (data->enable && + qemuMonitorTransactionBitmapEnable(actions, data->basenode, bi= tmapname) < 0) + return -1; + } + + if (data->merge && + qemuMonitorTransactionBitmapMerge(actions, data->basenode, bitmapn= ame, + &data->merge) < 0) + return -1; + + return 0; +} + + +/** + * @topsrc: virStorageSource representing 'top' of the job + * @basesrc: virStorageSource representing 'base' of the job + * @blockNamedNodeData: hash table containing data about bitmaps + * @actions: filled with arguments for a 'transaction' command + * @disabledBitmapsBase: bitmap names which were disabled + * + * Calculates the necessary bitmap merges/additions/enablements to properly + * handle commit of images from 'top' into 'base'. The necessary operations + * in form of argumets of the 'transaction' command are filled into 'actio= ns' + * if there is anything to do. Otherwise NULL is returned. + */ +int +qemuBlockBitmapsHandleCommitFinish(virStorageSourcePtr topsrc, + virStorageSourcePtr basesrc, + virHashTablePtr blockNamedNodeData, + virJSONValuePtr *actions, + char **disabledBitmapsBase) +{ + g_autoptr(virJSONValue) act =3D virJSONValueNewArray(); + virStorageSourcePtr n; + qemuBlockNamedNodeDataPtr entry; + g_autoptr(virHashTable) commitdata =3D NULL; + struct qemuBlockBitmapsHandleCommitData *bitmapdata; + size_t i; + + commitdata =3D virHashNew(qemuBlockBitmapsHandleCommitDataFree); + + for (n =3D topsrc; n !=3D basesrc; 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]; + + if (!(bitmapdata =3D virHashLookup(commitdata, bitmap->name)))= { + bitmapdata =3D g_new0(struct qemuBlockBitmapsHandleCommitD= ata, 1); + + /* we must mirror the state of the topmost bitmap and merge + * everything else */ + bitmapdata->create =3D true; + bitmapdata->enable =3D bitmap->recording; + bitmapdata->basenode =3D basesrc->nodeformat; + bitmapdata->merge =3D virJSONValueNewArray(); + bitmapdata->granularity =3D bitmap->granularity; + bitmapdata->persistent =3D bitmap->persistent; + + if (virHashAddEntry(commitdata, bitmap->name, bitmapdata) = < 0) { + qemuBlockBitmapsHandleCommitDataFree(bitmapdata); + return -1; + } + } + + if (bitmap->inconsistent || + !qemuBlockBitmapChainIsValid(topsrc, bitmap->name, blockNa= medNodeData)) + bitmapdata->skip =3D true; + + if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(bitmapdat= a->merge, + n->nodefo= rmat, + bitmap->n= ame) < 0) + return -1; + } + } + + if ((entry =3D virHashLookup(blockNamedNodeData, basesrc->nodeformat))= ) { + /* note that all bitmaps in 'base' were disabled when commit was s= tarted */ + for (i =3D 0; i < entry->nbitmaps; i++) { + qemuBlockNamedNodeDataBitmapPtr bitmap =3D entry->bitmaps[i]; + + if ((bitmapdata =3D virHashLookup(commitdata, bitmap->name))) { + bitmapdata->create =3D false; + } else { + char **disabledbitmaps =3D disabledBitmapsBase; + + for (disabledbitmaps =3D disabledBitmapsBase; *disabledbit= maps; disabledbitmaps++) { + if (STREQ(*disabledBitmapsBase, bitmap->name)) { + bitmapdata =3D g_new0(struct qemuBlockBitmapsHandl= eCommitData, 1); + + bitmapdata->create =3D false; + bitmapdata->enable =3D true; + bitmapdata->basenode =3D basesrc->nodeformat; + bitmapdata->granularity =3D bitmap->granularity; + bitmapdata->persistent =3D bitmap->persistent; + + if (virHashAddEntry(commitdata, bitmap->name, bitm= apdata) < 0) { + qemuBlockBitmapsHandleCommitDataFree(bitmapdat= a); + return -1; + } + + break; + } + } + } + } + } + + if (virHashForEach(commitdata, qemuBlockBitmapsHandleCommitFinishItera= te, act) < 0) + return -1; + + if (virJSONValueArraySize(act) > 0) + *actions =3D g_steal_pointer(&act); + + return 0; +} + + /** * qemuBlockReopenFormat: * @vm: domain object diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index b3d7d0f876..cb408d2eee 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -229,6 +229,20 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr sr= c, bool shallow, virJSONValuePtr *actions); +int +qemuBlockBitmapsHandleCommitStart(virStorageSourcePtr topsrc, + virStorageSourcePtr basesrc, + virHashTablePtr blockNamedNodeData, + virJSONValuePtr *actions, + char ***disabledBitmapsBase); + +int +qemuBlockBitmapsHandleCommitFinish(virStorageSourcePtr topsrc, + virStorageSourcePtr basesrc, + virHashTablePtr blockNamedNodeData, + virJSONValuePtr *actions, + char **disabledBitmapsBase); + int qemuBlockReopenFormat(virDomainObjPtr vm, virStorageSourcePtr src, --=20 2.24.1