From patchwork Tue Jun 1 15:40:19 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yoshiaki Tamura X-Patchwork-Id: 54228 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 20F07B7D20 for ; Wed, 2 Jun 2010 01:45:28 +1000 (EST) Received: from localhost ([127.0.0.1]:42190 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OJTef-0003oy-C9 for incoming@patchwork.ozlabs.org; Tue, 01 Jun 2010 11:45:25 -0400 Received: from [140.186.70.92] (port=59382 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OJTay-00021J-09 for qemu-devel@nongnu.org; Tue, 01 Jun 2010 11:41:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OJTav-0003SQ-7Z for qemu-devel@nongnu.org; Tue, 01 Jun 2010 11:41:35 -0400 Received: from sh.osrg.net ([192.16.179.4]:51197) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OJTau-0003Qo-NA for qemu-devel@nongnu.org; Tue, 01 Jun 2010 11:41:33 -0400 Received: from fs.osrg.net (postfix@fs.osrg.net [10.0.0.12]) by sh.osrg.net (8.14.3/8.14.3/OSRG-NET) with ESMTP id o51FfRVa024005; Wed, 2 Jun 2010 00:41:27 +0900 Received: from localhost (hype-wd0.osrg.net [10.72.1.16]) by fs.osrg.net (Postfix) with ESMTP id 7E5113E02CC; Wed, 2 Jun 2010 00:41:27 +0900 (JST) From: Yoshiaki Tamura To: qemu-devel@nongnu.org Date: Wed, 2 Jun 2010 00:40:19 +0900 Message-Id: <1275406821-30024-3-git-send-email-tamura.yoshiaki@lab.ntt.co.jp> X-Mailer: git-send-email 1.7.0.31.g1df487 In-Reply-To: <1275406821-30024-1-git-send-email-tamura.yoshiaki@lab.ntt.co.jp> References: <1275406821-30024-1-git-send-email-tamura.yoshiaki@lab.ntt.co.jp> X-Dispatcher: imput version 20070423(IM149) Lines: 160 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-3.0 (sh.osrg.net [192.16.179.4]); Wed, 02 Jun 2010 00:41:28 +0900 (JST) X-Virus-Scanned: clamav-milter 0.96 at sh X-Virus-Status: Clean X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: aliguori@us.ibm.com, Yoshiaki Tamura Subject: [Qemu-devel] [PATCH 2/4] migration-tcp: threaded tcp incoming migration. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Create a thread to handle tcp incoming migration when CONFIG_IOTHREAD is enabled. Spawned thread writes it's return status to th_fds[1] before exit, and main thread joins and reads it. In tcp_start_incoming_migration(), allocate FdMigrationState and return MigrationState to let migration to print incoming migration info. Signed-off-by: Yoshiaki Tamura --- migration-tcp.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++--------- migration.h | 2 +- 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/migration-tcp.c b/migration-tcp.c index 95ce722..f20e5fe 100644 --- a/migration-tcp.c +++ b/migration-tcp.c @@ -18,6 +18,7 @@ #include "sysemu.h" #include "buffered_file.h" #include "block.h" +#include "qemu-thread.h" //#define DEBUG_MIGRATION_TCP @@ -29,6 +30,11 @@ do { } while (0) #endif +#ifdef CONFIG_IOTHREAD +static QemuThread migration_thread; +static int th_fds[2]; +#endif + static int socket_errno(FdMigrationState *s) { return socket_error(); @@ -176,41 +182,93 @@ static void tcp_accept_incoming_migration(void *opaque) out_fopen: qemu_fclose(f); out: +#ifndef CONFIG_IOTHREAD qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); +#endif close(s); close(c); +#ifdef CONFIG_IOTHREAD + write(th_fds[1], &ret, sizeof(ret)); + qemu_thread_exit(NULL); +#endif +} + +#ifdef CONFIG_IOTHREAD +static void tcp_incoming_migration_complete(void *opaque) +{ + int ret, state = 0; + FdMigrationState *s = opaque; + + qemu_thread_join(&migration_thread, NULL); + + ret = read(th_fds[0], &state, sizeof(state)); + if (ret == -1) { + fprintf(stderr, "failed to read from pipe\n"); + goto err; + } + + s->state = state < 0 ? MIG_STATE_ERROR : MIG_STATE_COMPLETED; + +err: + qemu_set_fd_handler2(th_fds[0], NULL, NULL, NULL, NULL); + close(th_fds[0]); + close(th_fds[1]); } +#endif -int tcp_start_incoming_migration(const char *host_port) +MigrationState *tcp_start_incoming_migration(const char *host_port) { struct sockaddr_in addr; + FdMigrationState *s; int val; - int s; if (parse_host_port(&addr, host_port) < 0) { fprintf(stderr, "invalid host/port combination: %s\n", host_port); - return -EINVAL; + return NULL; } - s = qemu_socket(PF_INET, SOCK_STREAM, 0); - if (s == -1) - return -socket_error(); + s = qemu_mallocz(sizeof(*s)); + + s->get_error = socket_errno; + s->close = tcp_close; + s->mig_state.cancel = migrate_fd_cancel; + s->mig_state.get_status = migrate_fd_get_status; + s->state = MIG_STATE_ACTIVE; + + s->fd = qemu_socket(PF_INET, SOCK_STREAM, 0); + if (s->fd == -1) { + qemu_free(s); + return NULL; + } val = 1; - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val)); + setsockopt(s->fd, SOL_SOCKET, SO_REUSEADDR, + (const char *)&val, sizeof(val)); - if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) + if (bind(s->fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) goto err; - if (listen(s, 1) == -1) + if (listen(s->fd, 1) == -1) goto err; - qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL, - (void *)(unsigned long)s); +#ifdef CONFIG_IOTHREAD + if (qemu_pipe(th_fds) == -1) { + fprintf(stderr, "failed to create pipe\n"); + goto err; + } - return 0; + qemu_thread_create(&migration_thread, (void *)tcp_accept_incoming_migration, + (void *)(unsigned long)s->fd); + qemu_set_fd_handler2(th_fds[0], NULL, tcp_incoming_migration_complete, NULL, + (void *)s); +#else + qemu_set_fd_handler2(s->fd, NULL, tcp_accept_incoming_migration, NULL, + (void *)(unsigned long)s->fd); +#endif + + return &s->mig_state; err: - close(s); - return -socket_error(); + close(s->fd); + return NULL; } diff --git a/migration.h b/migration.h index 385423f..c11e6db 100644 --- a/migration.h +++ b/migration.h @@ -76,7 +76,7 @@ MigrationState *exec_start_outgoing_migration(Monitor *mon, int blk, int inc); -int tcp_start_incoming_migration(const char *host_port); +MigrationState *tcp_start_incoming_migration(const char *host_port); MigrationState *tcp_start_outgoing_migration(Monitor *mon, const char *host_port,