From nobody Thu May 15 08:32:57 2025 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 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1510960728478996.9328951455989; Fri, 17 Nov 2017 15:18:48 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8B42525C4F; Fri, 17 Nov 2017 23:18:46 +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 6A9471347C; Fri, 17 Nov 2017 23:18:46 +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 2EEE41800BDC; Fri, 17 Nov 2017 23:18:46 +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 vAHNHbca005547 for ; Fri, 17 Nov 2017 18:17:37 -0500 Received: by smtp.corp.redhat.com (Postfix) id E50255D753; Fri, 17 Nov 2017 23:17:37 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-167.phx2.redhat.com [10.3.117.167]) by smtp.corp.redhat.com (Postfix) with ESMTP id ACF505D6A8 for ; Fri, 17 Nov 2017 23:17:37 +0000 (UTC) From: John Ferlan To: libvir-list@redhat.com Date: Fri, 17 Nov 2017 18:17:31 -0500 Message-Id: <20171117231731.2880-7-jferlan@redhat.com> In-Reply-To: <20171117231731.2880-1-jferlan@redhat.com> References: <20171117231731.2880-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 6/6] qemu: Allow showing the dump progress for memory only dump 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: , MIME-Version: 1.0 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.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 17 Nov 2017 23:18:47 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" https://bugzilla.redhat.com/show_bug.cgi?id=3D916061 If the QEMU version running is new enough (based on QEMU_CAPS_QUERY_DUMP) we can add a 'detach' boolean to the dump-guest-memory command in order to tell QEMU to run in a thread. Then, use the qemuDumpWaitForCompletion in order to 'watch' the dump and save the stats into the jobInfo data so that tools (such as virsh) can pick up and display the completion percentage. The processing is similar to qemuMigrationWaitForCompletion at least with respect to calling the query-dump in a while loop that gets a micro sleep in order for qemuDomainGetJobInfo to be able to pull out the changed migration stats values. As an added benefit, while the domain is being dumped, we don't lock out other commands. Signed-off-by: John Ferlan --- src/qemu/qemu_driver.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++= +--- 1 file changed, 80 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 066c778726..bcbacf6549 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3750,6 +3750,73 @@ qemuDomainManagedSaveRemove(virDomainPtr dom, unsign= ed int flags) } =20 =20 +/** + * qemuDumpWaitForCompletion: + * @driver: qemu driver data + * @vm: domain object + * @asyncJob: async job id + * + * If the query dump capability exists, then it's possible to start a + * guest memory dump operation using a thread via a 'detach' qualifier + * to the dump guest memory command. This allows the async check if the + * dump is done. + * + * Returns 0 on success, -1 on failure + */ +static int +qemuDumpWaitForCompletion(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivatePtr priv =3D vm->privateData; + qemuDomainJobInfoPtr jobInfo =3D priv->job.current; + qemuMonitorDumpStats stats; + struct timespec ts =3D { .tv_sec =3D 0, .tv_nsec =3D 50 * 1000 * 1000u= ll }; + int rv; + + do { + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + rv =3D qemuMonitorQueryDump(priv->mon, &stats); + + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0) + return -1; + + /* Save the stats in the migration stats so that a GetJobInfo + * will be able to compute the completion percentage */ + jobInfo->stats.ram_total =3D stats.total; + jobInfo->stats.ram_remaining =3D stats.total - stats.completed; + jobInfo->stats.ram_transferred =3D stats.completed; + switch (stats.status) { + case QEMU_MONITOR_DUMP_STATUS_NONE: + case QEMU_MONITOR_DUMP_STATUS_FAILED: + case QEMU_MONITOR_DUMP_STATUS_LAST: + virReportError(VIR_ERR_OPERATION_FAILED, + _("dump query failed, status=3D%d"), stats.stat= us); + return -1; + break; + + case QEMU_MONITOR_DUMP_STATUS_ACTIVE: + jobInfo->status =3D QEMU_DOMAIN_JOB_STATUS_ACTIVE; + VIR_DEBUG("dump active, bytes written=3D'%llu' remaining=3D'%l= lu'", + stats.completed, stats.total - stats.completed); + break; + + case QEMU_MONITOR_DUMP_STATUS_COMPLETED: + jobInfo->status =3D QEMU_DOMAIN_JOB_STATUS_COMPLETED; + VIR_DEBUG("dump completed, bytes written=3D'%llu'", stats.comp= leted); + break; + } + virObjectUnlock(vm); + nanosleep(&ts, NULL); + virObjectLock(vm); + } while (stats.status =3D=3D QEMU_MONITOR_DUMP_STATUS_ACTIVE); + + return 0; +} + + static int qemuDumpToFd(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -3758,6 +3825,7 @@ qemuDumpToFd(virQEMUDriverPtr driver, const char *dumpformat) { qemuDomainObjPrivatePtr priv =3D vm->privateData; + bool detach =3D false; int ret =3D -1; =20 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY)) { @@ -3766,10 +3834,13 @@ qemuDumpToFd(virQEMUDriverPtr driver, return -1; } =20 + detach =3D virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_DUMP); + if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, fd) = < 0) return -1; =20 - VIR_FREE(priv->job.current); + if (!detach) + VIR_FREE(priv->job.current); priv->job.dump_memory_only =3D true; =20 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) @@ -3784,15 +3855,20 @@ qemuDumpToFd(virQEMUDriverPtr driver, "for this QEMU binary"), dumpformat); ret =3D -1; + ignore_value(qemuDomainObjExitMonitor(driver, vm)); goto cleanup; } } =20 - ret =3D qemuMonitorDumpToFd(priv->mon, fd, dumpformat, false); + ret =3D qemuMonitorDumpToFd(priv->mon, fd, dumpformat, detach); =20 - cleanup: - ignore_value(qemuDomainObjExitMonitor(driver, vm)); + if ((qemuDomainObjExitMonitor(driver, vm) < 0) || ret < 0) + goto cleanup; =20 + if (detach) + ret =3D qemuDumpWaitForCompletion(driver, vm, asyncJob); + + cleanup: return ret; } =20 --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list