Commit ffd843bcdc46768f26507f0889c92f4bda287986

Authored by ths
1 parent 1cb6c3fd

Run monitor over unix domain sockets, by Anthony Liguori.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2259 c046a42c-6fe2-441c-8c8c-71466251a162
qemu-doc.texi
@@ -586,6 +586,11 @@ MAGIC_SYSRQ sequence if you use a telnet that supports sending the break @@ -586,6 +586,11 @@ MAGIC_SYSRQ sequence if you use a telnet that supports sending the break
586 sequence. Typically in unix telnet you do it with Control-] and then 586 sequence. Typically in unix telnet you do it with Control-] and then
587 type "send break" followed by pressing the enter key. 587 type "send break" followed by pressing the enter key.
588 588
  589 +@item unix:path[,server][,nowait]
  590 +A unix domain socket is used instead of a tcp socket. The option works the
  591 +same as if you had specified @code{-serial tcp} except the unix domain socket
  592 +@var{path} is used for connections.
  593 +
589 @end table 594 @end table
590 595
591 @item -parallel dev 596 @item -parallel dev
qemu_socket.h
@@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
19 #include <sys/socket.h> 19 #include <sys/socket.h>
20 #include <netinet/in.h> 20 #include <netinet/in.h>
21 #include <netinet/tcp.h> 21 #include <netinet/tcp.h>
  22 +#include <sys/un.h>
22 23
23 #define socket_error() errno 24 #define socket_error() errno
24 #define closesocket(s) close(s) 25 #define closesocket(s) close(s)
@@ -2206,6 +2206,7 @@ static void udp_chr_add_read_handler(CharDriverState *chr, @@ -2206,6 +2206,7 @@ static void udp_chr_add_read_handler(CharDriverState *chr,
2206 } 2206 }
2207 2207
2208 int parse_host_port(struct sockaddr_in *saddr, const char *str); 2208 int parse_host_port(struct sockaddr_in *saddr, const char *str);
  2209 +int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
2209 int parse_host_src_port(struct sockaddr_in *haddr, 2210 int parse_host_src_port(struct sockaddr_in *haddr,
2210 struct sockaddr_in *saddr, 2211 struct sockaddr_in *saddr,
2211 const char *str); 2212 const char *str);
@@ -2270,6 +2271,7 @@ typedef struct { @@ -2270,6 +2271,7 @@ typedef struct {
2270 int connected; 2271 int connected;
2271 int max_size; 2272 int max_size;
2272 int do_telnetopt; 2273 int do_telnetopt;
  2274 + int is_unix;
2273 } TCPCharDriver; 2275 } TCPCharDriver;
2274 2276
2275 static void tcp_chr_accept(void *opaque); 2277 static void tcp_chr_accept(void *opaque);
@@ -2291,6 +2293,8 @@ static int tcp_chr_read_poll(void *opaque) @@ -2291,6 +2293,8 @@ static int tcp_chr_read_poll(void *opaque)
2291 TCPCharDriver *s = chr->opaque; 2293 TCPCharDriver *s = chr->opaque;
2292 if (!s->connected) 2294 if (!s->connected)
2293 return 0; 2295 return 0;
  2296 + if (!s->fd_can_read)
  2297 + return 0;
2294 s->max_size = s->fd_can_read(s->fd_opaque); 2298 s->max_size = s->fd_can_read(s->fd_opaque);
2295 return s->max_size; 2299 return s->max_size;
2296 } 2300 }
@@ -2416,12 +2420,25 @@ static void tcp_chr_accept(void *opaque) @@ -2416,12 +2420,25 @@ static void tcp_chr_accept(void *opaque)
2416 CharDriverState *chr = opaque; 2420 CharDriverState *chr = opaque;
2417 TCPCharDriver *s = chr->opaque; 2421 TCPCharDriver *s = chr->opaque;
2418 struct sockaddr_in saddr; 2422 struct sockaddr_in saddr;
  2423 +#ifndef _WIN32
  2424 + struct sockaddr_un uaddr;
  2425 +#endif
  2426 + struct sockaddr *addr;
