Merge remote-tracking branch 'mjt/trivial-patches' into staging
# By Gerd Hoffmann (13) and Michael Tokarev (1) # Via Michael Tokarev * mjt/trivial-patches: doc: we use seabios, not bochs bios qemu-socket: don't leak opts on error qemu-char: report udp backend errors qemu-char: add -chardev mux support qemu-char: minor mux chardev fixes qemu-char: use ChardevBackendKind in CharDriver qemu-char: don't leak opts on error qemu-char: fix documentation for telnet+wait socket flags qemu-char: print notification to stderr qemu-char: use more specific error_setg_* variants qemu-char: check optional fields using has_* qemu-socket: catch monitor_get_fd failures qemu-socket: drop pointless allocation qemu-socket: zero-initialize SocketAddress Message-id: 1372443465-22384-1-git-send-email-mjt@msgid.tls.msk.ru Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
		
						commit
						ffeec223b5
					
				@ -281,7 +281,7 @@ CharDriverState *qemu_chr_find(const char *name);
 | 
				
			|||||||
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
 | 
					QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *));
 | 
					void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *));
 | 
				
			||||||
void register_char_driver_qapi(const char *name, int kind,
 | 
					void register_char_driver_qapi(const char *name, ChardevBackendKind kind,
 | 
				
			||||||
        void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp));
 | 
					        void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* add an eventfd to the qemu devices that are polled */
 | 
					/* add an eventfd to the qemu devices that are polled */
 | 
				
			||||||
 | 
				
			|||||||
@ -3288,10 +3288,11 @@
 | 
				
			|||||||
# @addr: socket address to listen on (server=true)
 | 
					# @addr: socket address to listen on (server=true)
 | 
				
			||||||
#        or connect to (server=false)
 | 
					#        or connect to (server=false)
 | 
				
			||||||
# @server: #optional create server socket (default: true)
 | 
					# @server: #optional create server socket (default: true)
 | 
				
			||||||
# @wait: #optional wait for connect (not used for server
 | 
					# @wait: #optional wait for incoming connection on server
 | 
				
			||||||
#        sockets, default: false)
 | 
					#        sockets (default: false).
 | 
				
			||||||
# @nodelay: #optional set TCP_NODELAY socket option (default: false)
 | 
					# @nodelay: #optional set TCP_NODELAY socket option (default: false)
 | 
				
			||||||
# @telnet: #optional enable telnet protocol (default: false)
 | 
					# @telnet: #optional enable telnet protocol on server
 | 
				
			||||||
 | 
					#          sockets (default: false)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Since: 1.4
 | 
					# Since: 1.4
 | 
				
			||||||
