[PATCH 16/20] qemu: Support O_DIRECT with mapped-ram on restore

Jim Fehlig via Devel posted 20 patches 3 months, 2 weeks ago
[PATCH 16/20] qemu: Support O_DIRECT with mapped-ram on restore
Posted by Jim Fehlig via Devel 3 months, 2 weeks ago
When using the mapped-ram migration capability, direct IO is
enabled by setting the "direct-io" migration parameter to
"true" and passing QEMU an additional fd with O_DIRECT set.

Signed-off-by: Jim Fehlig <jfehlig@suse.com>
---
 src/qemu/qemu_migration.c | 11 ++++++-----
 src/qemu/qemu_process.c   | 30 ++++++++++++++++++++++++++----
 src/qemu/qemu_process.h   |  6 ++++--
 3 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index daa42bcfe4..56199c616b 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2948,7 +2948,8 @@ qemuMigrationDstPrepareCleanup(virQEMUDriver *driver,
 }
 
 static qemuProcessIncomingDef *
-qemuMigrationDstPrepare(virDomainObj *vm,
+qemuMigrationDstPrepare(virQEMUDriver *driver,
+                        virDomainObj *vm,
                         bool tunnel,
                         const char *protocol,
                         const char *listenAddress,
@@ -3008,8 +3009,8 @@ qemuMigrationDstPrepare(virDomainObj *vm,
         migrateFrom = g_strdup_printf(incFormat, protocol, listenAddress, port);
     }
 
-    return qemuProcessIncomingDefNew(vm, listenAddress,
-                                     migrateFrom, fd, NULL, NULL);
+    return qemuProcessIncomingDefNew(driver, vm, listenAddress,
+                                     migrateFrom, fd, NULL, NULL, NULL);
 }
 
 
@@ -3151,7 +3152,7 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver,
         goto error;
     stopProcess = true;
 
-    if (!(incoming = qemuMigrationDstPrepare(vm, tunnel, protocol,
+    if (!(incoming = qemuMigrationDstPrepare(driver, vm, tunnel, protocol,
                                              listenAddress, port,
                                              &dataFD[0])))
         goto error;
@@ -3522,7 +3523,7 @@ qemuMigrationDstPrepareResume(virQEMUDriver *driver,
 
     priv->origname = g_strdup(origname);
 
-    if (!(incoming = qemuMigrationDstPrepare(vm, false, protocol,
+    if (!(incoming = qemuMigrationDstPrepare(driver, vm, false, protocol,
                                              listenAddress, port, NULL)))
         goto cleanup;
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b02cd84aff..e10894d0f9 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4694,13 +4694,16 @@ qemuProcessIncomingDefFree(qemuProcessIncomingDef *inc)
  * qemuProcessIncomingDefFree will NOT close it.
  */
 qemuProcessIncomingDef *
-qemuProcessIncomingDefNew(virDomainObj *vm,
+qemuProcessIncomingDefNew(virQEMUDriver *driver,
+                          virDomainObj *vm,
                           const char *listenAddress,
                           const char *migrateFrom,
                           int *fd,
                           const char *path,
-                          virQEMUSaveData *data)
+                          virQEMUSaveData *data,
+                          qemuMigrationParams *migParams)
 {
+    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
     qemuDomainObjPrivate *priv = vm->privateData;
     qemuProcessIncomingDef *inc = NULL;
 
@@ -4715,10 +4718,28 @@ qemuProcessIncomingDefNew(virDomainObj *vm,
         size_t offset = sizeof(virQEMUSaveHeader) + data->header.data_len;
 
         if (data->header.features & QEMU_SAVE_FEATURE_MAPPED_RAM) {
+            bool directio = false;
             unsigned int fdsetId;
 
             inc->fdPassMigrate = qemuFDPassNew("migrate", priv);
-            qemuFDPassAddFD(inc->fdPassMigrate, fd, "-buffered-fd");
+            /* When using directio with mapped-ram, qemu needs an fd without
+             * O_DIRECT set for reading small bits of unaligned state. */
+            if (qemuMigrationParamsGetBool(migParams,
+                                           QEMU_MIGRATION_PARAM_DIRECT_IO,
+                                           &directio) < 0)
+                goto error;
+
+            if (directio) {
+                VIR_AUTOCLOSE bufferedFd = -1;
+
+                if ((bufferedFd = qemuDomainOpenFile(cfg, NULL, path, O_RDONLY, NULL)) < 0)
+                    goto error;
+
+                qemuFDPassAddFD(inc->fdPassMigrate, &bufferedFd, "-buffered-fd");
+                qemuFDPassAddFD(inc->fdPassMigrate, fd, "-directio-fd");
+            } else {
+                qemuFDPassAddFD(inc->fdPassMigrate, fd, "-buffered-fd");
+            }
             qemuFDPassGetId(inc->fdPassMigrate, &fdsetId);
             inc->uri = g_strdup_printf("file:/dev/fdset/%u,offset=%#lx", fdsetId, offset);
         } else {
@@ -8377,7 +8398,8 @@ qemuProcessStartWithMemoryState(virConnectPtr conn,
     int rc = 0;
     int ret = -1;
 
-    incoming = qemuProcessIncomingDefNew(vm, NULL, "stdio", fd, path, data);
+    incoming = qemuProcessIncomingDefNew(driver, vm, NULL, "stdio",
+                                         fd, path, data, migParams);
     if (!incoming)
         return -1;
 
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 93699da8bd..0e6aedf75d 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -58,12 +58,14 @@ struct _qemuProcessIncomingDef {
     const char *path; /* path associated with fd */
 };
 
-qemuProcessIncomingDef *qemuProcessIncomingDefNew(virDomainObj *vm,
+qemuProcessIncomingDef *qemuProcessIncomingDefNew(virQEMUDriver *driver,
+                                                  virDomainObj *vm,
                                                   const char *listenAddress,
                                                   const char *migrateFrom,
                                                   int *fd,
                                                   const char *path,
-                                                  virQEMUSaveData *data);
+                                                  virQEMUSaveData *data,
+                                                  qemuMigrationParams *migParams);
 
 void qemuProcessIncomingDefFree(qemuProcessIncomingDef *inc);
 
-- 
2.35.3