2419 socklen_t len; 2427 socklen_t len;
2420 int fd; 2428 int fd;
2421 2429
2422 for(;;) { 2430 for(;;) {
2423 - len = sizeof(saddr);  
2424 - fd = accept(s->listen_fd, (struct sockaddr *)&saddr, &len); 2431 +#ifndef _WIN32
  2432 + if (s->is_unix) {
  2433 + len = sizeof(uaddr);
  2434 + addr = (struct sockaddr *)&uaddr;
  2435 + } else
  2436 +#endif
  2437 + {
  2438 + len = sizeof(saddr);
  2439 + addr = (struct sockaddr *)&saddr;
  2440 + }
  2441 + fd = accept(s->listen_fd, addr, &len);
2425 if (fd < 0 && errno != EINTR) { 2442 if (fd < 0 && errno != EINTR) {
2426 return; 2443 return;
2427 } else if (fd >= 0) { 2444 } else if (fd >= 0) {
@@ -2447,7 +2464,8 @@ static void tcp_chr_close(CharDriverState *chr) @@ -2447,7 +2464,8 @@ static void tcp_chr_close(CharDriverState *chr)
2447 } 2464 }
2448 2465
2449 static CharDriverState *qemu_chr_open_tcp(const char *host_str, 2466 static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2450 - int is_telnet) 2467 + int is_telnet,
  2468 + int is_unix)
2451 { 2469 {
2452 CharDriverState *chr = NULL; 2470 CharDriverState *chr = NULL;
2453 TCPCharDriver *s = NULL; 2471 TCPCharDriver *s = NULL;
@@ -2456,9 +2474,26 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, @@ -2456,9 +2474,26 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2456 int is_waitconnect = 1; 2474 int is_waitconnect = 1;
2457 const char *ptr; 2475 const char *ptr;
2458 struct sockaddr_in saddr; 2476 struct sockaddr_in saddr;
  2477 +#ifndef _WIN32
  2478 + struct sockaddr_un uaddr;
  2479 +#endif
  2480 + struct sockaddr *addr;
  2481 + socklen_t addrlen;
2459 2482
2460 - if (parse_host_port(&saddr, host_str) < 0)  
2461 - goto fail; 2483 +#ifndef _WIN32
  2484 + if (is_unix) {
  2485 + addr = (struct sockaddr *)&uaddr;
  2486 + addrlen = sizeof(uaddr);
  2487 + if (parse_unix_path(&uaddr, host_str) < 0)
  2488 + goto fail;
  2489 + } else
  2490 +#endif
  2491 + {
  2492 + addr = (struct sockaddr *)&saddr;
  2493 + addrlen = sizeof(saddr);
  2494 + if (parse_host_port(&saddr, host_str) < 0)
  2495 + goto fail;
  2496 + }
2462 2497
2463 ptr = host_str; 2498 ptr = host_str;
2464 while((ptr = strchr(ptr,','))) { 2499 while((ptr = strchr(ptr,','))) {
@@ -2481,8 +2516,14 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, @@ -2481,8 +2516,14 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2481 s = qemu_mallocz(sizeof(TCPCharDriver)); 2516 s = qemu_mallocz(sizeof(TCPCharDriver));
2482 if (!s) 2517 if (!s)
2483 goto fail; 2518 goto fail;
2484 -  
2485 - fd = socket(PF_INET, SOCK_STREAM, 0); 2519 +
  2520 +#ifndef _WIN32
  2521 + if (is_unix)
  2522 + fd = socket(PF_UNIX, SOCK_STREAM, 0);
  2523 + else
  2524 +#endif
  2525 + fd = socket(PF_INET, SOCK_STREAM, 0);
  2526 +
2486 if (fd < 0) 2527 if (fd < 0)
2487 goto fail; 2528 goto fail;
2488 2529
@@ -2492,24 +2533,43 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, @@ -2492,24 +2533,43 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2492 s->connected = 0; 2533 s->connected = 0;
2493 s->fd = -1; 2534 s->fd = -1;
2494 s->listen_fd = -1; 2535 s->listen_fd = -1;
  2536 + s->is_unix = is_unix;
  2537 +
  2538 + chr->opaque = s;
  2539 + chr->chr_write = tcp_chr_write;
  2540 + chr->chr_add_read_handler = tcp_chr_add_read_handler;
  2541 + chr->chr_close = tcp_chr_close;
  2542 +
2495 if (is_listen) { 2543 if (is_listen) {
2496 /* allow fast reuse */ 2544 /* allow fast reuse */
2497 - val = 1;  
2498 - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val)); 2545 +#ifndef _WIN32
  2546 + if (is_unix) {
  2547 + char path[109];
  2548 + strncpy(path, uaddr.sun_path, 108);
  2549 + path[108] = 0;
  2550 + unlink(path);
  2551 + } else
  2552 +#endif
  2553 + {
  2554 + val = 1;
  2555 + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
  2556 + }
2499 2557
2500 - ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));  
2501 - if (ret < 0) 2558 + ret = bind(fd, addr, addrlen);
  2559 + if (ret < 0)
2502 goto fail; 2560 goto fail;
  2561 +
2503 ret = listen(fd, 0); 2562 ret = listen(fd, 0);
2504 if (ret < 0) 2563 if (ret < 0)
2505 goto fail; 2564 goto fail;
  2565 +
2506 s->listen_fd = fd; 2566 s->listen_fd = fd;
2507 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr); 2567 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
2508 if (is_telnet) 2568 if (is_telnet)
2509 s->do_telnetopt = 1; 2569 s->do_telnetopt = 1;
2510 } else { 2570 } else {
2511 for(;;) { 2571 for(;;) {
2512 - ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); 2572 + ret = connect(fd, addr, addrlen);
2513 if (ret < 0) { 2573 if (ret < 0) {
2514 err = socket_error(); 2574 err = socket_error();
2515 if (err == EINTR || err == EWOULDBLOCK) { 2575 if (err == EINTR || err == EWOULDBLOCK) {
@@ -2530,10 +2590,6 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, @@ -2530,10 +2590,6 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2530 qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr); 2590 qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
2531 } 2591 }
2532 2592
2533 - chr->opaque = s;  
2534 - chr->chr_write = tcp_chr_write;  
2535 - chr->chr_add_read_handler = tcp_chr_add_read_handler;  
2536 - chr->chr_close = tcp_chr_close;  
2537 if (is_listen && is_waitconnect) { 2593 if (is_listen && is_waitconnect) {
2538 printf("QEMU waiting for connection on: %s\n", host_str); 2594 printf("QEMU waiting for connection on: %s\n", host_str);
2539 tcp_chr_accept(chr); 2595 tcp_chr_accept(chr);
@@ -2559,16 +2615,18 @@ CharDriverState *qemu_chr_open(const char *filename) @@ -2559,16 +2615,18 @@ CharDriverState *qemu_chr_open(const char *filename)
2559 return qemu_chr_open_null(); 2615 return qemu_chr_open_null();
2560 } else 2616 } else
2561 if (strstart(filename, "tcp:", &p)) { 2617 if (strstart(filename, "tcp:", &p)) {
2562 - return qemu_chr_open_tcp(p, 0); 2618 + return qemu_chr_open_tcp(p, 0, 0);
2563 } else 2619 } else
2564 if (strstart(filename, "telnet:", &p)) { 2620 if (strstart(filename, "telnet:", &p)) {
2565 - return qemu_chr_open_tcp(p, 1); 2621 + return qemu_chr_open_tcp(p, 1, 0);
2566 } else 2622 } else
2567 if (strstart(filename, "udp:", &p)) { 2623 if (strstart(filename, "udp:", &p)) {
2568 return qemu_chr_open_udp(p); 2624 return qemu_chr_open_udp(p);
2569 } else 2625 } else
2570 #ifndef _WIN32 2626 #ifndef _WIN32
2571 - if (strstart(filename, "file:", &p)) { 2627 + if (strstart(filename, "unix:", &p)) {
  2628 + return qemu_chr_open_tcp(p, 0, 1);
  2629 + } else if (strstart(filename, "file:", &p)) {
2572 return qemu_chr_open_file_out(p); 2630 return qemu_chr_open_file_out(p);
2573 } else if (strstart(filename, "pipe:", &p)) { 2631 } else if (strstart(filename, "pipe:", &p)) {
2574 return qemu_chr_open_pipe(p); 2632 return qemu_chr_open_pipe(p);
@@ -2743,6 +2801,24 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str) @@ -2743,6 +2801,24 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str)
2743 return 0; 2801 return 0;
2744 } 2802 }
2745 2803
  2804 +int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
  2805 +{
  2806 + const char *p;
  2807 + int len;
  2808 +
  2809 + len = MIN(108, strlen(str));
  2810 + p = strchr(str, ',');
  2811 + if (p)
  2812 + len = MIN(len, p - str);
  2813 +
  2814 + memset(uaddr, 0, sizeof(*uaddr));
  2815 +
  2816 + uaddr->sun_family = AF_UNIX;
  2817 + memcpy(uaddr->sun_path, str, len);
  2818 +
  2819 + return 0;
  2820 +}
  2821 +
2746 /* find or alloc a new VLAN */ 2822 /* find or alloc a new VLAN */
2747 VLANState *qemu_find_vlan(int id) 2823 VLANState *qemu_find_vlan(int id)
2748 { 2824 {
@@ -6955,6 +7031,7 @@ int main(int argc, char **argv) @@ -6955,6 +7031,7 @@ int main(int argc, char **argv)
6955 vm_start(); 7031 vm_start();
6956 } 7032 }
6957 } 7033 }
  7034 +
6958 main_loop(); 7035 main_loop();
6959 quit_timers(); 7036 quit_timers();
6960 return 0; 7037 return 0;