From patchwork Thu Sep 10 08:58:42 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 33284 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by bilbo.ozlabs.org (Postfix) with ESMTPS id 8184DB7080 for ; Thu, 10 Sep 2009 19:29:59 +1000 (EST) Received: from localhost ([127.0.0.1]:53234 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MlfyV-0000V8-R5 for incoming@patchwork.ozlabs.org; Thu, 10 Sep 2009 05:29:55 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MlfUs-0005Uy-WD for qemu-devel@nongnu.org; Thu, 10 Sep 2009 04:59:19 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MlfUo-0005SG-Mm for qemu-devel@nongnu.org; Thu, 10 Sep 2009 04:59:18 -0400 Received: from [199.232.76.173] (port=49331 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MlfUo-0005SA-6R for qemu-devel@nongnu.org; Thu, 10 Sep 2009 04:59:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:10258) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MlfUn-0007XQ-9G for qemu-devel@nongnu.org; Thu, 10 Sep 2009 04:59:13 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n8A8xC3i020999 for ; Thu, 10 Sep 2009 04:59:12 -0400 Received: from zweiblum.home.kraxel.org (vpn2-9-74.ams2.redhat.com [10.36.9.74]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id n8A8x3Zc009502; Thu, 10 Sep 2009 04:59:04 -0400 Received: by zweiblum.home.kraxel.org (Postfix, from userid 500) id 8FCD5700E9; Thu, 10 Sep 2009 10:58:56 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 10 Sep 2009 10:58:42 +0200 Message-Id: <1252573135-27688-11-git-send-email-kraxel@redhat.com> In-Reply-To: <1252573135-27688-1-git-send-email-kraxel@redhat.com> References: <1252573135-27688-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH v2 10/23] convert unix+tcp chardevs to QemuOpts. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org new cmd line syntax: unix socket: -chardev socket,id=name,path=/path/to/socket tcp socket: -chardev socket,id=name,host=hostaddr|ipaddr,port=portnr server and nowait options work as usual. Alternatively you can use server=[on|off] + wait=[on|off] syntax. Signed-off-by: Gerd Hoffmann --- qemu-char.c | 122 +++++++++++++++++++++++++++++++-------------------------- qemu-config.c | 27 +++++++++++++ 2 files changed, 93 insertions(+), 56 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 0573033..bff160e 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2116,67 +2116,39 @@ static void tcp_chr_close(CharDriverState *chr) qemu_chr_event(chr, CHR_EVENT_CLOSED); } -static CharDriverState *qemu_chr_open_tcp(const char *host_str, - int is_telnet, - int is_unix) +static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) { CharDriverState *chr = NULL; TCPCharDriver *s = NULL; - int fd = -1, offset = 0; - int is_listen = 0; - int is_waitconnect = 1; - int do_nodelay = 0; - const char *ptr; - - ptr = host_str; - while((ptr = strchr(ptr,','))) { - ptr++; - if (!strncmp(ptr,"server",6)) { - is_listen = 1; - } else if (!strncmp(ptr,"nowait",6)) { - is_waitconnect = 0; - } else if (!strncmp(ptr,"nodelay",6)) { - do_nodelay = 1; - } else if (!strncmp(ptr,"to=",3)) { - /* nothing, inet_listen() parses this one */; - } else if (!strncmp(ptr,"ipv4",4)) { - /* nothing, inet_connect() and inet_listen() parse this one */; - } else if (!strncmp(ptr,"ipv6",4)) { - /* nothing, inet_connect() and inet_listen() parse this one */; - } else { - printf("Unknown option: %s\n", ptr); - goto fail; - } - } + int fd = -1; + int is_listen; + int is_waitconnect; + int do_nodelay; + int is_unix; + int is_telnet; + + is_listen = qemu_opt_get_bool(opts, "server", 0); + is_waitconnect = qemu_opt_get_bool(opts, "wait", 1); + is_telnet = qemu_opt_get_bool(opts, "telnet", 0); + do_nodelay = !qemu_opt_get_bool(opts, "delay", 1); + is_unix = qemu_opt_get(opts, "path") != NULL; if (!is_listen) is_waitconnect = 0; chr = qemu_mallocz(sizeof(CharDriverState)); s = qemu_mallocz(sizeof(TCPCharDriver)); - if (is_listen) { - chr->filename = qemu_malloc(256); - if (is_unix) { - pstrcpy(chr->filename, 256, "unix:"); - } else if (is_telnet) { - pstrcpy(chr->filename, 256, "telnet:"); - } else { - pstrcpy(chr->filename, 256, "tcp:"); - } - offset = strlen(chr->filename); - } if (is_unix) { if (is_listen) { - fd = unix_listen(host_str, chr->filename + offset, 256 - offset); + fd = unix_listen_opts(opts); } else { - fd = unix_connect(host_str); + fd = unix_connect_opts(opts); } } else { if (is_listen) { - fd = inet_listen(host_str, chr->filename + offset, 256 - offset, - SOCK_STREAM, 0); + fd = inet_listen_opts(opts, 0); } else { - fd = inet_connect(host_str, SOCK_STREAM); + fd = inet_connect_opts(opts); } } if (fd < 0) @@ -2202,6 +2174,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr); if (is_telnet) s->do_telnetopt = 1; + } else { s->connected = 1; s->fd = fd; @@ -2209,14 +2182,30 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, tcp_chr_connect(chr); } + /* for "info chardev" monitor command */ + chr->filename = qemu_malloc(256); + if (is_unix) { + snprintf(chr->filename, 256, "unix:%s%s", + qemu_opt_get(opts, "path"), + qemu_opt_get_bool(opts, "server", 0) ? ",server" : ""); + } else if (is_telnet) { + snprintf(chr->filename, 256, "telnet:%s:%s%s", + qemu_opt_get(opts, "host"), qemu_opt_get(opts, "port"), + qemu_opt_get_bool(opts, "server", 0) ? ",server" : ""); + } else { + snprintf(chr->filename, 256, "tcp:%s:%s%s", + qemu_opt_get(opts, "host"), qemu_opt_get(opts, "port"), + qemu_opt_get_bool(opts, "server", 0) ? ",server" : ""); + } + if (is_listen && is_waitconnect) { printf("QEMU waiting for connection on: %s\n", - chr->filename ? chr->filename : host_str); + chr->filename); tcp_chr_accept(chr); socket_set_nonblock(s->listen_fd); } - return chr; + fail: if (fd >= 0) closesocket(fd); @@ -2227,6 +2216,8 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename) { + char host[65], port[33]; + int pos; const char *p; QemuOpts *opts; @@ -2248,7 +2239,33 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename) qemu_opt_set(opts, "path", p); return opts; } + if (strstart(filename, "tcp:", &p) || + strstart(filename, "telnet:", &p)) { + if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) { + host[0] = 0; + if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) + goto fail; + } + qemu_opt_set(opts, "backend", "socket"); + qemu_opt_set(opts, "host", host); + qemu_opt_set(opts, "port", port); + if (p[pos] == ',') { + if (qemu_opts_do_parse(opts, p+pos+1, NULL) != 0) + goto fail; + } + if (strstart(filename, "telnet:", &p)) + qemu_opt_set(opts, "telnet", "on"); + return opts; + } + if (strstart(filename, "unix:", &p)) { + qemu_opt_set(opts, "backend", "socket"); + if (qemu_opts_do_parse(opts, p, "path") != 0) + goto fail; + return opts; + } +fail: + fprintf(stderr, "%s: fail on \"%s\"\n", __FUNCTION__, filename); qemu_opts_del(opts); return NULL; } @@ -2258,6 +2275,7 @@ static const struct { CharDriverState *(*open)(QemuOpts *opts); } backend_table[] = { { .name = "null", .open = qemu_chr_open_null }, + { .name = "socket", .open = qemu_chr_open_socket }, #ifdef _WIN32 { .name = "file", .open = qemu_chr_open_win_file_out }, { .name = "pipe", .open = qemu_chr_open_win_pipe }, @@ -2320,12 +2338,6 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i if (strstart(filename, "vc:", &p)) { chr = text_console_init(p); } else - if (strstart(filename, "tcp:", &p)) { - chr = qemu_chr_open_tcp(p, 0, 0); - } else - if (strstart(filename, "telnet:", &p)) { - chr = qemu_chr_open_tcp(p, 1, 0); - } else if (strstart(filename, "udp:", &p)) { chr = qemu_chr_open_udp(p); } else @@ -2341,9 +2353,7 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i chr = qemu_chr_open_msmouse(); } else #ifndef _WIN32 - if (strstart(filename, "unix:", &p)) { - chr = qemu_chr_open_tcp(p, 0, 1); - } else if (!strcmp(filename, "pty")) { + if (!strcmp(filename, "pty")) { chr = qemu_chr_open_pty(); } else if (!strcmp(filename, "stdio")) { chr = qemu_chr_open_stdio(); diff --git a/qemu-config.c b/qemu-config.c index 49be6be..3b5083c 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -85,6 +85,33 @@ QemuOptsList qemu_chardev_opts = { },{ .name = "path", .type = QEMU_OPT_STRING, + },{ + .name = "host", + .type = QEMU_OPT_STRING, + },{ + .name = "port", + .type = QEMU_OPT_STRING, + },{ + .name = "to", + .type = QEMU_OPT_NUMBER, + },{ + .name = "ipv4", + .type = QEMU_OPT_BOOL, + },{ + .name = "ipv6", + .type = QEMU_OPT_BOOL, + },{ + .name = "wait", + .type = QEMU_OPT_BOOL, + },{ + .name = "server", + .type = QEMU_OPT_BOOL, + },{ + .name = "delay", + .type = QEMU_OPT_BOOL, + },{ + .name = "telnet", + .type = QEMU_OPT_BOOL, }, { /* end if list */ } },