[libvirt] [PATCH 16/8] save: support O_DIRECT during qemu restore

Eric Blake eblake at redhat.com
Sat Jul 16 23:09:06 UTC 2011


Wire up the restore direction to use iohelper for O_DIRECT.

* src/qemu/qemu_driver.c (qemuddDomainObjStart)
(qemuDomainSaveImageOpen, qemuDomainObjRestore)
(qemuDomainObjStart): Add parameter.
(qemudDomainStartWithFlags, qemuAutostartDomain)
(qemuDomainRestoreFlags): Update callers.
---

Could be squashed into 8/8.

 src/qemu/qemu_driver.c |   80 ++++++++++++++++++++++++++++++-----------------
 1 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a42ff8e..27b971f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -117,11 +117,12 @@ static void processWatchdogEvent(void *data, void *opaque);

 static int qemudShutdown(void);

-static int qemudDomainObjStart(virConnectPtr conn,
-                               struct qemud_driver *driver,
-                               virDomainObjPtr vm,
-                               bool start_paused,
-                               bool autodestroy);
+static int qemuDomainObjStart(virConnectPtr conn,
+                              struct qemud_driver *driver,
+                              virDomainObjPtr vm,
+                              bool start_paused,
+                              bool autodestroy,
+                              bool direct);

 static int qemudDomainGetMaxVcpus(virDomainPtr dom);

