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 586 sequence. Typically in unix telnet you do it with Control-] and then
587 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 594 @end table
590 595  
591 596 @item -parallel dev
... ...
qemu_socket.h
... ... @@ -19,6 +19,7 @@
19 19 #include <sys/socket.h>
20 20 #include <netinet/in.h>
21 21 #include <netinet/tcp.h>
  22 +#include <sys/un.h>
22 23  
23 24 #define socket_error() errno
24 25 #define closesocket(s) close(s)
... ...
... ... @@ -2206,6 +2206,7 @@ static void udp_chr_add_read_handler(CharDriverState *chr,
2206 2206 }
2207 2207  
2208 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 2210 int parse_host_src_port(struct sockaddr_in *haddr,
2210 2211 struct sockaddr_in *saddr,
2211 2212 const char *str);
... ... @@ -2270,6 +2271,7 @@ typedef struct {
2270 2271 int connected;
2271 2272 int max_size;
2272 2273 int do_telnetopt;
  2274 + int is_unix;
2273 2275 } TCPCharDriver;
2274 2276  
2275 2277 static void tcp_chr_accept(void *opaque);
... ... @@ -2291,6 +2293,8 @@ static int tcp_chr_read_poll(void *opaque)
2291 2293 TCPCharDriver *s = chr->opaque;
2292 2294 if (!s->connected)
2293 2295 return 0;
  2296 + if (!s->fd_can_read)
  2297 + return 0;
2294 2298 s->max_size = s->fd_can_read(s->fd_opaque);
2295 2299 return s->max_size;
2296 2300 }
... ... @@ -2416,12 +2420,25 @@ static void tcp_chr_accept(void *opaque)
2416 2420 CharDriverState *chr = opaque;
2417 2421 TCPCharDriver *s = chr->opaque;
2418 2422 struct sockaddr_in saddr;
  2423 +#ifndef _WIN32
  2424 + struct sockaddr_un uaddr;
  2425 +#endif
  2426 + struct sockaddr *addr;
2419 2427 socklen_t len;
2420 2428 int fd;
2421 2429  
2422 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 2442 if (fd < 0 && errno != EINTR) {
2426 2443 return;
2427 2444 } else if (fd >= 0) {
... ... @@ -2447,7 +2464,8 @@ static void tcp_chr_close(CharDriverState *chr)
2447 2464 }
2448 2465  
2449 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 2470 CharDriverState *chr = NULL;
2453 2471 TCPCharDriver *s = NULL;
... ... @@ -2456,9 +2474,26 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2456 2474 int is_waitconnect = 1;
2457 2475 const char *ptr;
2458 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 2498 ptr = host_str;
2464 2499 while((ptr = strchr(ptr,','))) {
... ... @@ -2481,8 +2516,14 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2481 2516 s = qemu_mallocz(sizeof(TCPCharDriver));
2482 2517 if (!s)
2483 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 2527 if (fd < 0)
2487 2528 goto fail;
2488 2529  
... ... @@ -2492,24 +2533,43 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2492 2533 s->connected = 0;
2493 2534 s->fd = -1;
2494 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 2543 if (is_listen) {
2496 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 2560 goto fail;
  2561 +
2503 2562 ret = listen(fd, 0);
2504 2563 if (ret < 0)
2505 2564 goto fail;
  2565 +
2506 2566 s->listen_fd = fd;
2507 2567 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
2508 2568 if (is_telnet)
2509 2569 s->do_telnetopt = 1;
2510 2570 } else {
2511 2571 for(;;) {
2512   - ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
  2572 + ret = connect(fd, addr, addrlen);
2513 2573 if (ret < 0) {
2514 2574 err = socket_error();
2515 2575 if (err == EINTR || err == EWOULDBLOCK) {
... ... @@ -2530,10 +2590,6 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2530 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 2593 if (is_listen && is_waitconnect) {
2538 2594 printf("QEMU waiting for connection on: %s\n", host_str);
2539 2595 tcp_chr_accept(chr);
... ... @@ -2559,16 +2615,18 @@ CharDriverState *qemu_chr_open(const char *filename)
2559 2615 return qemu_chr_open_null();
2560 2616 } else
2561 2617 if (strstart(filename, "tcp:", &p)) {
2562   - return qemu_chr_open_tcp(p, 0);
  2618 + return qemu_chr_open_tcp(p, 0, 0);
2563 2619 } else
2564 2620 if (strstart(filename, "telnet:", &p)) {
2565   - return qemu_chr_open_tcp(p, 1);
  2621 + return qemu_chr_open_tcp(p, 1, 0);
2566 2622 } else
2567 2623 if (strstart(filename, "udp:", &p)) {
2568 2624 return qemu_chr_open_udp(p);
2569 2625 } else
2570 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 2630 return qemu_chr_open_file_out(p);
2573 2631 } else if (strstart(filename, "pipe:", &p)) {
2574 2632 return qemu_chr_open_pipe(p);
... ... @@ -2743,6 +2801,24 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str)
2743 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 2822 /* find or alloc a new VLAN */
2747 2823 VLANState *qemu_find_vlan(int id)
2748 2824 {
... ... @@ -6955,6 +7031,7 @@ int main(int argc, char **argv)
6955 7031 vm_start();
6956 7032 }
6957 7033 }
  7034 +
6958 7035 main_loop();
6959 7036 quit_timers();
6960 7037 return 0;
... ...