From: minyard@acm.org
To: qemu-devel@nongnu.org
Cc: bcketchum@gmail.com, Corey Minyard <cminyard@mvista.com>,
hwd@huawei.com, afaerber@suse.de, mst@redhat.com
Subject: [Qemu-devel] [PATCH 3/7] qemu-char: Wait until socket connect to report connected
Date: Tue, 4 Mar 2014 18:38:53 -0600 [thread overview]
Message-ID: <1393979937-9082-4-git-send-email-minyard@acm.org> (raw)
In-Reply-To: <1393979937-9082-1-git-send-email-minyard@acm.org>
From: Corey Minyard <cminyard@mvista.com>
The socket code was reporting that a socket connection was connected
as soon as the connect call was issued. If the connection failed, it
would then report it was not connected. With the reconnect code, it's
better to wait until the connection is actually operational before
reporting that the socket is connected.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
qemu-char.c | 49 ++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 40 insertions(+), 9 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index d9838aa..6d6dd36 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2310,9 +2310,10 @@ static CharDriverState *qemu_chr_open_udp(CharDriverState *chr, QemuOpts *opts)
typedef struct {
GIOChannel *chan, *listen_chan;
+ int waitsrc;
guint listen_tag;
int fd, listen_fd;
- int connected;
+ enum { TCP_NOT_CONNECTED, TCP_WAITING_CONNECT, TCP_CONNECTED } state;
int max_size;
int do_telnetopt;
int do_nodelay;
@@ -2325,7 +2326,7 @@ static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
TCPCharDriver *s = chr->opaque;
- if (s->connected) {
+ if (s->state == TCP_CONNECTED) {
return io_channel_send(s->chan, buf, len);
} else {
/* XXX: indicate an error ? */
@@ -2337,7 +2338,7 @@ static int tcp_chr_read_poll(void *opaque)
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
- if (!s->connected)
+ if (s->state != TCP_CONNECTED)
return 0;
s->max_size = qemu_chr_be_can_write(chr);
return s->max_size;
@@ -2482,7 +2483,7 @@ static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
uint8_t buf[READ_BUF_LEN];
int len, size;
- if (!s->connected || s->max_size <= 0) {
+ if (s->state != TCP_CONNECTED || s->max_size <= 0) {
return TRUE;
}
len = sizeof(buf);
@@ -2491,7 +2492,7 @@ static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
size = tcp_chr_recv(chr, (void *)buf, len);
if (size == 0) {
/* connection closed */
- s->connected = 0;
+ s->state = TCP_NOT_CONNECTED;
if (s->listen_chan) {
s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr);
}
@@ -2518,17 +2519,48 @@ CharDriverState *qemu_chr_open_eventfd(CharDriverState *chr, int eventfd)
}
#endif
-static void tcp_chr_connect(void *opaque)
+static gboolean tcp_wait_connect(GIOChannel *source,
+ GIOCondition condition,
+ gpointer opaque)
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
- s->connected = 1;
+ if (s->state != TCP_WAITING_CONNECT) {
+ return FALSE;
+ }
+ if (condition & G_IO_ERR || condition & G_IO_HUP) {
+ /* The connected failed */
+ s->state = TCP_NOT_CONNECTED;
+ g_io_channel_unref(s->chan);
+ s->chan = NULL;
+ closesocket(s->fd);
+ s->fd = -1;
+ return FALSE;
+ }
+
+ s->state = TCP_CONNECTED;
if (s->chan) {
chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll,
tcp_chr_read, chr);
}
qemu_chr_be_generic_open(chr);
+ return FALSE;
+}
+
+static void tcp_chr_connect(void *opaque)
+{
+ CharDriverState *chr = opaque;
+ TCPCharDriver *s = chr->opaque;
+
+ s->state = TCP_WAITING_CONNECT;
+ if (s->chan) {
+ /* Wait until write becomes ready before reporting connected. */
+ s->waitsrc = g_io_add_watch(s->chan,
+ G_IO_OUT | G_IO_HUP | G_IO_ERR,
+ tcp_wait_connect,
+ chr);
+ }
}
#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
@@ -2650,7 +2682,7 @@ static CharDriverState *qemu_chr_open_socket_fd(CharDriverState *chr,
s = g_malloc0(sizeof(TCPCharDriver));
- s->connected = 0;
+ s->state = TCP_NOT_CONNECTED;
s->fd = -1;
s->listen_fd = -1;
s->msgfd = -1;
@@ -2695,7 +2727,6 @@ static CharDriverState *qemu_chr_open_socket_fd(CharDriverState *chr,
s->do_telnetopt = 1;
}
} else {
- s->connected = 1;
s->fd = fd;
socket_set_nodelay(fd);
s->chan = io_channel_from_socket(s->fd);
--
1.8.3.1
next prev parent reply other threads:[~2014-03-05 0:40 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-05 0:38 [Qemu-devel] [PATCH 0/7] Allow a client chardev to reconnect if disconnected minyard
2014-03-05 0:38 ` [Qemu-devel] [PATCH 1/7] qemu-char: Allocate CharDriverState in qemu_chr_new_from_opts minyard
2014-03-05 0:38 ` [Qemu-devel] [PATCH 2/7] qemu-char: Allow a chardev to reconnect if disconnected minyard
2014-03-06 6:47 ` Weidong Huang
2014-03-06 17:18 ` Corey Minyard
2014-03-06 17:41 ` Michael S. Tsirkin
2014-03-06 7:43 ` Michael S. Tsirkin
2014-03-06 18:04 ` Corey Minyard
2014-03-06 18:43 ` Michael S. Tsirkin
2014-03-05 0:38 ` minyard [this message]
2014-03-05 0:38 ` [Qemu-devel] [PATCH 4/7] qemu-char: remove free of chr from win_stdio_close minyard
2014-03-05 0:38 ` [Qemu-devel] [PATCH 5/7] qemu-char: Close fd at end of file minyard
2014-03-05 0:38 ` [Qemu-devel] [PATCH 6/7] qemu-char: Clean up error handling in qmp_chardev_add minyard
2014-03-05 0:38 ` [Qemu-devel] [PATCH 7/7] console: Don't use the console if NULL minyard
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=1393979937-9082-4-git-send-email-minyard@acm.org \
--to=minyard@acm.org \
--cc=afaerber@suse.de \
--cc=bcketchum@gmail.com \
--cc=cminyard@mvista.com \
--cc=hwd@huawei.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).