qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

migration: convert socket server to QIONetListener

Instead of creating a QIOChannelSocket directly for the migration
server socket, use a QIONetListener. This provides the ability
to listen on multiple sockets at the same time, so enables
full support for IPv4/IPv6 dual stack.

For example, '$QEMU -incoming tcp::9000' now correctly listens
on both 0.0.0.0 and :: at the same time, instead of only on 0.0.0.0.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <20180312141714.7223-1-berrange@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

authored by

Daniel P. Berrange and committed by
Dr. David Alan Gilbert
bdd847a0 4c2c1015

+16 -32
+16 -32
migration/socket.c
··· 24 24 #include "migration.h" 25 25 #include "qemu-file.h" 26 26 #include "io/channel-socket.h" 27 + #include "io/net-listener.h" 27 28 #include "trace.h" 28 29 29 30 ··· 129 130 } 130 131 131 132 132 - static gboolean socket_accept_incoming_migration(QIOChannel *ioc, 133 - GIOCondition condition, 134 - gpointer opaque) 133 + static void socket_accept_incoming_migration(QIONetListener *listener, 134 + QIOChannelSocket *cioc, 135 + gpointer opaque) 135 136 { 136 - QIOChannelSocket *sioc; 137 - Error *err = NULL; 138 - 139 - sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), 140 - &err); 141 - if (!sioc) { 142 - error_report("could not accept migration connection (%s)", 143 - error_get_pretty(err)); 144 - goto out; 145 - } 146 - 147 137 trace_migration_socket_incoming_accepted(); 148 138 149 - qio_channel_set_name(QIO_CHANNEL(sioc), "migration-socket-incoming"); 150 - migration_channel_process_incoming(QIO_CHANNEL(sioc)); 151 - object_unref(OBJECT(sioc)); 139 + qio_channel_set_name(QIO_CHANNEL(cioc), "migration-socket-incoming"); 140 + migration_channel_process_incoming(QIO_CHANNEL(cioc)); 152 141 153 - out: 154 142 if (migration_has_all_channels()) { 155 143 /* Close listening socket as its no longer needed */ 156 - qio_channel_close(ioc, NULL); 157 - return G_SOURCE_REMOVE; 158 - } else { 159 - return G_SOURCE_CONTINUE; 144 + qio_net_listener_disconnect(listener); 145 + 146 + object_unref(OBJECT(listener)); 160 147 } 161 148 } 162 149 ··· 164 151 static void socket_start_incoming_migration(SocketAddress *saddr, 165 152 Error **errp) 166 153 { 167 - QIOChannelSocket *listen_ioc = qio_channel_socket_new(); 154 + QIONetListener *listener = qio_net_listener_new(); 168 155 169 - qio_channel_set_name(QIO_CHANNEL(listen_ioc), 170 - "migration-socket-listener"); 156 + qio_net_listener_set_name(listener, "migration-socket-listener"); 171 157 172 - if (qio_channel_socket_listen_sync(listen_ioc, saddr, errp) < 0) { 173 - object_unref(OBJECT(listen_ioc)); 158 + if (qio_net_listener_open_sync(listener, saddr, errp) < 0) { 159 + object_unref(OBJECT(listener)); 174 160 return; 175 161 } 176 162 177 - qio_channel_add_watch(QIO_CHANNEL(listen_ioc), 178 - G_IO_IN, 179 - socket_accept_incoming_migration, 180 - listen_ioc, 181 - (GDestroyNotify)object_unref); 163 + qio_net_listener_set_client_func(listener, 164 + socket_accept_incoming_migration, 165 + NULL, NULL); 182 166 } 183 167 184 168 void tcp_start_incoming_migration(const char *host_port, Error **errp)