convert unix+tcp chardevs to QemuOpts.
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 <kraxel@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
e5bc776fa9
commit
aeb2c47a1e
120
qemu-char.c
120
qemu-char.c
@ -2116,67 +2116,39 @@ static void tcp_chr_close(CharDriverState *chr)
|
|||||||
qemu_chr_event(chr, CHR_EVENT_CLOSED);
|
qemu_chr_event(chr, CHR_EVENT_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CharDriverState *qemu_chr_open_tcp(const char *host_str,
|
static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
|
||||||
int is_telnet,
|
|
||||||
int is_unix)
|
|
||||||
{
|
{
|
||||||
CharDriverState *chr = NULL;
|
CharDriverState *chr = NULL;
|
||||||
TCPCharDriver *s = NULL;
|
TCPCharDriver *s = NULL;
|
||||||
int fd = -1, offset = 0;
|
int fd = -1;
|
||||||
int is_listen = 0;
|
int is_listen;
|
||||||
int is_waitconnect = 1;
|
int is_waitconnect;
|
||||||
int do_nodelay = 0;
|
int do_nodelay;
|
||||||
const char *ptr;
|
int is_unix;
|
||||||
|
int is_telnet;
|
||||||
|
|
||||||
ptr = host_str;
|
is_listen = qemu_opt_get_bool(opts, "server", 0);
|
||||||
while((ptr = strchr(ptr,','))) {
|
is_waitconnect = qemu_opt_get_bool(opts, "wait", 1);
|
||||||
ptr++;
|
is_telnet = qemu_opt_get_bool(opts, "telnet", 0);
|
||||||
if (!strncmp(ptr,"server",6)) {
|
do_nodelay = !qemu_opt_get_bool(opts, "delay", 1);
|
||||||
is_listen = 1;
|
is_unix = qemu_opt_get(opts, "path") != NULL;
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!is_listen)
|
if (!is_listen)
|
||||||
is_waitconnect = 0;
|
is_waitconnect = 0;
|
||||||
|
|
||||||
chr = qemu_mallocz(sizeof(CharDriverState));
|
chr = qemu_mallocz(sizeof(CharDriverState));
|
||||||
s = qemu_mallocz(sizeof(TCPCharDriver));
|
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_unix) {
|
||||||
if (is_listen) {
|
if (is_listen) {
|
||||||
fd = unix_listen(host_str, chr->filename + offset, 256 - offset);
|
fd = unix_listen_opts(opts);
|
||||||
} else {
|
} else {
|
||||||
fd = unix_connect(host_str);
|
fd = unix_connect_opts(opts);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (is_listen) {
|
if (is_listen) {
|
||||||
fd = inet_listen(host_str, chr->filename + offset, 256 - offset,
|
fd = inet_listen_opts(opts, 0);
|
||||||
SOCK_STREAM, 0);
|
|
||||||
} else {
|
} else {
|
||||||
fd = inet_connect(host_str, SOCK_STREAM);
|
fd = inet_connect_opts(opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fd < 0)
|
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);
|
qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
|
||||||
if (is_telnet)
|
if (is_telnet)
|
||||||
s->do_telnetopt = 1;
|
s->do_telnetopt = 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
s->connected = 1;
|
s->connected = 1;
|
||||||
s->fd = fd;
|
s->fd = fd;
|
||||||
@ -2209,14 +2182,30 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
|
|||||||
tcp_chr_connect(chr);
|
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) {
|
if (is_listen && is_waitconnect) {
|
||||||
printf("QEMU waiting for connection on: %s\n",
|
printf("QEMU waiting for connection on: %s\n",
|
||||||
chr->filename ? chr->filename : host_str);
|
chr->filename);
|
||||||
tcp_chr_accept(chr);
|
tcp_chr_accept(chr);
|
||||||
socket_set_nonblock(s->listen_fd);
|
socket_set_nonblock(s->listen_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return chr;
|
return chr;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
closesocket(fd);
|
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)
|
static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
|
||||||
{
|
{
|
||||||
|
char host[65], port[33];
|
||||||
|
int pos;
|
||||||
const char *p;
|
const char *p;
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
|
|
||||||
@ -2248,7 +2239,33 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
|
|||||||
qemu_opt_set(opts, "path", p);
|
qemu_opt_set(opts, "path", p);
|
||||||
return opts;
|
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);
|
qemu_opts_del(opts);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -2258,6 +2275,7 @@ static const struct {
|
|||||||
CharDriverState *(*open)(QemuOpts *opts);
|
CharDriverState *(*open)(QemuOpts *opts);
|
||||||
} backend_table[] = {
|
} backend_table[] = {
|
||||||
{ .name = "null", .open = qemu_chr_open_null },
|
{ .name = "null", .open = qemu_chr_open_null },
|
||||||
|
{ .name = "socket", .open = qemu_chr_open_socket },
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
{ .name = "file", .open = qemu_chr_open_win_file_out },
|
{ .name = "file", .open = qemu_chr_open_win_file_out },
|
||||||
{ .name = "pipe", .open = qemu_chr_open_win_pipe },
|
{ .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)) {
|
if (strstart(filename, "vc:", &p)) {
|
||||||
chr = text_console_init(p);
|
chr = text_console_init(p);
|
||||||
} else
|
} 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)) {
|
if (strstart(filename, "udp:", &p)) {
|
||||||
chr = qemu_chr_open_udp(p);
|
chr = qemu_chr_open_udp(p);
|
||||||
} else
|
} else
|
||||||
@ -2341,9 +2353,7 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
|
|||||||
chr = qemu_chr_open_msmouse();
|
chr = qemu_chr_open_msmouse();
|
||||||
} else
|
} else
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (strstart(filename, "unix:", &p)) {
|
if (!strcmp(filename, "pty")) {
|
||||||
chr = qemu_chr_open_tcp(p, 0, 1);
|
|
||||||
} else if (!strcmp(filename, "pty")) {
|
|
||||||
chr = qemu_chr_open_pty();
|
chr = qemu_chr_open_pty();
|
||||||
} else if (!strcmp(filename, "stdio")) {
|
} else if (!strcmp(filename, "stdio")) {
|
||||||
chr = qemu_chr_open_stdio();
|
chr = qemu_chr_open_stdio();
|
||||||
|
@ -85,6 +85,33 @@ QemuOptsList qemu_chardev_opts = {
|
|||||||
},{
|
},{
|
||||||
.name = "path",
|
.name = "path",
|
||||||
.type = QEMU_OPT_STRING,
|
.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 */ }
|
{ /* end if list */ }
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user