@@ -106,4 +106,6 @@ bool migration_incoming_postcopy_advised(void);
/* True if background snapshot is active */
bool migration_in_bg_snapshot(void);
+bool migrate_uri_parse(const char *uri, MigrationChannel **channel,
+ Error **errp);
#endif
@@ -2046,6 +2046,7 @@ void qmp_migrate(const char *uri, bool has_channels,
MigrationState *s = migrate_get_current();
g_autoptr(MigrationChannel) channel = NULL;
MigrationAddress *addr = NULL;
+ MigrationChannel *channelv[MIGRATION_CHANNEL_TYPE__MAX] = { NULL };
/*
* Having preliminary checks for uri and channel
@@ -2056,12 +2057,21 @@ void qmp_migrate(const char *uri, bool has_channels,
}
if (channels) {
- /* To verify that Migrate channel list has only item */
- if (channels->next) {
- error_setg(errp, "Channel list has more than one entries");
+ for ( ; channels; channels = channels->next) {
+ MigrationChannelType type = channels->value->channel_type;
+
+ if (channelv[type]) {
+ error_setg(errp, "Channel list has more than one %s entry",
+ MigrationChannelType_str(type));
+ return;
+ }
+ channelv[type] = channels->value;
+ }
+ addr = channelv[MIGRATION_CHANNEL_TYPE_MAIN]->addr;
+ if (!addr) {
+ error_setg(errp, "Channel list has no main entry");
return;
}
- addr = channels->value->addr;
}
if (uri) {
@@ -522,8 +522,6 @@ bool check_dirty_bitmap_mig_alias_map(const BitmapMigrationNodeAliasList *bbm,
Error **errp);
void migrate_add_address(SocketAddress *address);
-bool migrate_uri_parse(const char *uri, MigrationChannel **channel,
- Error **errp);
int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque);
#define qemu_ram_foreach_block \
@@ -4937,10 +4937,17 @@ DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \
"-incoming exec:cmdline\n" \
" accept incoming migration on given file descriptor\n" \
" or from given external command\n" \
+ "-incoming @MigrationChannel\n" \
+ " accept incoming migration on the channel\n" \
"-incoming defer\n" \
" wait for the URI to be specified via migrate_incoming\n",
QEMU_ARCH_ALL)
SRST
+The -incoming option specifies the migration channel for an incoming
+migration. It may be used multiple times to specify multiple
+migration channel types. The channel type is specified in @MigrationChannel,
+and is 'main' for all other forms of -incoming.
+
``-incoming tcp:[host]:port[,to=maxport][,ipv4=on|off][,ipv6=on|off]``
\
``-incoming rdma:host:port[,ipv4=on|off][,ipv6=on|off]``
@@ -4960,6 +4967,16 @@ SRST
Accept incoming migration as an output from specified external
command.
+``-incoming @MigrationChannel``
+ Accept incoming migration on the channel. See the QAPI documentation
+ for the syntax of the @MigrationChannel data element. For example:
+ ::
+
+ -incoming '{"channel-type": "main",
+ "addr": { "transport": "socket",
+ "type": "unix",
+ "path": "my.sock" }}'
+
``-incoming defer``
Wait for the URI to be specified via migrate\_incoming. The monitor
can be used to change settings (such as migration parameters) prior
@@ -123,6 +123,7 @@
#include "qapi/qapi-visit-block-core.h"
#include "qapi/qapi-visit-compat.h"
#include "qapi/qapi-visit-machine.h"
+#include "qapi/qapi-visit-migration.h"
#include "qapi/qapi-visit-ui.h"
#include "qapi/qapi-commands-block-core.h"
#include "qapi/qapi-commands-migration.h"
@@ -159,6 +160,7 @@ typedef struct DeviceOption {
static const char *cpu_option;
static const char *mem_path;
static const char *incoming;
+static MigrationChannelList *incoming_channels;
static const char *loadvm;
static const char *accelerators;
static bool have_custom_ram_size;
@@ -1821,6 +1823,35 @@ static void object_option_add_visitor(Visitor *v)
QTAILQ_INSERT_TAIL(&object_opts, opt, next);
}
+static void incoming_option_parse(const char *str)
+{
+ MigrationChannel *channel;
+
+ if (str[0] == '{') {
+ QObject *obj = qobject_from_json(str, &error_fatal);
+ Visitor *v = qobject_input_visitor_new(obj);
+
+ qobject_unref(obj);
+ visit_type_MigrationChannel(v, "channel", &channel, &error_fatal);
+ visit_free(v);
+ } else if (!strcmp(str, "defer")) {
+ channel = NULL;
+ } else {
+ migrate_uri_parse(str, &channel, &error_fatal);
+ }
+
+ /* New incoming spec replaces the previous */
+
+ if (incoming_channels) {
+ qapi_free_MigrationChannelList(incoming_channels);
+ }
+ if (channel) {
+ incoming_channels = g_new0(MigrationChannelList, 1);
+ incoming_channels->value = channel;
+ }
+ incoming = str;
+}
+
static void object_option_parse(const char *str)
{
QemuOpts *opts;
@@ -2730,7 +2761,7 @@ void qmp_x_exit_preconfig(Error **errp)
if (incoming) {
Error *local_err = NULL;
if (strcmp(incoming, "defer") != 0) {
- qmp_migrate_incoming(incoming, false, NULL, true, true,
+ qmp_migrate_incoming(NULL, true, incoming_channels, true, true,
&local_err);
if (local_err) {
error_reportf_err(local_err, "-incoming %s: ", incoming);
@@ -3477,7 +3508,7 @@ void qemu_init(int argc, char **argv)
if (!incoming) {
runstate_set(RUN_STATE_INMIGRATE);
}
- incoming = optarg;
+ incoming_option_parse(optarg);
break;
case QEMU_OPTION_only_migratable:
only_migratable = 1;
Extend the -incoming option to allow an @MigrationChannel to be specified. This allows channels other than 'main' to be described on the command line, which will be needed for CPR. Signed-off-by: Steve Sistare <steven.sistare@oracle.com> --- include/migration/misc.h | 2 ++ migration/migration.c | 18 ++++++++++++++---- migration/migration.h | 2 -- qemu-options.hx | 17 +++++++++++++++++ system/vl.c | 35 +++++++++++++++++++++++++++++++++-- 5 files changed, 66 insertions(+), 8 deletions(-)