[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 2/2 v2] qemu: try to use qemu's dump-guest-meory when vm uses host device



---
 src/qemu/qemu_domain.c |    1 +
 src/qemu/qemu_domain.h |    1 +
 src/qemu/qemu_driver.c |   42 ++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 69d9e6e..e3a668a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -158,6 +158,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv)
     job->phase = 0;
     job->mask = DEFAULT_JOB_MASK;
     job->start = 0;
+    job->qemu_dump = false;
     memset(&job->info, 0, sizeof(job->info));
 }
 
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index adccfed..f1ab0e6 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -97,6 +97,7 @@ struct qemuDomainJobObj {
     int phase;                          /* Job phase (mainly for migrations) */
     unsigned long long mask;            /* Jobs allowed during async job */
     unsigned long long start;           /* When the async job started */
+    bool qemu_dump;                     /* use qemu dump to do dump */
     virDomainJobInfo info;              /* Async job progress data */
 };
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d9e35be..fb14734 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2953,6 +2953,31 @@ cleanup:
     return ret;
 }
 
+/* Return 0 on success, -1 on failure, or -2 if not supported. */
+static int qemuDumpToFd(struct qemud_driver *driver, virDomainObjPtr vm,
+                        int fd, enum qemuDomainAsyncJob asyncJob)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int ret = -1;
+
+    if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD))
+        return -2;
+
+    if (virSecurityManagerSetImageFDLabel(driver->securityManager, vm->def,
+                                          fd) < 0)
+        return -1;
+
+    priv->job.qemu_dump = true;
+
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        return -1;
+
+    ret = qemuMonitorDumpToFd(priv->mon, 0, fd, 0, 0);
+    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+    return ret;
+}
+
 static int
 doCoreDump(struct qemud_driver *driver,
            virDomainObjPtr vm,
@@ -2984,6 +3009,19 @@ doCoreDump(struct qemud_driver *driver,
                            NULL, NULL)) < 0)
         goto cleanup;
 
+    if (vm->def->nhostdevs > 0) {
+        /*
+         * If the guest uses host devices, migrate command will fail. So we
+         * should use dump command.
+         *
+         * qemu dump does not support fd that is associated with a pipe,
+         * socket, or FIFO. So we should call qemuDumpTpFd() before calling
+         * virFileWrapperFdNew(). */
+        ret = qemuDumpToFd(driver, vm, fd, QEMU_ASYNC_JOB_DUMP);
+        if (ret != -2)
+            goto cleanup;
+    }
+
     if (!(wrapperFd = virFileWrapperFdNew(&fd, path, flags)))
         goto cleanup;
 
@@ -9332,7 +9370,7 @@ static int qemuDomainGetJobInfo(virDomainPtr dom,
     priv = vm->privateData;
 
     if (virDomainObjIsActive(vm)) {
-        if (priv->job.asyncJob) {
+        if (priv->job.asyncJob && !priv->job.qemu_dump) {
             memcpy(info, &priv->job.info, sizeof(*info));
 
             /* Refresh elapsed time again just to ensure it
@@ -9390,7 +9428,7 @@ static int qemuDomainAbortJob(virDomainPtr dom) {
 
     priv = vm->privateData;
 
-    if (!priv->job.asyncJob) {
+    if (!priv->job.asyncJob || priv->job.qemu_dump) {
         qemuReportError(VIR_ERR_OPERATION_INVALID,
                         "%s", _("no job is active on the domain"));
         goto endjob;
-- 
1.7.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]