From nobody Tue Oct 28 17:34:04 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1760363179; cv=none; d=zohomail.com; s=zohoarc; b=kZHz2RtRalpyv05rbCrrlm8Id5/NUAEvmIKeuLaNz7dmmN2IGFWzjkSOETc5rcOjx7L/VCs+z80cazNFyeHiK3IBdcAwudigH+4X051N3te1Bl8Jimxit0Uf7eyW/z7d/aiigXj0tda8XwATq6bphXD6by7uGUM8GEbgv3dDgoc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1760363179; h=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id:Cc; bh=DbPZYrUVzMFrxRqz2fbct1pF4wR2EVK5eg+SNnONzdA=; b=NdiRaK6BN/dVHbLGah+O71DrZWY8aiEtNKiZ1nt3h/UKnyxpnrMlTlXlqxKcp14Lr2kKRUyGArcyOKH2VhiiqOZC2pHa4Ykfol6uvkKTHmoUyvWgFWCcA5iiaybbzjU2hfznzUdOw/UENdmqikMxp6mZV14SfmeToe3Uip41xfA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1760363179944988.5761784419836; Mon, 13 Oct 2025 06:46:19 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id C3A3D3F299; Mon, 13 Oct 2025 09:46:18 -0400 (EDT) Received: from [172.19.199.20] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id DF55244435; Mon, 13 Oct 2025 09:41:36 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 4442C43FC1; Mon, 13 Oct 2025 09:41:09 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 522B541BE7 for ; Mon, 13 Oct 2025 09:41:08 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-152-5oUd9B0oOHSGGIslXOzLPw-1; Mon, 13 Oct 2025 09:41:05 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id ACA011800599 for ; Mon, 13 Oct 2025 13:41:04 +0000 (UTC) Received: from speedmetal.lan (unknown [10.45.242.15]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 07ECE1801AD5 for ; Mon, 13 Oct 2025 13:41:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1760362867; h=from:from: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; bh=DbPZYrUVzMFrxRqz2fbct1pF4wR2EVK5eg+SNnONzdA=; b=GBV7Y0XDEL2u7caAgAvnO4PzPUCfO1B+h6ioPCxy86Bus9pJi4hSvPX4i42baDQ6ruNeKV 2kSEwvyHK1Mh/VQRiubFDzhHxKE/OCJFcdgPUPfdhR5mW5IcEvB5YOQJRWHy21VVCXR/q2 /4sPhhtrakIGLbkiBNuNUiXVgwWHSZM= X-MC-Unique: 5oUd9B0oOHSGGIslXOzLPw-1 X-Mimecast-MFC-AGG-ID: 5oUd9B0oOHSGGIslXOzLPw_1760362864 To: devel@lists.libvirt.org Subject: [PATCH 5/7] qemu: snapshot: Deactivate block nodes on manually snapshotted disks Date: Mon, 13 Oct 2025 15:40:54 +0200 Message-ID: <37ef44fa63b6aaf60e9aced2960ce3b742b5e10b.1760362814.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: gSld1HF73dmtf3e4xJmMr8gY8Mvu9Nj5Uf6cJgxS4_Y_1760362864 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: AOMO764XGL7WNGB7NLINCHU67GUVD6US X-Message-ID-Hash: AOMO764XGL7WNGB7NLINCHU67GUVD6US X-MailFrom: pkrempa@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Peter Krempa via Devel Reply-To: Peter Krempa X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1760363182074154100 Content-Type: text/plain; charset="utf-8" From: Peter Krempa If the user wants to manually preserve state of the disk we need, apart from pausing the machine to quiesce all writes, also deactivate the block nodes of the device. This ensures that qemu writes out metadata (e.g. block dirty bitmaps) which are normally stored only in memory, thus allowing a consistent snapshot including the metadata. Signed-off-by: Peter Krempa --- src/qemu/qemu_snapshot.c | 81 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index c988de37ca..5c12dca892 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -1552,6 +1552,83 @@ qemuSnapshotCreateActiveExternalDisks(virDomainObj *= vm, } +static int +qemuSnapshotCreateActiveExternalDisksManual(virDomainObj *vm, + virDomainMomentObj *snap, + virDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivate *priv =3D vm->privateData; + virDomainSnapshotDef *snapdef =3D virDomainSnapshotObjGetDef(snap); + g_autoptr(GPtrArray) nodenames =3D g_ptr_array_new(); + int ret =3D 0; + size_t i; + + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_SET_ACTIVE)) + return 0; + + for (i =3D 0; i < snapdef->ndisks; i++) { + virDomainDiskDef *domdisk =3D vm->def->disks[i]; + qemuDomainDiskPrivate *domdiskPriv =3D QEMU_DOMAIN_DISK_PRIVATE(do= mdisk); + virStorageSource *n; + + if (snapdef->disks[i].snapshot !=3D VIR_DOMAIN_SNAPSHOT_LOCATION_M= ANUAL) + continue; + + if (domdiskPriv->nodeCopyOnRead) + g_ptr_array_add(nodenames, domdiskPriv->nodeCopyOnRead); + + if (domdisk->nthrottlefilters > 0) { + size_t j; + + for (j =3D 0; j < domdisk->nthrottlefilters; j++) { + g_ptr_array_add(nodenames, (void *) qemuBlockThrottleFilte= rGetNodename(domdisk->throttlefilters[j])); + } + } + + for (n =3D domdisk->src; virStorageSourceIsBacking(n); n =3D n->ba= ckingStore) { + const char *tmp; + + if ((tmp =3D qemuBlockStorageSourceGetFormatNodename(n))) + g_ptr_array_add(nodenames, (void *) tmp); + + if ((tmp =3D qemuBlockStorageSourceGetSliceNodename(n))) + g_ptr_array_add(nodenames, (void *) tmp); + + g_ptr_array_add(nodenames, (void *) qemuBlockStorageSourceGetS= torageNodename(n)); + + if (n->dataFileStore) { + if ((tmp =3D qemuBlockStorageSourceGetFormatNodename(n->da= taFileStore))) + g_ptr_array_add(nodenames, (void *) tmp); + + if ((tmp =3D qemuBlockStorageSourceGetSliceNodename(n->dat= aFileStore))) + g_ptr_array_add(nodenames, (void *) tmp); + + g_ptr_array_add(nodenames, (void *) qemuBlockStorageSource= GetStorageNodename(n->dataFileStore)); + } + } + } + + if (nodenames->len =3D=3D 0) + return 0; + + if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) + return -1; + + for (i =3D 0; i < nodenames->len; i++) { + const char *nodename =3D g_ptr_array_index(nodenames, i); + + if (qemuMonitorBlockdevSetActive(priv->mon, nodename, false) < 0) { + ret =3D -1; + break; + } + } + + qemuDomainObjExitMonitor(vm); + + return ret; +} + + static int qemuSnapshotCreateActiveExternal(virQEMUDriver *driver, virDomainObj *vm, @@ -1627,6 +1704,10 @@ qemuSnapshotCreateActiveExternal(virQEMUDriver *driv= er, } } + if (has_manual && + qemuSnapshotCreateActiveExternalDisksManual(vm, snap, VIR_ASYNC_JO= B_SNAPSHOT) < 0) + goto cleanup; + /* We need to collect reply from 'query-named-block-nodes' prior to the * migration step as qemu deactivates bitmaps after migration so the r= esult * would be wrong */ --=20 2.51.0