@@ -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
*
@@ -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;
+}
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