From nobody Mon Feb 9 10:33:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 207.211.31.120 as permitted sender) client-ip=207.211.31.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 207.211.31.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=1583931411; cv=none; d=zohomail.com; s=zohoarc; b=CTIIbO/djZQZqI+HSsN1hRL6u1QybVgFTMOwPALVuloJUmLUhhAxJ1Ie4zpYeYohKDmGCWgZ8D9iHUwVBJyttvm0nWYP9JeW2wjVmdVrQtc5j72SD6esZ/mO+jjU9FCstpEXxKHMuRhozw620XD5Q0Lmsoj6RTkvUJ+1w4eotCA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1583931411; 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=yPHYHGwincDOYfaxMRqggjjIIUHKsFpRGqY8H1bVy7A=; b=DY3zxHdjlzTG6BZT7uWKhnw0c30Dnm88AmmBudVrDYzRdTMnKSbY/w7QvfLXz3eJA8YheP98tXIkp+SOq1UlHWURWEMoe6lwf3eO2/RNentTEjSlDz2JRpGXN4gjyBc1n/5R2dTOeUr6VBRE3k+DlUGwr046GC7EpE6nhtAJnVU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.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 [207.211.31.120]) by mx.zohomail.com with SMTPS id 1583931411046346.1311243016396; Wed, 11 Mar 2020 05:56:51 -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-463-mcpP1jaqMtaezjS_6VWQZQ-1; Wed, 11 Mar 2020 08:56:47 -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 67837102CE14; Wed, 11 Mar 2020 12:56:40 +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 38C4890519; Wed, 11 Mar 2020 12:56:40 +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 DE17A86A26; Wed, 11 Mar 2020 12:56:39 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 02BCudcD009412 for ; Wed, 11 Mar 2020 08:56:39 -0400 Received: by smtp.corp.redhat.com (Postfix) id 161355C57D; Wed, 11 Mar 2020 12:56:39 +0000 (UTC) Received: from angien.redhat.com (unknown [10.43.2.48]) by smtp.corp.redhat.com (Postfix) with ESMTP id C90435C3FD; Wed, 11 Mar 2020 12:56:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583931409; 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=yPHYHGwincDOYfaxMRqggjjIIUHKsFpRGqY8H1bVy7A=; b=Cq+FftdD549rf5ZXaqiY8XuehILPcPYFIB4F5iTAoeI6eXPdYhVYSqoV4vECJFt0tseOcp yTtlWQwhRwrEOvcCH0wgFVI7UWd/un/SsIB/WnlcXuuopNsufy8tAInF+5k6qfxukBgRlQ 8A62uCB5y2VHGU5an0R9EC/a6QZpB8Y= X-MC-Unique: mcpP1jaqMtaezjS_6VWQZQ-1 From: Peter Krempa To: libvir-list@redhat.com Subject: [PATCH v2 11/19] qemu: block: Implement helpers for dealing with bitmaps during block commit Date: Wed, 11 Mar 2020 13:55:56 +0100 Message-Id: <57c3f8c8115d0e6a084838f08f5277116ddee03a.1583930936.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 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.13 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 Reviewed-by: Eric Blake --- src/qemu/qemu_block.c | 219 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_block.h | 14 +++ 2 files changed, 233 insertions(+) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index edebbcd0ce..6853c021ca 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -2962,6 +2962,225 @@ 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 topsrc, + 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 false; + 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(topsrc, bitmap->name, blockNamedN= odeData)) + 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 { + if (disabledBitmapsBase) { + char **disabledbitmaps; + + for (disabledbitmaps =3D disabledBitmapsBase; *disable= dbitmaps; disabledbitmaps++) { + if (STREQ(*disabledBitmapsBase, bitmap->name)) { + bitmapdata =3D g_new0(struct qemuBlockBitmapsH= andleCommitData, 1); + + bitmapdata->create =3D false; + bitmapdata->enable =3D true; + bitmapdata->basenode =3D basesrc->nodeformat; + bitmapdata->granularity =3D bitmap->granularit= y; + bitmapdata->persistent =3D bitmap->persistent; + + if (virHashAddEntry(commitdata, bitmap->name, = bitmapdata) < 0) { + qemuBlockBitmapsHandleCommitDataFree(bitma= pdata); + 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 1d8a364bd0..ac666ffb3a 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 qemuBlockReopenReadWrite(virDomainObjPtr vm, virStorageSourcePtr src, --=20 2.24.1