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

Re: [libvirt] [PATCH 1/3] libxl: Receive migration data in a thread



On 13.11.2014 03:36, Jim Fehlig wrote:
The libxl driver receives migration data within an IO callback invoked
by the event loop, effectively disabling the event loop while migration
occurs.

This patch moves receving of the migration data to a thread.  The
incoming connection is still accepted in the IO callback, but control
is immediately returned to the event loop after spawning the thread.

Signed-off-by: Jim Fehlig <jfehlig suse com>
---
  src/libxl/libxl_migration.c | 60 +++++++++++++++++++++++++++++++--------------
  1 file changed, 42 insertions(+), 18 deletions(-)

diff --git a/src/libxl/libxl_migration.c b/src/libxl/libxl_migration.c
index 0b562f7..1940209 100644
--- a/src/libxl/libxl_migration.c
+++ b/src/libxl/libxl_migration.c
@@ -35,6 +35,7 @@
  #include "vircommand.h"
  #include "virstring.h"
  #include "virobject.h"
+#include "virthread.h"
  #include "rpc/virnetsocket.h"
  #include "libxl_domain.h"
  #include "libxl_driver.h"
@@ -48,6 +49,7 @@ VIR_LOG_INIT("libxl.libxl_migration");
  typedef struct _libxlMigrationDstArgs {
      virObject parent;

+    int recvfd;
      virConnectPtr conn;
      virDomainObjPtr vm;
      unsigned int flags;
@@ -82,31 +84,18 @@ libxlMigrationDstArgsOnceInit(void)
  VIR_ONCE_GLOBAL_INIT(libxlMigrationDstArgs)

  static void
-libxlDoMigrateReceive(virNetSocketPtr sock,
-                      int events ATTRIBUTE_UNUSED,
-                      void *opaque)
+libxlDoMigrateReceive(void *opaque)
  {
      libxlMigrationDstArgs *args = opaque;
-    virConnectPtr conn = args->conn;
      virDomainObjPtr vm = args->vm;
      virNetSocketPtr *socks = args->socks;
      size_t nsocks = args->nsocks;
      bool paused = args->flags & VIR_MIGRATE_PAUSED;
-    libxlDriverPrivatePtr driver = conn->privateData;
-    virNetSocketPtr client_sock;
-    int recvfd = -1;
+    libxlDriverPrivatePtr driver = args->conn->privateData;
+    int recvfd = args->recvfd;
      size_t i;
      int ret;

-    if (virNetSocketAccept(sock, &client_sock) < 0) {
-        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-                       _("Fail to accept migration connection"));
-        goto cleanup;
-    }
-    VIR_DEBUG("Accepted migration connection\n");
-    recvfd = virNetSocketDupFD(client_sock, true);
-    virObjectUnref(client_sock);
-
      virObjectLock(vm);
      ret = libxlDomainStart(driver, vm, paused, recvfd);
      virObjectUnlock(vm);
@@ -114,7 +103,6 @@ libxlDoMigrateReceive(virNetSocketPtr sock,
      if (ret < 0 && !vm->persistent)
          virDomainObjListRemove(driver->domains, vm);

- cleanup:
      /* Remove all listen socks from event handler, and close them. */
      for (i = 0; i < nsocks; i++) {
          virNetSocketUpdateIOCallback(socks[i], 0);
@@ -127,6 +115,42 @@ libxlDoMigrateReceive(virNetSocketPtr sock,
      VIR_FORCE_CLOSE(recvfd);
  }

+
+static void
+libxlMigrateReceive(virNetSocketPtr sock,
+                    int events ATTRIBUTE_UNUSED,
+                    void *opaque)
+{
+    libxlMigrationDstArgs *args = opaque;
+    virNetSocketPtr client_sock;
+    int recvfd;
+    virThread thread;
+
+    /* Accept migration connection */
+    virNetSocketAccept(sock, &client_sock);
+    if (client_sock == NULL) {
+        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                       _("Failed to accept migration connection"));
+        return;
+    }
+    VIR_DEBUG("Accepted migration connection."
+              "  Spawing thread to process migration data");
+    recvfd = virNetSocketDupFD(client_sock, true);
+    virObjectUnref(client_sock);
+
+    /*
+     * Avoid blocking the event loop.  Start a thread to receive
+     * the migration data
+     */
+    args->recvfd = recvfd;
+    if (virThreadCreate(&thread, false,
+                        libxlDoMigrateReceive, args) < 0) {
+        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                       _("Failed to create thread for receiving migration data"));

I believe you want VIR_FORCE_CLOSE(args->recvfd) in case thread creation failed.

+    }
+}
+
+
  static int
  libxlDoMigrateSend(libxlDriverPrivatePtr driver,
                     virDomainObjPtr vm,
@@ -376,7 +400,7 @@ libxlDomainMigrationPrepare(virConnectPtr dconn,

          if (virNetSocketAddIOCallback(socks[i],
                                        VIR_EVENT_HANDLE_READABLE,
-                                      libxlDoMigrateReceive,
+                                      libxlMigrateReceive,
                                        args,
                                        virObjectFreeCallback) < 0)
              continue;


ACK with that fixed.

Michal


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