From patchwork Thu Apr 10 11:43:46 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gonglei (Arei)" X-Patchwork-Id: 338095 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 62DA1140087 for ; Thu, 10 Apr 2014 21:45:01 +1000 (EST) Received: from localhost ([::1]:50397 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WYDPf-00006w-H1 for incoming@patchwork.ozlabs.org; Thu, 10 Apr 2014 07:44:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56451) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WYDPL-00006a-Sj for qemu-devel@nongnu.org; Thu, 10 Apr 2014 07:44:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WYDPF-00019b-Qt for qemu-devel@nongnu.org; Thu, 10 Apr 2014 07:44:39 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:41762) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WYDPE-000170-Vk for qemu-devel@nongnu.org; Thu, 10 Apr 2014 07:44:33 -0400 Received: from 172.24.2.119 (EHLO szxeml206-edg.china.huawei.com) ([172.24.2.119]) by szxrg02-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id BSH45996; Thu, 10 Apr 2014 19:44:13 +0800 (CST) Received: from SZXEML424-HUB.china.huawei.com (10.82.67.163) by szxeml206-edg.china.huawei.com (172.24.2.59) with Microsoft SMTP Server (TLS) id 14.3.158.1; Thu, 10 Apr 2014 19:43:38 +0800 Received: from localhost (10.177.19.102) by szxeml424-hub.china.huawei.com (10.82.67.163) with Microsoft SMTP Server id 14.3.158.1; Thu, 10 Apr 2014 19:44:06 +0800 From: To: Date: Thu, 10 Apr 2014 19:43:46 +0800 Message-ID: <1397130226-7332-1-git-send-email-arei.gonglei@huawei.com> X-Mailer: git-send-email 1.7.3.1.msysgit.0 MIME-Version: 1.0 X-Originating-IP: [10.177.19.102] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 119.145.14.65 Cc: Huangweidong , minyard@acm.org, mst@redhat.com, bcketchum@gmail.com, Gonglei , kraxel@redhat.com, afaerber@suse.de Subject: [Qemu-devel] [PATCH] qemu-char: Allow a chardev to reconnect if disconnected X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Huangweidong Allow a socket chardev reconnect if the connection drops while in use. Signed-off-by: Huangweidong Signed-off-by: Gonglei --- This patch is modified according to corey's patch. Some changes below: 1. IMO it's unnecessary that chardev reconnect if it fails to connect at startup. Qemu exit in this scene. In this way the patch does not change interface of chardev. It would be much more simple. 2. I set the reconnect timer one second, just like pty. include/sysemu/char.h | 2 ++ qemu-char.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/include/sysemu/char.h b/include/sysemu/char.h index b81a6ff..f646ac8 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -19,6 +19,7 @@ #define CHR_EVENT_MUX_OUT 4 /* mux-focus will move on */ #define CHR_EVENT_CLOSED 5 /* connection closed */ +#define CHR_SOCK_RECONNECT_TIME 1 /* reconnection time (second) */ #define CHR_IOCTL_SERIAL_SET_PARAMS 1 typedef struct { @@ -82,6 +83,7 @@ struct CharDriverState { guint fd_in_tag; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; + QEMUTimer *recon_timer; }; /** diff --git a/qemu-char.c b/qemu-char.c index 54ed244..a87a345 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -96,9 +96,17 @@ void qemu_chr_be_event(CharDriverState *s, int event) /* Keep track if the char device is open */ switch (event) { case CHR_EVENT_OPENED: + if (s->recon_timer) { + timer_del(s->recon_timer); + } s->be_open = 1; break; case CHR_EVENT_CLOSED: + if (s->recon_timer) { + timer_mod(s->recon_timer, + (get_clock() + + (CHR_SOCK_RECONNECT_TIME * get_ticks_per_sec()))); + } s->be_open = 0; break; } @@ -2619,6 +2627,43 @@ static void tcp_chr_close(CharDriverState *chr) qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } +static void recon_timeout(void *opaque) +{ + CharDriverState *chr = opaque; + QemuOpts *opts = chr->opts; + TCPCharDriver *tcp = (TCPCharDriver *)chr->opaque; + int fd = -1; + Error *local_err = NULL; + + if (chr->be_open) { + return; + } + + if (tcp->is_unix) { + fd = unix_connect_opts(opts, &local_err, NULL, NULL); + } else { + fd = inet_connect_opts(opts, &local_err, NULL, NULL); + } + + if (fd < 0) { + goto fail; + } + + tcp->fd = fd; + socket_set_nodelay(fd); + tcp->chan = io_channel_from_socket(tcp->fd); + tcp_chr_connect(chr); + printf("chardev: socket reconnect sucess\n"); + return; + +fail: + if (local_err) { + qerror_report_err(local_err); + error_free(local_err); + } + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); +} + static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay, bool is_listen, bool is_telnet, bool is_waitconnect, @@ -2693,6 +2738,11 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay, socket_set_nodelay(fd); s->chan = io_channel_from_socket(s->fd); tcp_chr_connect(chr); + chr->recon_timer = timer_new(QEMU_CLOCK_REALTIME, SCALE_NS, + recon_timeout, chr); + timer_mod(chr->recon_timer, + (get_clock() + + (CHR_SOCK_RECONNECT_TIME * get_ticks_per_sec()))); } if (is_listen && is_waitconnect) {