mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-09-09 00:07:57 -06:00
migration: incoming channel
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> Acked-by: Peter Xu <peterx@redhat.com> Link: https://lore.kernel.org/r/1736967650-129648-13-git-send-email-steven.sistare@oracle.com Signed-off-by: Fabiano Rosas <farosas@suse.de>
This commit is contained in:
parent
f2374f0fc3
commit
2862b6b924
3 changed files with 70 additions and 8 deletions
|
@ -695,7 +695,8 @@ static void qemu_start_incoming_migration(const char *uri, bool has_channels,
|
||||||
if (channels) {
|
if (channels) {
|
||||||
/* To verify that Migrate channel list has only item */
|
/* To verify that Migrate channel list has only item */
|
||||||
if (channels->next) {
|
if (channels->next) {
|
||||||
error_setg(errp, "Channel list has more than one entries");
|
error_setg(errp, "Channel list must have only one entry, "
|
||||||
|
"for type 'main'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addr = channels->value->addr;
|
addr = channels->value->addr;
|
||||||
|
@ -2054,6 +2055,7 @@ void qmp_migrate(const char *uri, bool has_channels,
|
||||||
MigrationState *s = migrate_get_current();
|
MigrationState *s = migrate_get_current();
|
||||||
g_autoptr(MigrationChannel) channel = NULL;
|
g_autoptr(MigrationChannel) channel = NULL;
|
||||||
MigrationAddress *addr = NULL;
|
MigrationAddress *addr = NULL;
|
||||||
|
MigrationChannel *channelv[MIGRATION_CHANNEL_TYPE__MAX] = { NULL };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Having preliminary checks for uri and channel
|
* Having preliminary checks for uri and channel
|
||||||
|
@ -2064,12 +2066,21 @@ void qmp_migrate(const char *uri, bool has_channels,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channels) {
|
if (channels) {
|
||||||
/* To verify that Migrate channel list has only item */
|
for ( ; channels; channels = channels->next) {
|
||||||
if (channels->next) {
|
MigrationChannelType type = channels->value->channel_type;
|
||||||
error_setg(errp, "Channel list has more than one entries");
|
|
||||||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
addr = channels->value->addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uri) {
|
if (uri) {
|
||||||
|
|
|
@ -4940,10 +4940,18 @@ DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \
|
||||||
"-incoming exec:cmdline\n" \
|
"-incoming exec:cmdline\n" \
|
||||||
" accept incoming migration on given file descriptor\n" \
|
" accept incoming migration on given file descriptor\n" \
|
||||||
" or from given external command\n" \
|
" or from given external command\n" \
|
||||||
|
"-incoming <channel>\n" \
|
||||||
|
" accept incoming migration on the migration channel\n" \
|
||||||
"-incoming defer\n" \
|
"-incoming defer\n" \
|
||||||
" wait for the URI to be specified via migrate_incoming\n",
|
" wait for the URI to be specified via migrate_incoming\n",
|
||||||
QEMU_ARCH_ALL)
|
QEMU_ARCH_ALL)
|
||||||
SRST
|
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 <channel>,
|
||||||
|
or is 'main' for all other forms of -incoming. If multiple -incoming
|
||||||
|
options are specified for a channel type, the last one takes precedence.
|
||||||
|
|
||||||
``-incoming tcp:[host]:port[,to=maxport][,ipv4=on|off][,ipv6=on|off]``
|
``-incoming tcp:[host]:port[,to=maxport][,ipv4=on|off][,ipv6=on|off]``
|
||||||
\
|
\
|
||||||
``-incoming rdma:host:port[,ipv4=on|off][,ipv6=on|off]``
|
``-incoming rdma:host:port[,ipv4=on|off][,ipv6=on|off]``
|
||||||
|
@ -4963,6 +4971,19 @@ SRST
|
||||||
Accept incoming migration as an output from specified external
|
Accept incoming migration as an output from specified external
|
||||||
command.
|
command.
|
||||||
|
|
||||||
|
``-incoming <channel>``
|
||||||
|
Accept incoming migration on the migration channel. For the syntax
|
||||||
|
of <channel>, see the QAPI documentation of ``MigrationChannel``.
|
||||||
|
Examples:
|
||||||
|
::
|
||||||
|
|
||||||
|
-incoming '{"channel-type": "main",
|
||||||
|
"addr": { "transport": "socket",
|
||||||
|
"type": "unix",
|
||||||
|
"path": "my.sock" }}'
|
||||||
|
|
||||||
|
-incoming main,addr.transport=socket,addr.type=unix,addr.path=my.sock
|
||||||
|
|
||||||
``-incoming defer``
|
``-incoming defer``
|
||||||
Wait for the URI to be specified via migrate\_incoming. The monitor
|
Wait for the URI to be specified via migrate\_incoming. The monitor
|
||||||
can be used to change settings (such as migration parameters) prior
|
can be used to change settings (such as migration parameters) prior
|
||||||
|
|
36
system/vl.c
36
system/vl.c
|
@ -123,6 +123,7 @@
|
||||||
#include "qapi/qapi-visit-block-core.h"
|
#include "qapi/qapi-visit-block-core.h"
|
||||||
#include "qapi/qapi-visit-compat.h"
|
#include "qapi/qapi-visit-compat.h"
|
||||||
#include "qapi/qapi-visit-machine.h"
|
#include "qapi/qapi-visit-machine.h"
|
||||||
|
#include "qapi/qapi-visit-migration.h"
|
||||||
#include "qapi/qapi-visit-ui.h"
|
#include "qapi/qapi-visit-ui.h"
|
||||||
#include "qapi/qapi-commands-block-core.h"
|
#include "qapi/qapi-commands-block-core.h"
|
||||||
#include "qapi/qapi-commands-migration.h"
|
#include "qapi/qapi-commands-migration.h"
|
||||||
|
@ -159,6 +160,8 @@ typedef struct DeviceOption {
|
||||||
static const char *cpu_option;
|
static const char *cpu_option;
|
||||||
static const char *mem_path;
|
static const char *mem_path;
|
||||||
static const char *incoming;
|
static const char *incoming;
|
||||||
|
static const char *incoming_str[MIGRATION_CHANNEL_TYPE__MAX];
|
||||||
|
static MigrationChannel *incoming_channels[MIGRATION_CHANNEL_TYPE__MAX];
|
||||||
static const char *loadvm;
|
static const char *loadvm;
|
||||||
static const char *accelerators;
|
static const char *accelerators;
|
||||||
static bool have_custom_ram_size;
|
static bool have_custom_ram_size;
|
||||||
|
@ -1813,6 +1816,30 @@ static void object_option_add_visitor(Visitor *v)
|
||||||
QTAILQ_INSERT_TAIL(&object_opts, opt, next);
|
QTAILQ_INSERT_TAIL(&object_opts, opt, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void incoming_option_parse(const char *str)
|
||||||
|
{
|
||||||
|
MigrationChannelType type = MIGRATION_CHANNEL_TYPE_MAIN;
|
||||||
|
MigrationChannel *channel;
|
||||||
|
Visitor *v;
|
||||||
|
|
||||||
|
if (!strcmp(str, "defer")) {
|
||||||
|
channel = NULL;
|
||||||
|
} else if (migrate_is_uri(str)) {
|
||||||
|
migrate_uri_parse(str, &channel, &error_fatal);
|
||||||
|
} else {
|
||||||
|
v = qobject_input_visitor_new_str(str, "channel-type", &error_fatal);
|
||||||
|
visit_type_MigrationChannel(v, NULL, &channel, &error_fatal);
|
||||||
|
visit_free(v);
|
||||||
|
type = channel->channel_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New incoming spec replaces the previous */
|
||||||
|
qapi_free_MigrationChannel(incoming_channels[type]);
|
||||||
|
incoming_channels[type] = channel;
|
||||||
|
incoming_str[type] = str;
|
||||||
|
incoming = incoming_str[MIGRATION_CHANNEL_TYPE_MAIN];
|
||||||
|
}
|
||||||
|
|
||||||
static void object_option_parse(const char *str)
|
static void object_option_parse(const char *str)
|
||||||
{
|
{
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
|
@ -2738,8 +2765,11 @@ void qmp_x_exit_preconfig(Error **errp)
|
||||||
if (incoming) {
|
if (incoming) {
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
if (strcmp(incoming, "defer") != 0) {
|
if (strcmp(incoming, "defer") != 0) {
|
||||||
qmp_migrate_incoming(incoming, false, NULL, true, true,
|
g_autofree MigrationChannelList *channels =
|
||||||
&local_err);
|
g_new0(MigrationChannelList, 1);
|
||||||
|
|
||||||
|
channels->value = incoming_channels[MIGRATION_CHANNEL_TYPE_MAIN];
|
||||||
|
qmp_migrate_incoming(NULL, true, channels, true, true, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_reportf_err(local_err, "-incoming %s: ", incoming);
|
error_reportf_err(local_err, "-incoming %s: ", incoming);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -3458,7 +3488,7 @@ void qemu_init(int argc, char **argv)
|
||||||
if (!incoming) {
|
if (!incoming) {
|
||||||
runstate_set(RUN_STATE_INMIGRATE);
|
runstate_set(RUN_STATE_INMIGRATE);
|
||||||
}
|
}
|
||||||
incoming = optarg;
|
incoming_option_parse(optarg);
|
||||||
break;
|
break;
|
||||||
case QEMU_OPTION_only_migratable:
|
case QEMU_OPTION_only_migratable:
|
||||||
only_migratable = 1;
|
only_migratable = 1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue