All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <aliguori@cs.utexas.edu>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 1/3] Add unix domain socket character device
Date: Sat, 16 Dec 2006 12:00:38 -0600	[thread overview]
Message-ID: <45843446.6010508@cs.utexas.edu> (raw)
In-Reply-To: <4584337D.6040706@cs.utexas.edu>

[-- Attachment #1: Type: text/plain, Size: 242 bytes --]

This patch introduces a unix: domain socket.  It reuses the tcp: code so 
it will behave almost identically.

An example usage would be:

qemu -hda ~/win2k.img -monitor unix:/home/anthony/monitor.sock,server,nowait

Regards,

Anthony Liguori

[-- Attachment #2: qemu-char-unix.diff --]
[-- Type: text/x-patch, Size: 7296 bytes --]

diff -r 01fafeaa2f64 qemu_socket.h
--- a/qemu_socket.h	Thu Dec 14 20:48:11 2006 +0000
+++ b/qemu_socket.h	Sat Dec 16 11:19:45 2006 -0600
@@ -19,6 +19,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
+#include <sys/un.h>
 
 #define socket_error() errno
 #define closesocket(s) close(s)
diff -r 01fafeaa2f64 vl.c
--- a/vl.c	Thu Dec 14 20:48:11 2006 +0000
+++ b/vl.c	Sat Dec 16 11:42:40 2006 -0600
@@ -2206,6 +2206,7 @@ static void udp_chr_add_read_handler(Cha
 }
 
 int parse_host_port(struct sockaddr_in *saddr, const char *str);
+int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
 int parse_host_src_port(struct sockaddr_in *haddr,
                         struct sockaddr_in *saddr,
                         const char *str);
@@ -2270,6 +2271,7 @@ typedef struct {
     int connected;
     int max_size;
     int do_telnetopt;
+    int is_unix;
 } TCPCharDriver;
 
 static void tcp_chr_accept(void *opaque);
@@ -2291,6 +2293,8 @@ static int tcp_chr_read_poll(void *opaqu
     TCPCharDriver *s = chr->opaque;
     if (!s->connected)
         return 0;
+    if (!s->fd_can_read)
+	return 0;
     s->max_size = s->fd_can_read(s->fd_opaque);
     return s->max_size;
 }
@@ -2416,12 +2420,25 @@ static void tcp_chr_accept(void *opaque)
     CharDriverState *chr = opaque;
     TCPCharDriver *s = chr->opaque;
     struct sockaddr_in saddr;
+#ifndef _WIN32
+    struct sockaddr_un uaddr;
+#endif
+    struct sockaddr *addr;
     socklen_t len;
     int fd;
 
     for(;;) {
-        len = sizeof(saddr);
-        fd = accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
+#ifndef _WIN32
+	if (s->is_unix) {
+	    len = sizeof(uaddr);
+	    addr = (struct sockaddr *)&uaddr;
+	} else
+#endif
+	{
+	    len = sizeof(saddr);
+	    addr = (struct sockaddr *)&saddr;
+	}
+        fd = accept(s->listen_fd, addr, &len);
         if (fd < 0 && errno != EINTR) {
             return;
         } else if (fd >= 0) {
@@ -2447,7 +2464,8 @@ static void tcp_chr_close(CharDriverStat
 }
 
 static CharDriverState *qemu_chr_open_tcp(const char *host_str, 
-                                          int is_telnet)
+                                          int is_telnet,
+					  int is_unix)
 {
     CharDriverState *chr = NULL;
     TCPCharDriver *s = NULL;
@@ -2456,9 +2474,26 @@ static CharDriverState *qemu_chr_open_tc
     int is_waitconnect = 1;
     const char *ptr;
     struct sockaddr_in saddr;
-
-    if (parse_host_port(&saddr, host_str) < 0)
-        goto fail;
+#ifndef _WIN32
+    struct sockaddr_un uaddr;
+#endif
+    struct sockaddr *addr;
+    socklen_t addrlen;
+
+#ifndef _WIN32
+    if (is_unix) {
+	addr = (struct sockaddr *)&uaddr;
+	addrlen = sizeof(uaddr);
+	if (parse_unix_path(&uaddr, host_str) < 0)
+	    goto fail;
+    } else
+#endif
+    {
+	addr = (struct sockaddr *)&saddr;
+	addrlen = sizeof(saddr);
+	if (parse_host_port(&saddr, host_str) < 0)
+	    goto fail;
+    }
 
     ptr = host_str;
     while((ptr = strchr(ptr,','))) {
@@ -2481,8 +2516,14 @@ static CharDriverState *qemu_chr_open_tc
     s = qemu_mallocz(sizeof(TCPCharDriver));
     if (!s)
         goto fail;
-    
-    fd = socket(PF_INET, SOCK_STREAM, 0);
+
+#ifndef _WIN32
+    if (is_unix)
+	fd = socket(PF_UNIX, SOCK_STREAM, 0);
+    else
+#endif
+	fd = socket(PF_INET, SOCK_STREAM, 0);
+	
     if (fd < 0) 
         goto fail;
 
@@ -2492,24 +2533,43 @@ static CharDriverState *qemu_chr_open_tc
     s->connected = 0;
     s->fd = -1;
     s->listen_fd = -1;
+    s->is_unix = is_unix;
+
+    chr->opaque = s;
+    chr->chr_write = tcp_chr_write;
+    chr->chr_add_read_handler = tcp_chr_add_read_handler;
+    chr->chr_close = tcp_chr_close;
+
     if (is_listen) {
         /* allow fast reuse */
-        val = 1;
-        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
+#ifndef _WIN32
+	if (is_unix) {
+	    char path[109];
+	    strncpy(path, uaddr.sun_path, 108);
+	    path[108] = 0;
+	    unlink(path);
+	} else
+#endif
+	{
+	    val = 1;
+	    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
+	}
         
-        ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
-        if (ret < 0) 
+        ret = bind(fd, addr, addrlen);
+        if (ret < 0)
             goto fail;
+
         ret = listen(fd, 0);
         if (ret < 0)
             goto fail;
+
         s->listen_fd = fd;
         qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
         if (is_telnet)
             s->do_telnetopt = 1;
     } else {
         for(;;) {
-            ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
+            ret = connect(fd, addr, addrlen);
             if (ret < 0) {
                 err = socket_error();
                 if (err == EINTR || err == EWOULDBLOCK) {
@@ -2530,10 +2590,6 @@ static CharDriverState *qemu_chr_open_tc
             qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
     }
     
-    chr->opaque = s;
-    chr->chr_write = tcp_chr_write;
-    chr->chr_add_read_handler = tcp_chr_add_read_handler;
-    chr->chr_close = tcp_chr_close;
     if (is_listen && is_waitconnect) {
         printf("QEMU waiting for connection on: %s\n", host_str);
         tcp_chr_accept(chr);
@@ -2559,16 +2615,18 @@ CharDriverState *qemu_chr_open(const cha
         return qemu_chr_open_null();
     } else 
     if (strstart(filename, "tcp:", &p)) {
-        return qemu_chr_open_tcp(p, 0);
+        return qemu_chr_open_tcp(p, 0, 0);
     } else
     if (strstart(filename, "telnet:", &p)) {
-        return qemu_chr_open_tcp(p, 1);
+        return qemu_chr_open_tcp(p, 1, 0);
     } else
     if (strstart(filename, "udp:", &p)) {
         return qemu_chr_open_udp(p);
     } else
 #ifndef _WIN32
-    if (strstart(filename, "file:", &p)) {
+    if (strstart(filename, "unix:", &p)) {
+	return qemu_chr_open_tcp(p, 0, 1);
+    } else if (strstart(filename, "file:", &p)) {
         return qemu_chr_open_file_out(p);
     } else if (strstart(filename, "pipe:", &p)) {
         return qemu_chr_open_pipe(p);
@@ -2740,6 +2798,24 @@ int parse_host_port(struct sockaddr_in *
     if (r == p)
         return -1;
     saddr->sin_port = htons(port);
+    return 0;
+}
+
+int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
+{
+    const char *p;
+    int len;
+
+    len = MIN(108, strlen(str));
+    p = strchr(str, ',');
+    if (p)
+	len = MIN(len, p - str);
+
+    memset(uaddr, 0, sizeof(*uaddr));
+
+    uaddr->sun_family = AF_UNIX;
+    memcpy(uaddr->sun_path, str, len);
+
     return 0;
 }
 
@@ -6955,6 +7031,7 @@ int main(int argc, char **argv)
             vm_start();
         }
     }
+
     main_loop();
     quit_timers();
     return 0;
diff -r 01fafeaa2f64 qemu-doc.texi
--- a/qemu-doc.texi	Thu Dec 14 20:48:11 2006 +0000
+++ b/qemu-doc.texi	Sat Dec 16 11:45:08 2006 -0600
@@ -586,6 +586,11 @@ sequence.  Typically in unix telnet you 
 sequence.  Typically in unix telnet you do it with Control-] and then
 type "send break" followed by pressing the enter key.
 
+@item unix:path[,server][,nowait]
+A unix domain socket is used instead of a tcp socket.  The option works the
+same as if you had specified @code{-serial tcp} except the unix domain socket
+@var{path} is used for connections.
+
 @end table
 
 @item -parallel dev

  reply	other threads:[~2006-12-16 18:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-12-16 17:57 [Qemu-devel] [PATCH 0/3] Add options to make writing a front end easier Anthony Liguori
2006-12-16 18:00 ` Anthony Liguori [this message]
2006-12-16 18:04 ` [Qemu-devel] [PATCH 2/3] Add unix domain socket and interface restriction to VNC Anthony Liguori
2006-12-16 18:08 ` [Qemu-devel] [PATCH 3/3] Add daemonize option Anthony Liguori
2006-12-19  1:08   ` [Qemu-devel] [PATCH 3/3] [UPDATE] " Anthony Liguori

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=45843446.6010508@cs.utexas.edu \
    --to=aliguori@cs.utexas.edu \
    --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.