From: "David S. Ahern" <daahern@cisco.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] re-send: enabling TCP keepalives - v5
Date: Sun, 10 May 2009 20:22:17 -0600 [thread overview]
Message-ID: <4A078BD9.3070507@cisco.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 576 bytes --]
I did not see a response to this a week+ ago. Any objections to this
minimalist version?
david
This patch enables TCP keepalives on VNC connections and TCP-based char
devices.
Changes v4 -> v5
- removed settings for the timers and counter such that OS defaults are
used once the keepalive option is enabled
- enabling keepalives is now an option for TCP char devices
(piggy-backed on the nodelay option Paul mentioned)
- forced on for vnc (making it an option for vnc is a big can of works
that does not need to be opened)
Signed-off-by: David Ahern <dsahern@gmail.com>
[-- Attachment #2: enable-tcp-keepalives-v5.patch --]
[-- Type: text/plain, Size: 5932 bytes --]
diff --git a/configure b/configure
index 82fb60a..5ce0236 100755
--- a/configure
+++ b/configure
@@ -1673,6 +1673,19 @@ if test "$fdt" = "yes" ; then
echo "FDT_LIBS=-lfdt" >> $config_mak
fi
+cat > $TMPC << EOF
+#include <sys/socket.h>
+int main(void) {
+ int val = 1;
+ if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) < 0)
+ return 1;
+ return 0;
+}
+EOF
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC >/dev/null 2> /dev/null ; then
+ echo "#define HAVE_SO_KEEPALIVE 1" >> $config_h
+fi
+
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
echo "#define O_LARGEFILE 0" >> $config_h
diff --git a/net.c b/net.c
index 7ae1e6d..e787883 100644
--- a/net.c
+++ b/net.c
@@ -2209,3 +2209,18 @@ void net_client_check(void)
vlan->id);
}
}
+
+int enable_tcp_keepalive(int sd)
+{
+#ifdef HAVE_SO_KEEPALIVE
+ int val = 1;
+
+ if (setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) < 0) {
+ return -1;
+ }
+#else
+ fprintf(stderr, "Warning: TCP keepalives not supported\n");
+#endif
+
+ return 0;
+}
diff --git a/net.h b/net.h
index cdf63a4..29d00fa 100644
--- a/net.h
+++ b/net.h
@@ -119,6 +119,8 @@ void net_client_check(void);
void net_host_device_add(Monitor *mon, const char *device, const char *opts);
void net_host_device_remove(Monitor *mon, int vlan_id, const char *device);
+int enable_tcp_keepalive(int sd);
+
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
#ifdef __sun__
diff --git a/qemu-char.c b/qemu-char.c
index 664cbfd..2d21022 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1825,6 +1825,7 @@ typedef struct {
int max_size;
int do_telnetopt;
int do_nodelay;
+ int do_keepalive;
int is_unix;
} TCPCharDriver;
@@ -1998,6 +1999,10 @@ static void tcp_chr_accept(void *opaque)
socket_set_nonblock(fd);
if (s->do_nodelay)
socket_set_nodelay(fd);
+ if (s->do_keepalive && enable_tcp_keepalive(fd) != 0) {
+ fprintf(stderr,
+ "tcp_chr_accept: failed to enable TCP keepalive probes\n");
+ }
s->fd = fd;
qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
tcp_chr_connect(chr);
@@ -2027,6 +2032,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
int is_listen = 0;
int is_waitconnect = 1;
int do_nodelay = 0;
+ int do_keepalive = 0;
const char *ptr;
ptr = host_str;
@@ -2038,6 +2044,8 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
is_waitconnect = 0;
} else if (!strncmp(ptr,"nodelay",6)) {
do_nodelay = 1;
+ } else if (!strncmp(ptr,"keepalive",9) && !is_unix) {
+ do_keepalive = 1;
} else if (!strncmp(ptr,"to=",3)) {
/* nothing, inet_listen() parses this one */;
} else if (!strncmp(ptr,"ipv4",4)) {
@@ -2091,6 +2099,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
s->listen_fd = -1;
s->is_unix = is_unix;
s->do_nodelay = do_nodelay && !is_unix;
+ s->do_keepalive = do_keepalive;
chr->opaque = s;
chr->chr_write = tcp_chr_write;
@@ -2105,6 +2114,10 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
s->connected = 1;
s->fd = fd;
socket_set_nodelay(fd);
+ if (s->do_keepalive && enable_tcp_keepalive(fd) != 0) {
+ fprintf(stderr,
+ "failed to enable TCP keepalive probes on %d\n", fd);
+ }
tcp_chr_connect(chr);
}
diff --git a/qemu-options.hx b/qemu-options.hx
index aa786e3..a57e335 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1165,16 +1165,16 @@ telnet on port 5555 to access the qemu port.
localhost 5555
@end table
-@item tcp:[@var{host}]:@var{port}[,@var{server}][,nowait][,nodelay]
+@item tcp:[@var{host}]:@var{port}[,@var{server}][,nowait][,nodelay][,keepalive]
The TCP Net Console has two modes of operation. It can send the serial
I/O to a location or wait for a connection from a location. By default
the TCP Net Console is sent to @var{host} at the @var{port}. If you use
the @var{server} option QEMU will wait for a client socket application
to connect to the port before continuing, unless the @code{nowait}
option was specified. The @code{nodelay} option disables the Nagle buffering
-algorithm. If @var{host} is omitted, 0.0.0.0 is assumed. Only
-one TCP connection at a time is accepted. You can use @code{telnet} to
-connect to the corresponding character device.
+algorithm. The @code{keepalive} option enables TCP keepalives. If @var{host}
+is omitted, 0.0.0.0 is assumed. Only one TCP connection at a time is accepted.
+You can use @code{telnet} to connect to the corresponding character device.
@table @code
@item Example to send tcp console to 192.168.0.2 port 4444
-serial tcp:192.168.0.2:4444
@@ -1184,7 +1184,7 @@ connect to the corresponding character device.
-serial tcp:192.168.0.100:4444,server,nowait
@end table
-@item telnet:@var{host}:@var{port}[,server][,nowait][,nodelay]
+@item telnet:@var{host}:@var{port}[,server][,nowait][,nodelay][,keepalive]
The telnet protocol is used instead of raw tcp sockets. The options
work the same as if you had specified @code{-serial tcp}. The
difference is that the port acts like a telnet server or client using
diff --git a/vnc.c b/vnc.c
index ab1f044..52af93d 100644
--- a/vnc.c
+++ b/vnc.c
@@ -29,6 +29,7 @@
#include "qemu_socket.h"
#include "qemu-timer.h"
#include "acl.h"
+#include "net.h"
#define VNC_REFRESH_INTERVAL (1000 / 30)
@@ -2021,6 +2022,10 @@ static void vnc_listen_read(void *opaque)
int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
if (csock != -1) {
+ if (enable_tcp_keepalive(csock) != 0) {
+ fprintf(stderr, "VNC: failed to enable TCP keepalive probes\n");
+ }
+
vnc_connect(vs, csock);
}
}
reply other threads:[~2009-05-11 2:22 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=4A078BD9.3070507@cisco.com \
--to=daahern@cisco.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 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.