[libvirt] [REBASE PATCH v2 8/9] qemu: Allow showing the dump progress for memory only dump

John Ferlan posted 9 patches 7 years, 3 months ago
There is a newer version of this series
[libvirt] [REBASE PATCH v2 8/9] qemu: Allow showing the dump progress for memory only dump
Posted by John Ferlan 7 years, 3 months ago
https://bugzilla.redhat.com/show_bug.cgi?id=916061

If the QEMU version running is new enough (based on the DUMP_COMPLETED
event), then we can add a 'detach' boolean to the dump-guest-memory
command in order to tell QEMU to run in a thread. This ensures that we
don't lock out other commands while the potentially long running dump
memory is completed.

This allows the usage of a qemuDumpWaitForCompletion which will wait
for the event while the qemuDomainGetJobInfoDumpStats can be used via
qemuDomainGetJobInfo in order to query QEMU in order to determine
how far along the job is.

Signed-off-by: John Ferlan <jferlan@redhat.com>
---
 src/qemu/qemu_driver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index adf66228b..efb3652df 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3758,6 +3758,34 @@ qemuDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
 }
 
 
+/**
+ * qemuDumpWaitForCompletion:
+ * @vm: domain object
+ *
+ * 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(virDomainObjPtr vm)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+
+    if (!priv->job.dumpCompletion)
+        return 0;
+
+    VIR_DEBUG("Waiting for dump completion");
+    while (!priv->job.dumpCompleted && !priv->job.abortJob) {
+        if (virDomainObjWait(vm) < 0)
+            return -1;
+    }
+    return 0;
+}
+
+
 static int
 qemuDumpToFd(virQEMUDriverPtr driver,
              virDomainObjPtr vm,
@@ -3766,6 +3794,7 @@ qemuDumpToFd(virQEMUDriverPtr driver,
              const char *dumpformat)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    bool detach = false;
     int ret = -1;
 
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY)) {
@@ -3774,10 +3803,13 @@ qemuDumpToFd(virQEMUDriverPtr driver,
         return -1;
     }
 
+    detach = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_COMPLETED);
+
     if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, fd) < 0)
         return -1;
 
-    VIR_FREE(priv->job.current);
+    if (!detach)
+        VIR_FREE(priv->job.current);
     priv->job.dump_memory_only = true;
 
     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
@@ -3792,15 +3824,23 @@ qemuDumpToFd(virQEMUDriverPtr driver,
                              "for this QEMU binary"),
                            dumpformat);
             ret = -1;
+            ignore_value(qemuDomainObjExitMonitor(driver, vm));
             goto cleanup;
         }
     }
 
-    ret = qemuMonitorDumpToFd(priv->mon, fd, dumpformat, false);
+    ret = qemuMonitorDumpToFd(priv->mon, fd, dumpformat, detach);
 
- cleanup:
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    if (detach && ret == 0)
+        priv->job.dumpCompletion = true;
+
+    if ((qemuDomainObjExitMonitor(driver, vm) < 0) || ret < 0)
+        goto cleanup;
+
+    if (detach)
+        ret = qemuDumpWaitForCompletion(vm);
 
+ cleanup:
     return ret;
 }
 
-- 
2.13.6

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REBASE PATCH v2 8/9] qemu: Allow showing the dump progress for memory only dump
Posted by Jiri Denemark 7 years, 3 months ago
On Fri, Jan 19, 2018 at 14:53:15 -0500, John Ferlan wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=916061
> 
> If the QEMU version running is new enough (based on the DUMP_COMPLETED
> event), then we can add a 'detach' boolean to the dump-guest-memory
> command in order to tell QEMU to run in a thread. This ensures that we
> don't lock out other commands while the potentially long running dump
> memory is completed.
> 
> This allows the usage of a qemuDumpWaitForCompletion which will wait
> for the event while the qemuDomainGetJobInfoDumpStats can be used via
> qemuDomainGetJobInfo in order to query QEMU in order to determine
> how far along the job is.
> 
> Signed-off-by: John Ferlan <jferlan@redhat.com>
> ---
>  src/qemu/qemu_driver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 44 insertions(+), 4 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index adf66228b..efb3652df 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -3758,6 +3758,34 @@ qemuDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
>  }
>  
>  
> +/**
> + * qemuDumpWaitForCompletion:
> + * @vm: domain object
> + *
> + * 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(virDomainObjPtr vm)
> +{
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +
> +    if (!priv->job.dumpCompletion)
> +        return 0;

This condition can never be true in your code. You can just drop it
while dropping dumpCompletion.

> +
> +    VIR_DEBUG("Waiting for dump completion");
> +    while (!priv->job.dumpCompleted && !priv->job.abortJob) {
> +        if (virDomainObjWait(vm) < 0)
> +            return -1;
> +    }
> +    return 0;
> +}
> +
> +
>  static int
>  qemuDumpToFd(virQEMUDriverPtr driver,
>               virDomainObjPtr vm,
> @@ -3766,6 +3794,7 @@ qemuDumpToFd(virQEMUDriverPtr driver,
>               const char *dumpformat)
>  {
>      qemuDomainObjPrivatePtr priv = vm->privateData;
> +    bool detach = false;
>      int ret = -1;
>  
>      if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY)) {
> @@ -3774,10 +3803,13 @@ qemuDumpToFd(virQEMUDriverPtr driver,
>          return -1;
>      }
>  
> +    detach = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_COMPLETED);
> +
>      if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, fd) < 0)
>          return -1;
>  
> -    VIR_FREE(priv->job.current);
> +    if (!detach)
> +        VIR_FREE(priv->job.current);
>      priv->job.dump_memory_only = true;
>  
>      if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
> @@ -3792,15 +3824,23 @@ qemuDumpToFd(virQEMUDriverPtr driver,
>                               "for this QEMU binary"),
>                             dumpformat);
>              ret = -1;
> +            ignore_value(qemuDomainObjExitMonitor(driver, vm));
>              goto cleanup;
>          }
>      }
>  
> -    ret = qemuMonitorDumpToFd(priv->mon, fd, dumpformat, false);
> +    ret = qemuMonitorDumpToFd(priv->mon, fd, dumpformat, detach);
>  
> - cleanup:
> -    ignore_value(qemuDomainObjExitMonitor(driver, vm));
> +    if (detach && ret == 0)
> +        priv->job.dumpCompletion = true;
> +
> +    if ((qemuDomainObjExitMonitor(driver, vm) < 0) || ret < 0)
> +        goto cleanup;
> +
> +    if (detach)
> +        ret = qemuDumpWaitForCompletion(vm);

We should update job.completed at this point.

>  
> + cleanup:
>      return ret;
>  }

Jirka

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list