From nobody Mon Feb 9 03:14:00 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 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=1565963718; cv=none; d=zoho.com; s=zohoarc; b=g2XiG/YU/OeEDhP3NWGpigFt/Ov2R3FiOms4s6smKgSiMmtw1gidSXFhPXBhOcmQK8beRUHt8jtcQMErpQl79vx/hQLT/Ki30faf9uiMhXgR6O7m2REDpgQowhuaVPu/6WwgBnk/WOazVLA1VYNpUqOr5s8QDQssmZHU0gXECp8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1565963718; 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:ARC-Authentication-Results; bh=s2JI17zc3cz9W+rlQBDH1e9jPrGulxkjzI8EaGiE0pg=; b=Ui1D5LsGm09hhbbQpXIHBUg1pXjgEq3hObHfeBB9pTFwC3h1IhxL2ORSmC5icbtS9lxS71dHskTsv0OBHCz8SiW8BXjytrvAGdAvUqwqc/ko1jfHCJGjBR+Tyq+dcolWJm1I+r24leT8sb0MpTeGLC2GnLoghjvfzCrc+q27Uu4= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1565963718314344.1108445093921; Fri, 16 Aug 2019 06:55:18 -0700 (PDT) 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 mx1.redhat.com (Postfix) with ESMTPS id 223CAEC520; Fri, 16 Aug 2019 13:55:17 +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 ECF4C1822C; Fri, 16 Aug 2019 13:55:16 +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 AE2C21800202; Fri, 16 Aug 2019 13:55:16 +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 x7GDsvLf029157 for ; Fri, 16 Aug 2019 09:54:57 -0400 Received: by smtp.corp.redhat.com (Postfix) id 76C641001B17; Fri, 16 Aug 2019 13:54:57 +0000 (UTC) Received: from angien.brq.redhat.com (unknown [10.43.2.229]) by smtp.corp.redhat.com (Postfix) with ESMTP id D0CD31001B03; Fri, 16 Aug 2019 13:54:56 +0000 (UTC) From: Peter Krempa To: libvir-list@redhat.com Date: Fri, 16 Aug 2019 15:54:43 +0200 Message-Id: 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 Cc: Peter Krempa Subject: [libvirt] [PATCH 09/10] qemu: Add -blockdev support for external snapshots 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: , Content-Transfer-Encoding: quoted-printable 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-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 16 Aug 2019 13:55:17 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Use the code for creating or attaching new storage source in the snapshot code and switch to 'blockdev-snapshot' for creating the snapshot itself. Signed-off-by: Peter Krempa Reviewed-by: J=C3=A1n Tomko --- src/qemu/qemu_driver.c | 104 ++++++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 16 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6e10b691e9..c22f74adaa 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15270,6 +15270,8 @@ struct _qemuDomainSnapshotDiskData { bool prepared; /* @src was prepared using qemuDomainStorageSourceAcces= sAllow */ virDomainDiskDefPtr disk; char *relPath; /* relative path component to fill into original disk */ + qemuBlockStorageSourceChainDataPtr crdata; + bool blockdevadded; virStorageSourcePtr persistsrc; virDomainDiskDefPtr persistdisk; @@ -15283,7 +15285,8 @@ static void qemuDomainSnapshotDiskDataCleanup(qemuDomainSnapshotDiskDataPtr data, size_t ndata, virQEMUDriverPtr driver, - virDomainObjPtr vm) + virDomainObjPtr vm, + qemuDomainAsyncJob asyncJob) { size_t i; @@ -15294,6 +15297,15 @@ qemuDomainSnapshotDiskDataCleanup(qemuDomainSnapsh= otDiskDataPtr data, /* on success of the snapshot the 'src' and 'persistsrc' propertie= s will * be set to NULL by qemuDomainSnapshotUpdateDiskSources */ if (data[i].src) { + if (data[i].blockdevadded) { + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) = =3D=3D 0) { + + qemuBlockStorageSourceAttachRollback(qemuDomainGetMoni= tor(vm), + data[i].crdata->s= rcdata[0]); + ignore_value(qemuDomainObjExitMonitor(driver, vm)); + } + } + if (data[i].created && virStorageFileUnlink(data[i].src) < 0) { VIR_WARN("Unable to remove just-created %s", @@ -15312,6 +15324,7 @@ qemuDomainSnapshotDiskDataCleanup(qemuDomainSnapsho= tDiskDataPtr data, VIR_FREE(data[i].relPath); } + qemuBlockStorageSourceChainDataFree(data[i].crdata); VIR_FREE(data); } @@ -15319,15 +15332,20 @@ qemuDomainSnapshotDiskDataCleanup(qemuDomainSnaps= hotDiskDataPtr data, static int qemuDomainSnapshotDiskDataCollectOne(virQEMUDriverPtr driver, virDomainObjPtr vm, + virQEMUDriverConfigPtr cfg, virDomainDiskDefPtr disk, virDomainSnapshotDiskDefPtr snapdisk, qemuDomainSnapshotDiskDataPtr dd, - bool reuse) + bool reuse, + bool blockdev, + qemuDomainAsyncJob asyncJob) { + qemuDomainObjPrivatePtr priv =3D vm->privateData; char *backingStoreStr; virDomainDiskDefPtr persistdisk; bool supportsCreate; bool supportsBacking; + int rc; dd->disk =3D disk; @@ -15393,6 +15411,44 @@ qemuDomainSnapshotDiskDataCollectOne(virQEMUDriver= Ptr driver, dd->prepared =3D true; + if (blockdev) { + /* create a terminator for the snapsot disks so that qemu does not= try + * to open them at first */ + virObjectUnref(dd->src->backingStore); + if (!(dd->src->backingStore =3D virStorageSourceNew())) + return -1; + + if (qemuDomainPrepareStorageSourceBlockdev(dd->disk, dd->src, + priv, cfg) < 0) + return -1; + + if (!(dd->crdata =3D qemuBuildStorageSourceChainAttachPrepareBlock= devTop(dd->src, + = priv->qemuCaps))) + return -1; + + if (reuse) { + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + rc =3D qemuBlockStorageSourceAttachApply(qemuDomainGetMonitor(= vm), + dd->crdata->srcdata[0]); + + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + return -1; + } else { + if (qemuBlockStorageSourceCreateDetectSize(vm, dd->src, dd->di= sk->src, + asyncJob) < 0) + return -1; + + if (qemuBlockStorageSourceCreate(vm, dd->src, dd->disk->src, + NULL, dd->crdata->srcdata[0], + asyncJob) < 0) + return -1; + } + + dd->blockdevadded =3D true; + } + return 0; } @@ -15407,7 +15463,10 @@ static int qemuDomainSnapshotDiskDataCollect(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainMomentObjPtr snap, + virQEMUDriverConfigPtr cfg, bool reuse, + bool blockdev, + qemuDomainAsyncJob asyncJob, qemuDomainSnapshotDiskDataPtr *rdata, size_t *rndata) { @@ -15424,9 +15483,10 @@ qemuDomainSnapshotDiskDataCollect(virQEMUDriverPtr= driver, if (snapdef->disks[i].snapshot =3D=3D VIR_DOMAIN_SNAPSHOT_LOCATION= _NONE) continue; - if (qemuDomainSnapshotDiskDataCollectOne(driver, vm, vm->def->disk= s[i], + if (qemuDomainSnapshotDiskDataCollectOne(driver, vm, cfg, vm->def-= >disks[i], snapdef->disks + i, - data + ndata++, reuse) < = 0) + data + ndata++, reuse, bl= ockdev, + asyncJob) < 0) goto cleanup; } @@ -15435,7 +15495,7 @@ qemuDomainSnapshotDiskDataCollect(virQEMUDriverPtr = driver, ret =3D 0; cleanup: - qemuDomainSnapshotDiskDataCleanup(data, ndata, driver, vm); + qemuDomainSnapshotDiskDataCleanup(data, ndata, driver, vm, asyncJob); return ret; } @@ -15456,13 +15516,15 @@ qemuDomainSnapshotUpdateDiskSourcesRenumber(virSt= orageSourcePtr src) * @driver: QEMU driver * @vm: domain object * @dd: snapshot disk data object + * @blockdev: -blockdev is in use for the VM * * Updates disk definition after a successful snapshot. */ static void qemuDomainSnapshotUpdateDiskSources(virQEMUDriverPtr driver, virDomainObjPtr vm, - qemuDomainSnapshotDiskDataPtr dd) + qemuDomainSnapshotDiskDataPtr dd, + bool blockdev) { /* storage driver access won'd be needed */ if (dd->initialized) @@ -15475,11 +15537,13 @@ qemuDomainSnapshotUpdateDiskSources(virQEMUDriver= Ptr driver, dd->disk->src->readonly =3D true; VIR_STEAL_PTR(dd->disk->src->relPath, dd->relPath); + virObjectUnref(dd->src->backingStore); VIR_STEAL_PTR(dd->src->backingStore, dd->disk->src); VIR_STEAL_PTR(dd->disk->src, dd->src); /* fix numbering of disks */ - qemuDomainSnapshotUpdateDiskSourcesRenumber(dd->disk->src); + if (!blockdev) + qemuDomainSnapshotUpdateDiskSourcesRenumber(dd->disk->src); if (dd->persistdisk) { VIR_STEAL_PTR(dd->persistsrc->backingStore, dd->persistdisk->src); @@ -15506,6 +15570,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr= driver, qemuDomainSnapshotDiskDataPtr diskdata =3D NULL; size_t ndiskdata =3D 0; virErrorPtr orig_err =3D NULL; + bool blockdev =3D virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV); if (virDomainObjCheckActive(vm) < 0) return -1; @@ -15515,8 +15580,8 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr= driver, /* prepare a list of objects to use in the vm definition so that we do= n't * have to roll back later */ - if (qemuDomainSnapshotDiskDataCollect(driver, vm, snap, reuse, - &diskdata, &ndiskdata) < 0) + if (qemuDomainSnapshotDiskDataCollect(driver, vm, snap, cfg, reuse, bl= ockdev, + asyncJob, &diskdata, &ndiskdata)= < 0) goto cleanup; /* check whether there's anything to do */ @@ -15530,11 +15595,18 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverP= tr driver, * VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL with a valid file name and * qcow2 format. */ for (i =3D 0; i < ndiskdata; i++) { - if (qemuBlockSnapshotAddLegacy(actions, - diskdata[i].disk, - diskdata[i].src, - reuse) < 0) - goto cleanup; + if (blockdev) { + if (qemuBlockSnapshotAddBlockdev(actions, + diskdata[i].disk, + diskdata[i].src)) + goto cleanup; + } else { + if (qemuBlockSnapshotAddLegacy(actions, + diskdata[i].disk, + diskdata[i].src, + reuse) < 0) + goto cleanup; + } } if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) @@ -15551,7 +15623,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr= driver, virDomainAuditDisk(vm, dd->disk->src, dd->src, "snapshot", rc >=3D= 0); if (rc =3D=3D 0) - qemuDomainSnapshotUpdateDiskSources(driver, vm, dd); + qemuDomainSnapshotUpdateDiskSources(driver, vm, dd, blockdev); } if (rc < 0) @@ -15583,7 +15655,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr= driver, vm->newDef) < 0)) ret =3D -1; - qemuDomainSnapshotDiskDataCleanup(diskdata, ndiskdata, driver, vm); + qemuDomainSnapshotDiskDataCleanup(diskdata, ndiskdata, driver, vm, asy= ncJob); virErrorRestore(&orig_err); return ret; --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list