On Mon, Dec 28, 2020 at 7:08 PM Lukas Straub <lukasstra...@web.de> wrote:
> Register a yank function to shutdown the socket on yank. > > Signed-off-by: Lukas Straub <lukasstra...@web.de> > Acked-by: Stefan Hajnoczi <stefa...@redhat.com> > Acked-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- > chardev/char-socket.c | 34 ++++++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/chardev/char-socket.c b/chardev/char-socket.c > index 213a4c8dd0..8a707d766c 100644 > --- a/chardev/char-socket.c > +++ b/chardev/char-socket.c > @@ -34,6 +34,7 @@ > #include "qapi/error.h" > #include "qapi/clone-visitor.h" > #include "qapi/qapi-visit-sockets.h" > +#include "qemu/yank.h" > > #include "chardev/char-io.h" > #include "qom/object.h" > @@ -70,6 +71,7 @@ struct SocketChardev { > size_t read_msgfds_num; > int *write_msgfds; > size_t write_msgfds_num; > + bool registered_yank; > > SocketAddress *addr; > bool is_listen; > @@ -415,6 +417,12 @@ static void tcp_chr_free_connection(Chardev *chr) > > tcp_set_msgfds(chr, NULL, 0); > remove_fd_in_watch(chr); > + if (s->state == TCP_CHARDEV_STATE_CONNECTING > + || s->state == TCP_CHARDEV_STATE_CONNECTED) { > + yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label), > + yank_generic_iochannel, > + QIO_CHANNEL(s->sioc)); > + } > object_unref(OBJECT(s->sioc)); > s->sioc = NULL; > object_unref(OBJECT(s->ioc)); > @@ -932,6 +940,9 @@ static int tcp_chr_add_client(Chardev *chr, int fd) > } > tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); > tcp_chr_set_client_ioc_name(chr, sioc); > + yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), > + yank_generic_iochannel, > + QIO_CHANNEL(sioc)); > ret = tcp_chr_new_client(chr, sioc); > object_unref(OBJECT(sioc)); > return ret; > @@ -946,6 +957,9 @@ static void tcp_chr_accept(QIONetListener *listener, > > tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); > tcp_chr_set_client_ioc_name(chr, cioc); > + yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), > + yank_generic_iochannel, > + QIO_CHANNEL(cioc)); > tcp_chr_new_client(chr, cioc); > } > > @@ -961,6 +975,9 @@ static int tcp_chr_connect_client_sync(Chardev *chr, > Error **errp) > object_unref(OBJECT(sioc)); > return -1; > } > + yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), > + yank_generic_iochannel, > + QIO_CHANNEL(sioc)); > tcp_chr_new_client(chr, sioc); > object_unref(OBJECT(sioc)); > return 0; > @@ -976,6 +993,9 @@ static void tcp_chr_accept_server_sync(Chardev *chr) > tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); > sioc = qio_net_listener_wait_client(s->listener); > tcp_chr_set_client_ioc_name(chr, sioc); > + yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), > + yank_generic_iochannel, > + QIO_CHANNEL(sioc)); > tcp_chr_new_client(chr, sioc); > object_unref(OBJECT(sioc)); > } > @@ -1086,6 +1106,9 @@ static void char_socket_finalize(Object *obj) > object_unref(OBJECT(s->tls_creds)); > } > g_free(s->tls_authz); > + if (s->registered_yank) { > + yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label)); > + } > > qemu_chr_be_event(chr, CHR_EVENT_CLOSED); > } > @@ -1101,6 +1124,9 @@ static void qemu_chr_socket_connected(QIOTask *task, > void *opaque) > > if (qio_task_propagate_error(task, &err)) { > tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); > + yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label), > + yank_generic_iochannel, > + QIO_CHANNEL(sioc)); > check_report_connect_error(chr, err); > goto cleanup; > } > @@ -1134,6 +1160,9 @@ static void tcp_chr_connect_client_async(Chardev > *chr) > tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); > sioc = qio_channel_socket_new(); > tcp_chr_set_client_ioc_name(chr, sioc); > + yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), > + yank_generic_iochannel, > + QIO_CHANNEL(sioc)); > /* > * Normally code would use the qio_channel_socket_connect_async > * method which uses a QIOTask + qio_task_set_error internally > @@ -1376,6 +1405,11 @@ static void qmp_chardev_open_socket(Chardev *chr, > qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS); > } > > + if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) > { > + return; > + } > + s->registered_yank = true; > + > /* be isn't opened until we get a connection */ > *be_opened = false; > > -- > 2.29.2 > > -- Marc-André Lureau