@@ -149,9 +150,11 @@ qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaq
                   vm->def->name,
                   err ? err->message : _("unknown error"));
     } else {
+        /* XXX need to wire direct autostart into qemu.conf */
         if (vm->autostart &&
             !virDomainObjIsActive(vm) &&
-            qemudDomainObjStart(data->conn, data->driver, vm, false, false) < 0) {
+            qemuDomainObjStart(data->conn, data->driver, vm,
+                               false, false, false) < 0) {
             err = virGetLastError();
             VIR_ERROR(_("Failed to autostart VM '%s': %s"),
                       vm->def->name,
@@ -3604,18 +3607,20 @@ cleanup:
     return ret;
 }

-static int ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
+static int ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(6)
 qemuDomainSaveImageOpen(struct qemud_driver *driver,
                         const char *path,
                         virDomainDefPtr *ret_def,
-                        struct qemud_save_header *ret_header)
+                        struct qemud_save_header *ret_header,
+                        bool direct, virDirectFdPtr *directFd)
 {
     int fd;
     struct qemud_save_header header;
     char *xml = NULL;
     virDomainDefPtr def = NULL;

-    if ((fd = virFileOpenAs(path, O_RDONLY, 0, getuid(), getgid(), 0)) < 0) {
+    if ((fd = virFileOpenAs(path, O_RDONLY | (direct ? O_DIRECT : 0), 0,
+                            getuid(), getgid(), 0)) < 0) {
         if ((fd != -EACCES && fd != -EPERM) ||
             driver->user == getuid()) {
             qemuReportError(VIR_ERR_OPERATION_FAILED,
@@ -3625,7 +3630,7 @@ qemuDomainSaveImageOpen(struct qemud_driver *driver,

         /* Opening as root failed, but qemu runs as a different user
          * that might have better luck. */
-        if ((fd = virFileOpenAs(path, O_RDONLY, 0,
+        if ((fd = virFileOpenAs(path, O_RDONLY | (direct ? O_DIRECT : 0), 0,
                                 driver->user, driver->group,
                                 VIR_FILE_OPEN_AS_UID)) < 0) {
             qemuReportError(VIR_ERR_OPERATION_FAILED,
@@ -3633,6 +3638,8 @@ qemuDomainSaveImageOpen(struct qemud_driver *driver,
             goto error;
         }
     }
+    if (direct && (*directFd = virDirectFdNew(&fd, path)) == NULL)
+        goto error;

     if (saferead(fd, &header, sizeof(header)) != sizeof(header)) {
         qemuReportError(VIR_ERR_OPERATION_FAILED,
@@ -3811,8 +3818,9 @@ qemuDomainRestoreFlags(virConnectPtr conn,
     int fd = -1;
     int ret = -1;
     struct qemud_save_header header;
+    virDirectFdPtr directFd = NULL;

-    virCheckFlags(0, -1);
+    virCheckFlags(VIR_DOMAIN_SAVE_DIRECT, -1);
     if (dxml) {
         qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                         _("xml modification unsupported"));
@@ -3821,7 +3829,8 @@ qemuDomainRestoreFlags(virConnectPtr conn,

     qemuDriverLock(driver);

-    fd = qemuDomainSaveImageOpen(driver, path, &def, &header);
+    fd = qemuDomainSaveImageOpen(driver, path, &def, &header,
+                                 flags & VIR_DOMAIN_SAVE_DIRECT, &directFd);
     if (fd < 0)
         goto cleanup;

@@ -3840,6 +3849,8 @@ qemuDomainRestoreFlags(virConnectPtr conn,
         goto cleanup;

     ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path);
+    if (virDirectFdClose(directFd) < 0)
+        VIR_WARN("Failed to close %s", path);

     if (qemuDomainObjEndJob(driver, vm) == 0)
         vm = NULL;
@@ -3851,6 +3862,7 @@ qemuDomainRestoreFlags(virConnectPtr conn,
 cleanup:
     virDomainDefFree(def);
     VIR_FORCE_CLOSE(fd);
+    virDirectFdFree(directFd);
     if (vm)
         virDomainObjUnlock(vm);
     qemuDriverUnlock(driver);
@@ -3868,14 +3880,17 @@ static int
 qemuDomainObjRestore(virConnectPtr conn,
                      struct qemud_driver *driver,
                      virDomainObjPtr vm,
-                     const char *path)
+                     const char *path,
+                     bool direct)
 {
     virDomainDefPtr def = NULL;
     int fd = -1;
     int ret = -1;
     struct qemud_save_header header;
+    virDirectFdPtr directFd = NULL;

-    fd = qemuDomainSaveImageOpen(driver, path, &def, &header);
+    fd = qemuDomainSaveImageOpen(driver, path, &def, &header,
+                                 direct, &directFd);
     if (fd < 0)
         goto cleanup;

@@ -3897,10 +3912,13 @@ qemuDomainObjRestore(virConnectPtr conn,
     def = NULL;

     ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path);
+    if (virDirectFdClose(directFd) < 0)
+        VIR_WARN("Failed to close %s", path);

 cleanup:
     virDomainDefFree(def);
     VIR_FORCE_CLOSE(fd);
+    virDirectFdFree(directFd);
     return ret;
 }

@@ -4114,11 +4132,13 @@ static int qemudNumDefinedDomains(virConnectPtr conn) {
 }


-static int qemudDomainObjStart(virConnectPtr conn,
-                               struct qemud_driver *driver,
-                               virDomainObjPtr vm,
-                               bool start_paused,
-                               bool autodestroy)
+static int
+qemuDomainObjStart(virConnectPtr conn,
+                   struct qemud_driver *driver,
+                   virDomainObjPtr vm,
+                   bool start_paused,
+                   bool autodestroy,
+                   bool direct)
 {
     int ret = -1;
     char *managed_save;
@@ -4133,7 +4153,7 @@ static int qemudDomainObjStart(virConnectPtr conn,
         goto cleanup;

     if (virFileExists(managed_save)) {
-        ret = qemuDomainObjRestore(conn, driver, vm, managed_save);
+        ret = qemuDomainObjRestore(conn, driver, vm, managed_save, direct);

         if ((ret == 0) && (unlink(managed_save) < 0))
             VIR_WARN("Failed to remove the managed state %s", managed_save);
@@ -4159,14 +4179,15 @@ cleanup:
 }

 static int
-qemudDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
+qemuDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
 {
     struct qemud_driver *driver = dom->conn->privateData;
     virDomainObjPtr vm;
     int ret = -1;

     virCheckFlags(VIR_DOMAIN_START_PAUSED |
-                  VIR_DOMAIN_START_AUTODESTROY, -1);
+                  VIR_DOMAIN_START_AUTODESTROY |
+                  VIR_DOMAIN_START_DIRECT, -1);

     qemuDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -4188,9 +4209,10 @@ qemudDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
         goto endjob;
     }

-    if (qemudDomainObjStart(dom->conn, driver, vm,
-                            (flags & VIR_DOMAIN_START_PAUSED) != 0,
-                            (flags & VIR_DOMAIN_START_AUTODESTROY) != 0) < 0)
+    if (qemuDomainObjStart(dom->conn, driver, vm,
+                           (flags & VIR_DOMAIN_START_PAUSED) != 0,
+                           (flags & VIR_DOMAIN_START_AUTODESTROY) != 0,
+                           (flags & VIR_DOMAIN_START_DIRECT) != 0) < 0)
         goto endjob;

     ret = 0;
@@ -4207,9 +4229,9 @@ cleanup:
 }

 static int
-qemudDomainStart(virDomainPtr dom)
+qemuDomainStart(virDomainPtr dom)
 {
-    return qemudDomainStartWithFlags(dom, 0);
+    return qemuDomainStartWithFlags(dom, 0);
 }

 static int
@@ -8615,8 +8637,8 @@ static virDriver qemuDriver = {
     .domainXMLToNative = qemuDomainXMLToNative, /* 0.6.4 */
     .listDefinedDomains = qemudListDefinedDomains, /* 0.2.0 */
     .numOfDefinedDomains = qemudNumDefinedDomains, /* 0.2.0 */
-    .domainCreate = qemudDomainStart, /* 0.2.0 */
-    .domainCreateWithFlags = qemudDomainStartWithFlags, /* 0.8.2 */
+    .domainCreate = qemuDomainStart, /* 0.2.0 */
+    .domainCreateWithFlags = qemuDomainStartWithFlags, /* 0.8.2 */
     .domainDefineXML = qemudDomainDefine, /* 0.2.0 */
     .domainUndefine = qemudDomainUndefine, /* 0.2.0 */
     .domainAttachDevice = qemuDomainAttachDevice, /* 0.4.1 */
-- 
1.7.4.4




More information about the libvir-list mailing list