Commit f749998939e564d8b8363bd6148b7a067d6bc9e3
1 parent
e5b0bc44
Add nodelay option for TCP character devices.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2362 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
17 additions
and
3 deletions
qemu-doc.texi
@@ -576,13 +576,14 @@ localhost 5555 | @@ -576,13 +576,14 @@ localhost 5555 | ||
576 | @end table | 576 | @end table |
577 | 577 | ||
578 | 578 | ||
579 | -@item tcp:[host]:port[,server][,nowait] | 579 | +@item tcp:[host]:port[,server][,nowait][,nodelay] |
580 | The TCP Net Console has two modes of operation. It can send the serial | 580 | The TCP Net Console has two modes of operation. It can send the serial |
581 | I/O to a location or wait for a connection from a location. By default | 581 | I/O to a location or wait for a connection from a location. By default |
582 | the TCP Net Console is sent to @var{host} at the @var{port}. If you use | 582 | the TCP Net Console is sent to @var{host} at the @var{port}. If you use |
583 | the @var{server} option QEMU will wait for a client socket application | 583 | the @var{server} option QEMU will wait for a client socket application |
584 | to connect to the port before continuing, unless the @code{nowait} | 584 | to connect to the port before continuing, unless the @code{nowait} |
585 | -option was specified. If @var{host} is omitted, 0.0.0.0 is assumed. Only | 585 | +option was specified. The @code{nodelay} option disables the Nagle buffering |
586 | +algoritm. If @var{host} is omitted, 0.0.0.0 is assumed. Only | ||
586 | one TCP connection at a time is accepted. You can use @code{telnet} to | 587 | one TCP connection at a time is accepted. You can use @code{telnet} to |
587 | connect to the corresponding character device. | 588 | connect to the corresponding character device. |
588 | @table @code | 589 | @table @code |
@@ -594,7 +595,7 @@ connect to the corresponding character device. | @@ -594,7 +595,7 @@ connect to the corresponding character device. | ||
594 | -serial tcp:192.168.0.100:4444,server,nowait | 595 | -serial tcp:192.168.0.100:4444,server,nowait |
595 | @end table | 596 | @end table |
596 | 597 | ||
597 | -@item telnet:host:port[,server][,nowait] | 598 | +@item telnet:host:port[,server][,nowait][,nodelay] |
598 | The telnet protocol is used instead of raw tcp sockets. The options | 599 | The telnet protocol is used instead of raw tcp sockets. The options |
599 | work the same as if you had specified @code{-serial tcp}. The | 600 | work the same as if you had specified @code{-serial tcp}. The |
600 | difference is that the port acts like a telnet server or client using | 601 | difference is that the port acts like a telnet server or client using |
vl.c
@@ -2497,6 +2497,12 @@ static void tcp_chr_telnet_init(int fd) | @@ -2497,6 +2497,12 @@ static void tcp_chr_telnet_init(int fd) | ||
2497 | send(fd, (char *)buf, 3, 0); | 2497 | send(fd, (char *)buf, 3, 0); |
2498 | } | 2498 | } |
2499 | 2499 | ||
2500 | +static void socket_set_nodelay(int fd) | ||
2501 | +{ | ||
2502 | + int val = 1; | ||
2503 | + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); | ||
2504 | +} | ||
2505 | + | ||
2500 | static void tcp_chr_accept(void *opaque) | 2506 | static void tcp_chr_accept(void *opaque) |
2501 | { | 2507 | { |
2502 | CharDriverState *chr = opaque; | 2508 | CharDriverState *chr = opaque; |
@@ -2530,6 +2536,8 @@ static void tcp_chr_accept(void *opaque) | @@ -2530,6 +2536,8 @@ static void tcp_chr_accept(void *opaque) | ||
2530 | } | 2536 | } |
2531 | } | 2537 | } |
2532 | socket_set_nonblock(fd); | 2538 | socket_set_nonblock(fd); |
2539 | + if (s->do_nodelay) | ||
2540 | + socket_set_nodelay(fd); | ||
2533 | s->fd = fd; | 2541 | s->fd = fd; |
2534 | qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL); | 2542 | qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL); |
2535 | tcp_chr_connect(chr); | 2543 | tcp_chr_connect(chr); |
@@ -2554,6 +2562,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, | @@ -2554,6 +2562,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, | ||
2554 | int fd = -1, ret, err, val; | 2562 | int fd = -1, ret, err, val; |
2555 | int is_listen = 0; | 2563 | int is_listen = 0; |
2556 | int is_waitconnect = 1; | 2564 | int is_waitconnect = 1; |
2565 | + int do_nodelay = 0; | ||
2557 | const char *ptr; | 2566 | const char *ptr; |
2558 | struct sockaddr_in saddr; | 2567 | struct sockaddr_in saddr; |
2559 | #ifndef _WIN32 | 2568 | #ifndef _WIN32 |
@@ -2584,6 +2593,8 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, | @@ -2584,6 +2593,8 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, | ||
2584 | is_listen = 1; | 2593 | is_listen = 1; |
2585 | } else if (!strncmp(ptr,"nowait",6)) { | 2594 | } else if (!strncmp(ptr,"nowait",6)) { |
2586 | is_waitconnect = 0; | 2595 | is_waitconnect = 0; |
2596 | + } else if (!strncmp(ptr,"nodelay",6)) { | ||
2597 | + do_nodelay = 1; | ||
2587 | } else { | 2598 | } else { |
2588 | printf("Unknown option: %s\n", ptr); | 2599 | printf("Unknown option: %s\n", ptr); |
2589 | goto fail; | 2600 | goto fail; |
@@ -2616,6 +2627,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, | @@ -2616,6 +2627,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, | ||
2616 | s->fd = -1; | 2627 | s->fd = -1; |
2617 | s->listen_fd = -1; | 2628 | s->listen_fd = -1; |
2618 | s->is_unix = is_unix; | 2629 | s->is_unix = is_unix; |
2630 | + s->do_nodelay = do_nodelay && !is_unix; | ||
2619 | 2631 | ||
2620 | chr->opaque = s; | 2632 | chr->opaque = s; |
2621 | chr->chr_write = tcp_chr_write; | 2633 | chr->chr_write = tcp_chr_write; |
@@ -2665,6 +2677,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, | @@ -2665,6 +2677,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, | ||
2665 | } | 2677 | } |
2666 | } | 2678 | } |
2667 | s->fd = fd; | 2679 | s->fd = fd; |
2680 | + socket_set_nodelay(fd); | ||
2668 | if (s->connected) | 2681 | if (s->connected) |
2669 | tcp_chr_connect(chr); | 2682 | tcp_chr_connect(chr); |
2670 | else | 2683 | else |