@@ -166,6 +166,26 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
qapi_free_MouseInfoList(mice_list);
}
+static char *SocketAddress_to_str(SocketAddress *addr)
+{
+ switch (addr->type) {
+ case SOCKET_ADDRESS_TYPE_INET:
+ return g_strdup_printf("tcp:%s:%s",
+ addr->u.inet.host,
+ addr->u.inet.port);
+ break;
+ case SOCKET_ADDRESS_TYPE_UNIX:
+ return g_strdup_printf("unix:%s",
+ addr->u.q_unix.path);
+ break;
+ case SOCKET_ADDRESS_TYPE_FD:
+ return g_strdup_printf("fd:%s", addr->u.fd.str);
+ break;
+ default:
+ abort();
+ }
+}
+
void hmp_info_migrate(Monitor *mon, const QDict *qdict)
{
MigrationInfo *info;
@@ -304,6 +324,17 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
g_free(str);
visit_free(v);
}
+ if (info->has_socket_address) {
+ SocketAddressList *addr;
+
+ monitor_printf(mon, "socket address: [\n");
+
+ for (addr = info->socket_address; addr; addr = addr->next) {
+ char *s = SocketAddress_to_str(addr->value);
+ monitor_printf(mon, "\t%s\n", s);
+ }
+ monitor_printf(mon, "]\n");
+ }
qapi_free_MigrationInfo(info);
qapi_free_MigrationCapabilityStatusList(caps);
}
@@ -31,6 +31,8 @@
#include "migration/vmstate.h"
#include "block/block.h"
#include "qapi/error.h"
+#include "qapi/clone-visitor.h"
+#include "qapi/qapi-visit-sockets.h"
#include "qapi/qapi-commands-migration.h"
#include "qapi/qapi-events-migration.h"
#include "qapi/qmp/qerror.h"
@@ -197,6 +199,11 @@ void migration_incoming_state_destroy(void)
}
qemu_event_reset(&mis->main_thread_load_event);
+
+ if (mis->socket_address) {
+ qapi_free_SocketAddressList(mis->socket_address);
+ mis->socket_address = NULL;
+ }
}
static void migrate_generate_event(int new_state)
@@ -312,6 +319,17 @@ void migration_incoming_enable_colo(void)
migration_colo_enabled = true;
}
+void migrate_add_address(SocketAddress *address)
+{
+ MigrationIncomingState *mis = migration_incoming_get_current();
+ SocketAddressList *addrs;
+
+ addrs = g_new0(SocketAddressList, 1);
+ addrs->next = mis->socket_address;
+ mis->socket_address = addrs;
+ addrs->value = QAPI_CLONE(SocketAddress, address);
+}
+
void qemu_start_incoming_migration(const char *uri, Error **errp)
{
const char *p;
@@ -960,6 +978,12 @@ static void fill_destination_migration_info(MigrationInfo *info)
{
MigrationIncomingState *mis = migration_incoming_get_current();
+ if (mis->socket_address) {
+ info->has_socket_address = true;
+ info->socket_address =
+ QAPI_CLONE(SocketAddressList, mis->socket_address);
+ }
+
switch (mis->state) {
case MIGRATION_STATUS_NONE:
return;
@@ -80,6 +80,9 @@ struct MigrationIncomingState {
bool postcopy_recover_triggered;
QemuSemaphore postcopy_pause_sem_dst;
QemuSemaphore postcopy_pause_sem_fault;
+
+ /* List of listening socket addresses */
+ SocketAddressList *socket_address;
};
MigrationIncomingState *migration_incoming_get_current(void);
@@ -292,6 +295,7 @@ void migrate_send_rp_resume_ack(MigrationIncomingState *mis, uint32_t value);
void dirty_bitmap_mig_before_vm_start(void);
void init_dirty_bitmap_incoming_migration(void);
+void migrate_add_address(SocketAddress *address);
#define qemu_ram_foreach_block \
#warning "Use qemu_ram_foreach_block_migratable in migration code"
@@ -15,6 +15,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/cutils.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
@@ -177,6 +178,7 @@ static void socket_start_incoming_migration(SocketAddress *saddr,
Error **errp)
{
QIONetListener *listener = qio_net_listener_new();
+ size_t i;
qio_net_listener_set_name(listener, "migration-socket-listener");
@@ -189,6 +191,15 @@ static void socket_start_incoming_migration(SocketAddress *saddr,
socket_accept_incoming_migration,
NULL, NULL,
g_main_context_get_thread_default());
+
+ for (i = 0; i < listener->nsioc; i++) {
+ SocketAddress *address =
+ qio_channel_socket_get_local_address(listener->sioc[i], errp);
+ if (!address) {
+ return;
+ }
+ migrate_add_address(address);
+ }
}
void tcp_start_incoming_migration(const char *host_port, Error **errp)
@@ -6,6 +6,7 @@
##
{ 'include': 'common.json' }
+{ 'include': 'sockets.json' }
##
# @MigrationStats:
@@ -196,6 +197,8 @@
# @compression: migration compression statistics, only returned if compression
# feature is on and status is 'active' or 'completed' (Since 3.1)
#
+# @socket-address: Only used for tcp, to know what the real port is (Since 3.1)
+#
# Since: 0.14.0
##
{ 'struct': 'MigrationInfo',
@@ -210,7 +213,8 @@
'*error-desc': 'str',
'*postcopy-blocktime' : 'uint32',
'*postcopy-vcpu-blocktime': ['uint32'],
- '*compression': 'CompressionStats'} }
+ '*compression': 'CompressionStats',
+ '*socket-address': ['SocketAddress'] } }
##
# @query-migrate:
@@ -152,3 +152,16 @@
'unix': 'UnixSocketAddress',
'vsock': 'VsockSocketAddress',
'fd': 'String' } }
+
+##
+# @DummyStruct:
+#
+# Both block-core and migration needs SocketAddressList
+# I am open to comments about how to share it
+#
+# @dummy-list: A dummy list
+#
+# Since: 3.1
+##
+{ 'struct': 'DummyStruct',
+ 'data': { 'dummy-list': ['SocketAddress'] } }