Skip to content

Commit

Permalink
chardev: update net listener gcontext
Browse files Browse the repository at this point in the history
TCP chardevs can be using QIO network listeners working in the
background when in listening mode.  However the network listeners are
always running in main context.  This can race with chardevs that are
running in non-main contexts.

To solve this, we need to re-setup the net listeners in
tcp_chr_update_read_handler() with the newly cached gcontext.

Reviewed-by: Marc-André Lureau <[email protected]>
Signed-off-by: Peter Xu <[email protected]>
Message-Id: <[email protected]>
Acked-by: Stefan Hajnoczi <[email protected]>
Reviewed-by: Daniel P. Berrangé <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
xzpeter authored and bonzini committed Mar 12, 2018
1 parent c863fde commit 3da9de5
Showing 1 changed file with 20 additions and 6 deletions.
26 changes: 20 additions & 6 deletions chardev/char-socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,8 @@ static void tcp_chr_disconnect(Chardev *chr)
tcp_chr_free_connection(chr);

if (s->listener) {
qio_net_listener_set_client_func(s->listener, tcp_chr_accept,
chr, NULL);
qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
chr, NULL, chr->gcontext);
}
update_disconnected_filename(s);
if (emit_close) {
Expand Down Expand Up @@ -560,6 +560,16 @@ static void tcp_chr_update_read_handler(Chardev *chr)
{
SocketChardev *s = SOCKET_CHARDEV(chr);

if (s->listener) {
/*
* It's possible that chardev context is changed in
* qemu_chr_be_update_read_handlers(). Reset it for QIO net
* listener if there is.
*/
qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
chr, NULL, chr->gcontext);
}

if (!s->connected) {
return;
}
Expand Down Expand Up @@ -744,7 +754,8 @@ static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
qio_channel_set_delay(s->ioc, false);
}
if (s->listener) {
qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
NULL, chr->gcontext);
}

if (s->tls_creds) {
Expand Down Expand Up @@ -825,7 +836,8 @@ static void char_socket_finalize(Object *obj)
tcp_chr_reconn_timer_cancel(s);
qapi_free_SocketAddress(s->addr);
if (s->listener) {
qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
NULL, chr->gcontext);
object_unref(OBJECT(s->listener));
}
if (s->tls_creds) {
Expand Down Expand Up @@ -981,8 +993,10 @@ static void qmp_chardev_open_socket(Chardev *chr,
return;
}
if (!s->ioc) {
qio_net_listener_set_client_func(s->listener, tcp_chr_accept,
chr, NULL);
qio_net_listener_set_client_func_full(s->listener,
tcp_chr_accept,
chr, NULL,
chr->gcontext);
}
} else if (qemu_chr_wait_connected(chr, errp) < 0) {
goto error;
Expand Down

0 comments on commit 3da9de5

Please sign in to comment.