Patchwork migration: add timeout option for tcp migraion send/receive socket

login
register
mail settings
Submitter Zhanghaoyu (A)
Date June 29, 2013, 1:41 a.m.
Message ID <D3E216785288A145B7BC975F83A2ED103FEE6420@szxeml556-mbx.china.huawei.com>
Download mbox | patch
Permalink /patch/255703/
State New
Headers show

Comments

Zhanghaoyu (A) - June 29, 2013, 1:41 a.m.
When network disconnection occurs during live migration, the migration thread will be stuck in the function sendmsg(), as the migration socket is in ~O_NONBLOCK mode now.

Signed-off-by: Zeng Junliang <zengjunliang@huawei.com>
---
 include/migration/migration.h |    4 ++++
 migration-tcp.c               |   23 ++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletions(-)

\ No newline at end of file

Patch

diff --git a/include/migration/migration.h b/include/migration/migration.h
index f0640e0..1a56248 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -23,6 +23,8 @@ 
 #include "qapi-types.h"
 #include "exec/cpu-common.h"
 
+#define QEMU_MIGRATE_SOCKET_OP_TIMEOUT 60
+
 struct MigrationParams {
     bool blk;
     bool shared;
@@ -109,6 +111,8 @@  uint64_t xbzrle_mig_pages_transferred(void);
 uint64_t xbzrle_mig_pages_overflow(void);
 uint64_t xbzrle_mig_pages_cache_miss(void);
 
+int tcp_migration_set_socket_timeout(int fd, int optname, int timeout_in_sec);
+
 /**
  * @migrate_add_blocker - prevent migration from proceeding
  *
diff --git a/migration-tcp.c b/migration-tcp.c
index b20ee58..391db0a 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -33,7 +33,7 @@  static void tcp_wait_for_connect(int fd, void *opaque)
 {
     MigrationState *s = opaque;
 
-    if (fd < 0) {
+    if (tcp_migration_set_socket_timeout(fd, SO_SNDTIMEO, QEMU_MIGRATE_SOCKET_OP_TIMEOUT) < 0) {
         DPRINTF("migrate connect error\n");
         s->file = NULL;
         migrate_fd_error(s);
@@ -76,6 +76,10 @@  static void tcp_accept_incoming_migration(void *opaque)
         goto out;
     }
 
+    if (tcp_migration_set_socket_timeout(c, SO_RCVTIMEO, QEMU_MIGRATE_SOCKET_OP_TIMEOUT) < 0) {
+        fprintf(stderr, "set tcp migration socket receive timeout error\n");
+        goto out;
+    }
     process_incoming_migration(f);
     return;
 
@@ -95,3 +99,20 @@  void tcp_start_incoming_migration(const char *host_port, Error **errp)
     qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL,
                          (void *)(intptr_t)s);
 }
+
+int tcp_migration_set_socket_timeout(int fd, int optname, int timeout_in_sec)
+{
+    struct timeval timeout;
+    int ret = 0;
+
+    if (fd < 0 || timeout_in_sec < 0 ||
+        (optname != SO_RCVTIMEO && optname != SO_SNDTIMEO))
+        return -1;
+
+    timeout.tv_sec = timeout_in_sec;
+    timeout.tv_usec = 0;
+
+    ret = qemu_setsockopt(fd, SOL_SOCKET, optname, &timeout, sizeof(timeout));
+
+    return ret;
+}