From nobody Mon Feb 9 13:35:49 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 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1551937763718407.2899991327464; Wed, 6 Mar 2019 21:49:23 -0800 (PST) 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 075222DA986; Thu, 7 Mar 2019 05:49:22 +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 D77F460DB4; Thu, 7 Mar 2019 05:49:21 +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 9E6493D388; Thu, 7 Mar 2019 05:49:21 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x275moDD004129 for ; Thu, 7 Mar 2019 00:48:50 -0500 Received: by smtp.corp.redhat.com (Postfix) id 4AA4B5D78F; Thu, 7 Mar 2019 05:48:50 +0000 (UTC) Received: from blue.redhat.com (ovpn-118-35.phx2.redhat.com [10.3.118.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4BF1E5D783; Thu, 7 Mar 2019 05:48:49 +0000 (UTC) From: Eric Blake To: libvir-list@redhat.com Date: Wed, 6 Mar 2019 23:47:51 -0600 Message-Id: <20190307054752.19522-20-eblake@redhat.com> In-Reply-To: <20190307054752.19522-1-eblake@redhat.com> References: <20190307054752.19522-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Cc: amureini@redhat.com, derez@redhat.com, vsementsov@virtuozzo.com, zhanhouliang@outlook.com, bharadwaj.rayala@rubrik.com, ydary@redhat.com, nsoffer@redhat.com, jsnow@redhat.com, suman.swaroop@rubrik.com Subject: [libvirt] [PATCH v5 19/20] wip: backup: qemu: Wire up qemu full push backup commands over QMP 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.29]); Thu, 07 Mar 2019 05:49:22 +0000 (UTC) Content-Type: text/plain; charset="utf-8" wip: still need to polish event code, cleanup properly on errors Update the code to support push backups; for now, the destination file still has to be local, although the XML could be extended into supporting remote destinations (where we will have to use the full power of blockdev-add). This also touches up the event handling to inform the user when the job is complete. Signed-off-by: Eric Blake --- src/qemu/qemu_driver.c | 81 +++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 25 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 76b72acbef..03506460a8 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -18030,14 +18030,13 @@ qemuDomainBackupPrepare(virQEMUDriverPtr driver, = virDomainObjPtr vm, /* Called while monitor lock is held. Best-effort cleanup. */ static int qemuDomainBackupDiskCleanup(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainBackupDiskDef *disk, bool incremental) + virDomainBackupDiskDef *disk, bool push, + bool incremental, bool completed) { qemuDomainObjPrivatePtr priv =3D vm->privateData; const char *node =3D vm->def->disks[disk->idx]->src->nodeformat; int ret =3D 0; - if (!disk->store) - return 0; if (disk->state >=3D VIR_DOMAIN_BACKUP_DISK_STATE_EXPORT) { /* No real need to use nbd-server-remove, since we will * shortly be calling nbd-server-stop. */ @@ -18050,16 +18049,17 @@ qemuDomainBackupDiskCleanup(virQEMUDriverPtr driv= er, virDomainObjPtr vm, } if (disk->state >=3D VIR_DOMAIN_BACKUP_DISK_STATE_READY && qemuMonitorBlockdevDel(priv->mon, disk->store->nodeformat) < 0) { - VIR_WARN("Unable to remove temp disk %s after backup", - disk->name); + VIR_WARN("Unable to remove %s disk %s after backup", + push ? "target" : "scratch", disk->name); ret =3D -1; } if (disk->state >=3D VIR_DOMAIN_BACKUP_DISK_STATE_LABEL) qemuDomainDiskChainElementRevoke(driver, vm, disk->store); - if (disk->state >=3D VIR_DOMAIN_BACKUP_DISK_STATE_CREATED && + if ((!push || !completed) && + disk->state >=3D VIR_DOMAIN_BACKUP_DISK_STATE_CREATED && disk->store->detected && unlink(disk->store->path) < 0) { - VIR_WARN("Unable to unlink temp disk %s after backup", - disk->store->path); + VIR_WARN("Unable to unlink %s disk %s after backup", + push ? "failed target" : "scratch", disk->store->path); ret =3D -1; } return ret; @@ -18079,6 +18079,7 @@ qemuDomainBackupBegin(virDomainPtr domain, const ch= ar *diskXml, virJSONValuePtr json =3D NULL; bool job_started =3D false; bool nbd_running =3D false; + bool push; size_t i; struct timeval tv; char *suffix =3D NULL; @@ -18127,7 +18128,8 @@ qemuDomainBackupBegin(virDomainPtr domain, const ch= ar *diskXml, if (!(def =3D virDomainBackupDefParseString(diskXml, driver->xmlopt, 0= ))) goto cleanup; - if (def->type =3D=3D VIR_DOMAIN_BACKUP_TYPE_PULL) { + push =3D def->type =3D=3D VIR_DOMAIN_BACKUP_TYPE_PUSH; + if (!push) { if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_BITMAP)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("qemu binary lacks pull-mode backup support")= ); @@ -18139,10 +18141,6 @@ qemuDomainBackupBegin(virDomainPtr domain, const c= har *diskXml, _(" must specify TCP server for n= ow")); goto cleanup; } - } else { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("push mode backups not supported yet")); - goto cleanup; } if (def->incremental) { if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BITMAP_MERGE)) { @@ -18223,6 +18221,7 @@ qemuDomainBackupBegin(virDomainPtr domain, const ch= ar *diskXml, cmd =3D NULL; } + /* FIXME: allow non-local files for push destinations */ if (virJSONValueObjectCreate(&file, "s:driver", "file", "s:filename", disk->store->path, @@ -18263,7 +18262,7 @@ qemuDomainBackupBegin(virDomainPtr domain, const ch= ar *diskXml, "blockdev-backup", "s:device", src->nodeformat, "s:target", disk->store->nodefor= mat, - "s:sync", "none", + "s:sync", push ? "full" : "none", "s:job-id", disk->name, NULL) < 0) goto endmon; @@ -18276,7 +18275,7 @@ qemuDomainBackupBegin(virDomainPtr domain, const ch= ar *diskXml, - pull: nbd-server-start with from user (or autogenerate s= erver) - pull: nbd-server-add per , including bitmap for incr */ - if (def->type =3D=3D VIR_DOMAIN_BACKUP_TYPE_PULL) { + if (!push) { if (qemuMonitorNBDServerStart(priv->mon, def->server->name, def->server->port, NULL) < 0) goto endmon; @@ -18308,11 +18307,14 @@ qemuDomainBackupBegin(virDomainPtr domain, const = char *diskXml, for (i =3D 0; i < def->ndisks; i++) { virDomainBackupDiskDef *disk =3D &def->disks[i]; + if (!disk->store) + continue; if (job_started && qemuMonitorBlockJobCancel(priv->mon, disk->name) < 0) VIR_WARN("Unable to stop backup job %s on vm %s after fail= ure", disk->store->nodeformat, vm->def->name); - qemuDomainBackupDiskCleanup(driver, vm, disk, !!def->increment= al); + qemuDomainBackupDiskCleanup(driver, vm, disk, push, + !!def->incremental, false); } virSetError(save_err); virFreeError(save_err); @@ -18387,6 +18389,8 @@ static int qemuDomainBackupEnd(virDomainPtr domain,= int id, unsigned int flags) bool want_abort =3D flags & VIR_DOMAIN_BACKUP_END_ABORT; virDomainBackupDefPtr def; size_t i; + bool push =3D true; + bool completed =3D true; virCheckFlags(VIR_DOMAIN_BACKUP_END_ABORT, -1); @@ -18405,23 +18409,50 @@ static int qemuDomainBackupEnd(virDomainPtr domai= n, int id, unsigned int flags) goto cleanup; } - if (priv->backup->type !=3D VIR_DOMAIN_BACKUP_TYPE_PUSH) - want_abort =3D false; def =3D priv->backup; + if (def->type !=3D VIR_DOMAIN_BACKUP_TYPE_PUSH) { + want_abort =3D false; + push =3D false; + } /* We are going to modify the domain below. */ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; qemuDomainObjEnterMonitor(driver, vm); - if (def->type =3D=3D VIR_DOMAIN_BACKUP_TYPE_PULL) + if (push) { + for (i =3D 0; i < def->ndisks; i++) { + virDomainBackupDiskDef *disk =3D &def->disks[i]; + + if (!disk->store) + continue; + if (disk->state !=3D VIR_DOMAIN_BACKUP_DISK_STATE_COMPLETE) + completed =3D false; + } + } else { ret =3D qemuMonitorNBDServerStop(priv->mon); - for (i =3D 0; i < def->ndisks; i++) { - if (qemuMonitorBlockJobCancel(priv->mon, - def->disks[i].name) < 0 || - qemuDomainBackupDiskCleanup(driver, vm, &def->disks[i], - !!def->incremental) < 0) - ret =3D -1; + } + if (!completed && !want_abort) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("backup job id '%d' not complete yet"), id); + } else { + for (i =3D 0; i < def->ndisks; i++) { + virDomainBackupDiskDef *disk =3D &def->disks[i]; + + if (!disk->store) + continue; + if (!push || disk->state < VIR_DOMAIN_BACKUP_DISK_STATE_COMPLE= TE) { + if (qemuMonitorBlockJobCancel(priv->mon, + disk->name) < 0 && + !want_abort) { + ret =3D -1; + continue; + } + } + if (qemuDomainBackupDiskCleanup(driver, vm, disk, push, + !!def->incremental, completed)= < 0) + ret =3D -1; + } } if (qemuDomainObjExitMonitor(driver, vm) < 0 || ret < 0) { ret =3D -1; --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list