##
 | 
					##
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										43
									
								
								qemu-char.c
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								qemu-char.c
									
									
									
									
									
								
							@ -2255,6 +2255,8 @@ static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fd = inet_dgram_opts(opts, &local_err);
 | 
					    fd = inet_dgram_opts(opts, &local_err);
 | 
				
			||||||
    if (fd < 0) {
 | 
					    if (fd < 0) {
 | 
				
			||||||
 | 
					        qerror_report_err(local_err);
 | 
				
			||||||
 | 
					        error_free(local_err);
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return qemu_chr_open_udp_fd(fd);
 | 
					    return qemu_chr_open_udp_fd(fd);
 | 
				
			||||||
@ -2604,7 +2606,7 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    memset(&ss, 0, ss_len);
 | 
					    memset(&ss, 0, ss_len);
 | 
				
			||||||
    if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) != 0) {
 | 
					    if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) != 0) {
 | 
				
			||||||
        error_setg(errp, "getsockname: %s", strerror(errno));
 | 
					        error_setg_errno(errp, errno, "getsockname");
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2666,7 +2668,7 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (is_listen && is_waitconnect) {
 | 
					    if (is_listen && is_waitconnect) {
 | 
				
			||||||
        printf("QEMU waiting for connection on: %s\n",
 | 
					        fprintf(stderr, "QEMU waiting for connection on: %s\n",
 | 
				
			||||||
                chr->filename);
 | 
					                chr->filename);
 | 
				
			||||||
        tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
 | 
					        tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
 | 
				
			||||||
        qemu_set_nonblock(s->listen_fd);
 | 
					        qemu_set_nonblock(s->listen_fd);
 | 
				
			||||||
@ -3115,12 +3117,25 @@ static void qemu_chr_parse_memory(QemuOpts *opts, ChardevBackend *backend,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
 | 
				
			||||||
 | 
					                               Error **errp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const char *chardev = qemu_opt_get(opts, "chardev");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (chardev == NULL) {
 | 
				
			||||||
 | 
					        error_setg(errp, "chardev: mux: no chardev given");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    backend->mux = g_new0(ChardevMux, 1);
 | 
				
			||||||
 | 
					    backend->mux->chardev = g_strdup(chardev);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct CharDriver {
 | 
					typedef struct CharDriver {
 | 
				
			||||||
    const char *name;
 | 
					    const char *name;
 | 
				
			||||||
    /* old, pre qapi */
 | 
					    /* old, pre qapi */
 | 
				
			||||||
    CharDriverState *(*open)(QemuOpts *opts);
 | 
					    CharDriverState *(*open)(QemuOpts *opts);
 | 
				
			||||||
    /* new, qapi-based */
 | 
					    /* new, qapi-based */
 | 
				
			||||||
    int kind;
 | 
					    ChardevBackendKind kind;
 | 
				
			||||||
    void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
 | 
					    void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
 | 
				
			||||||
} CharDriver;
 | 
					} CharDriver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3137,7 +3152,7 @@ void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *)
 | 
				
			|||||||
    backends = g_slist_append(backends, s);
 | 
					    backends = g_slist_append(backends, s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void register_char_driver_qapi(const char *name, int kind,
 | 
					void register_char_driver_qapi(const char *name, ChardevBackendKind kind,
 | 
				
			||||||
        void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp))
 | 
					        void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CharDriver *s;
 | 
					    CharDriver *s;
 | 
				
			||||||
@ -3178,7 +3193,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 | 
				
			|||||||
    if (i == NULL) {
 | 
					    if (i == NULL) {
 | 
				
			||||||
        error_setg(errp, "chardev: backend \"%s\" not found",
 | 
					        error_setg(errp, "chardev: backend \"%s\" not found",
 | 
				
			||||||
                   qemu_opt_get(opts, "backend"));
 | 
					                   qemu_opt_get(opts, "backend"));
 | 
				
			||||||
        return NULL;
 | 
					        goto err;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!cd->open) {
 | 
					    if (!cd->open) {
 | 
				
			||||||
@ -3186,7 +3201,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 | 
				
			|||||||
        ChardevBackend *backend = g_new0(ChardevBackend, 1);
 | 
					        ChardevBackend *backend = g_new0(ChardevBackend, 1);
 | 
				
			||||||
        ChardevReturn *ret = NULL;
 | 
					        ChardevReturn *ret = NULL;
 | 
				
			||||||
        const char *id = qemu_opts_id(opts);
 | 
					        const char *id = qemu_opts_id(opts);
 | 
				
			||||||
        const char *bid = NULL;
 | 
					        char *bid = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (qemu_opt_get_bool(opts, "mux", 0)) {
 | 
					        if (qemu_opt_get_bool(opts, "mux", 0)) {
 | 
				
			||||||
            bid = g_strdup_printf("%s-base", id);
 | 
					            bid = g_strdup_printf("%s-base", id);
 | 
				
			||||||
@ -3213,9 +3228,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 | 
				
			|||||||
            backend->kind = CHARDEV_BACKEND_KIND_MUX;
 | 
					            backend->kind = CHARDEV_BACKEND_KIND_MUX;
 | 
				
			||||||
            backend->mux->chardev = g_strdup(bid);
 | 
					            backend->mux->chardev = g_strdup(bid);
 | 
				
			||||||
            ret = qmp_chardev_add(id, backend, errp);
 | 
					            ret = qmp_chardev_add(id, backend, errp);
 | 
				
			||||||
            if (error_is_set(errp)) {
 | 
					            assert(!error_is_set(errp));
 | 
				
			||||||
                goto qapi_out;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        chr = qemu_chr_find(id);
 | 
					        chr = qemu_chr_find(id);
 | 
				
			||||||
@ -3224,6 +3237,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 | 
				
			|||||||
    qapi_out:
 | 
					    qapi_out:
 | 
				
			||||||
        qapi_free_ChardevBackend(backend);
 | 
					        qapi_free_ChardevBackend(backend);
 | 
				
			||||||
        qapi_free_ChardevReturn(ret);
 | 
					        qapi_free_ChardevReturn(ret);
 | 
				
			||||||
 | 
					        g_free(bid);
 | 
				
			||||||
        return chr;
 | 
					        return chr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3483,6 +3497,9 @@ QemuOptsList qemu_chardev_opts = {
 | 
				
			|||||||
        },{
 | 
					        },{
 | 
				
			||||||
            .name = "size",
 | 
					            .name = "size",
 | 
				
			||||||
            .type = QEMU_OPT_SIZE,
 | 
					            .type = QEMU_OPT_SIZE,
 | 
				
			||||||
 | 
					        },{
 | 
				
			||||||
 | 
					            .name = "chardev",
 | 
				
			||||||
 | 
					            .type = QEMU_OPT_STRING,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        { /* end of list */ }
 | 
					        { /* end of list */ }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@ -3494,7 +3511,7 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    HANDLE out;
 | 
					    HANDLE out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (file->in) {
 | 
					    if (file->has_in) {
 | 
				
			||||||
        error_setg(errp, "input file not supported");
 | 
					        error_setg(errp, "input file not supported");
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -3530,7 +3547,7 @@ static int qmp_chardev_open_file_source(char *src, int flags,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    TFR(fd = qemu_open(src, flags, 0666));
 | 
					    TFR(fd = qemu_open(src, flags, 0666));
 | 
				
			||||||
    if (fd == -1) {
 | 
					    if (fd == -1) {
 | 
				
			||||||
        error_setg(errp, "open %s: %s", src, strerror(errno));
 | 
					        error_setg_file_open(errp, errno, src);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return fd;
 | 
					    return fd;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -3545,7 +3562,7 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
 | 
				
			|||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (file->in) {
 | 
					    if (file->has_in) {
 | 
				
			||||||
        flags = O_RDONLY;
 | 
					        flags = O_RDONLY;
 | 
				
			||||||
        in = qmp_chardev_open_file_source(file->in, flags, errp);
 | 
					        in = qmp_chardev_open_file_source(file->in, flags, errp);
 | 
				
			||||||
        if (error_is_set(errp)) {
 | 
					        if (error_is_set(errp)) {
 | 
				
			||||||
@ -3773,6 +3790,8 @@ static void register_types(void)
 | 
				
			|||||||
    register_char_driver_qapi("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL);
 | 
					    register_char_driver_qapi("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL);
 | 
				
			||||||
    register_char_driver_qapi("pipe", CHARDEV_BACKEND_KIND_PIPE,
 | 
					    register_char_driver_qapi("pipe", CHARDEV_BACKEND_KIND_PIPE,
 | 
				
			||||||
                              qemu_chr_parse_pipe);
 | 
					                              qemu_chr_parse_pipe);
 | 
				
			||||||
 | 
					    register_char_driver_qapi("mux", CHARDEV_BACKEND_KIND_MUX,
 | 
				
			||||||
 | 
					                              qemu_chr_parse_mux);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type_init(register_types);
 | 
					type_init(register_types);
 | 
				
			||||||
 | 
				
			|||||||
@ -214,7 +214,7 @@ PCI UHCI USB controller and a virtual USB hub.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
SMP is supported with up to 255 CPUs.
 | 
					SMP is supported with up to 255 CPUs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL
 | 
					QEMU uses the PC BIOS from the Seabios project and the Plex86/Bochs LGPL
 | 
				
			||||||
VGA BIOS.
 | 
					VGA BIOS.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QEMU uses YM3812 emulation by Tatsuyuki Satoh.
 | 
					QEMU uses YM3812 emulation by Tatsuyuki Satoh.
 | 
				
			||||||
 | 
				
			|||||||
@ -848,9 +848,9 @@ int unix_nonblocking_connect(const char *path,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
SocketAddress *socket_parse(const char *str, Error **errp)
 | 
					SocketAddress *socket_parse(const char *str, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SocketAddress *addr = NULL;
 | 
					    SocketAddress *addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    addr = g_new(SocketAddress, 1);
 | 
					    addr = g_new0(SocketAddress, 1);
 | 
				
			||||||
    if (strstart(str, "unix:", NULL)) {
 | 
					    if (strstart(str, "unix:", NULL)) {
 | 
				
			||||||
        if (str[5] == '\0') {
 | 
					        if (str[5] == '\0') {
 | 
				
			||||||
            error_setg(errp, "invalid Unix socket address");
 | 
					            error_setg(errp, "invalid Unix socket address");
 | 
				
			||||||
@ -871,7 +871,6 @@ SocketAddress *socket_parse(const char *str, Error **errp)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        addr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
					        addr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
				
			||||||
        addr->inet = g_new(InetSocketAddress, 1);
 | 
					 | 
				
			||||||
        addr->inet = inet_parse(str, errp);
 | 
					        addr->inet = inet_parse(str, errp);
 | 
				
			||||||
        if (addr->inet == NULL) {
 | 
					        if (addr->inet == NULL) {
 | 
				
			||||||
            goto fail;
 | 
					            goto fail;
 | 
				
			||||||
@ -904,7 +903,7 @@ int socket_connect(SocketAddress *addr, Error **errp,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    case SOCKET_ADDRESS_KIND_FD:
 | 
					    case SOCKET_ADDRESS_KIND_FD:
 | 
				
			||||||
        fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
 | 
					        fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
 | 
				
			||||||
        if (callback) {
 | 
					        if (fd >= 0 && callback) {
 | 
				
			||||||
            qemu_set_nonblock(fd);
 | 
					            qemu_set_nonblock(fd);
 | 
				
			||||||
            callback(fd, opaque);
 | 
					            callback(fd, opaque);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -964,7 +963,7 @@ int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        error_setg(errp, "socket type unsupported for datagram");
 | 
					        error_setg(errp, "socket type unsupported for datagram");
 | 
				
			||||||
        return -1;
 | 
					        fd = -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    qemu_opts_del(opts);
 | 
					    qemu_opts_del(opts);
 | 
				
			||||||
    return fd;
 | 
					    return fd;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user