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
next prev parent 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.