All of lore.kernel.org
 help / color / mirror / Atom feed
From: Corey Minyard <minyard@acm.org>
To: arei.gonglei@huawei.com, qemu-devel@nongnu.org
Cc: bcketchum@gmail.com, Huangweidong <weidong.huang@huawei.com>,
	kraxel@redhat.com, afaerber@suse.de, mst@redhat.com
Subject: Re: [Qemu-devel] [PATCH] qemu-char: Allow a chardev to reconnect if disconnected
Date: Thu, 10 Apr 2014 09:56:35 -0500	[thread overview]
Message-ID: <5346B123.3070606@acm.org> (raw)
In-Reply-To: <1397130226-7332-1-git-send-email-arei.gonglei@huawei.com>

On 04/10/2014 06:43 AM, arei.gonglei@huawei.com wrote:
> From: Huangweidong <weidong.huang@huawei.com>
>
> Allow a socket chardev reconnect if the connection drops while in use.
>
> Signed-off-by: Huangweidong <weidong.huang@huawei.com>
> Signed-off-by: Gonglei <arei.gonglei@huawei.com>
> ---
> 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.

I believe that it should not stop qemu if it fails at startup. 
Otherwise you constrain the start order and you can prevent a server
from coming up because of a missing resource that may not be that
critical at the moment.  With the current implementation, client sockets
really aren't that useful for a critical system.  Reconnecting makes it
usable in a critical system.

> 2. I set the reconnect timer one second, just like pty.

I'm not too picky about the time.  A couple of things about this:

With this patch, the default behavior changes to reconnect.  That might
cause issues for some users.  Adding a configurable timeout is easy if
you have to specify something on the command line, that's why I did it.

Also, if something is listening to connect/disconnect events from the
device, it will get a connect then disconnect every second.  It's
probably better to wait until the connection is actually established
before you report it up.

-corey
>
>  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) {

  reply	other threads:[~2014-04-10 14:56 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-10 11:43 [Qemu-devel] [PATCH] qemu-char: Allow a chardev to reconnect if disconnected arei.gonglei
2014-04-10 14:56 ` Corey Minyard [this message]
2014-04-11  7:08   ` Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5346B123.3070606@acm.org \
    --to=minyard@acm.org \
    --cc=afaerber@suse.de \
    --cc=arei.gonglei@huawei.com \
    --cc=bcketchum@gmail.com \
    --cc=kraxel@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=weidong.huang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.