[libvirt] [PATCHv4 06/15] qemu: allow simple domain save to use fd: protocol

Eric Blake eblake at redhat.com
Thu Mar 10 01:45:46 UTC 2011


This allows direct saves (no compression, no root-squash NFS) to use
the more efficient fd: migration, which in turn avoids a race where
qemu exec: migration can sometimes fail because qemu does a generic
waitpid() that conflicts with the pclose() used by exec:.  Further
patches will solve compression and root-squash NFS.

* src/qemu/qemu_driver.c (qemudDomainSaveFlag): Use new function
when there is no compression.
---
 src/qemu/qemu_driver.c |   26 +++++++++++++++++++++++---
 1 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2d11da8..c4d3c85 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1790,6 +1790,7 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom,
     int is_reg = 0;
     unsigned long long offset;
     virCgroupPtr cgroup = NULL;
+    virBitmapPtr qemuCaps = NULL;

     memset(&header, 0, sizeof(header));
     memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
@@ -1820,6 +1821,11 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom,
         }
     }

+    if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch,
+                                   NULL,
+                                   &qemuCaps) < 0)
+        goto endjob;
+
     /* Get XML for the domain */
     xml = virDomainDefFormat(vm->def, VIR_DOMAIN_XML_SECURE);
     if (!xml) {
@@ -1980,10 +1986,23 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom,

     if (header.compressed == QEMUD_SAVE_FORMAT_RAW) {
         const char *args[] = { "cat", NULL };
+        /* XXX gross - why don't we reuse the fd already opened earlier */
+        int fd = -1;
+
+        if (qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
+            priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX)
+            fd = open(path, O_WRONLY);
         qemuDomainObjEnterMonitorWithDriver(driver, vm);
-        rc = qemuMonitorMigrateToFile(priv->mon,
-                                      QEMU_MONITOR_MIGRATE_BACKGROUND,
-                                      args, path, offset);
+        if (fd >= 0 && lseek(fd, offset, SEEK_SET) == offset) {
+            rc = qemuMonitorMigrateToFd(priv->mon,
+                                        QEMU_MONITOR_MIGRATE_BACKGROUND,
+                                        fd);
+        } else {
+            rc = qemuMonitorMigrateToFile(priv->mon,
+                                          QEMU_MONITOR_MIGRATE_BACKGROUND,
+                                          args, path, offset);
+        }
+        VIR_FORCE_CLOSE(fd);
         qemuDomainObjExitMonitorWithDriver(driver, vm);
     } else {
         const char *prog = qemudSaveCompressionTypeToString(header.compressed);
@@ -2065,6 +2084,7 @@ endjob:
     }

 cleanup:
+    qemuCapsFree(qemuCaps);
     VIR_FREE(xml);
     if (ret != 0 && is_reg)
         unlink(path);
-- 
1.7.4




More information about the libvir-list mailing list