aboutsummaryrefslogtreecommitdiff
path: root/migration/migration.c
diff options
context:
space:
mode:
Diffstat (limited to 'migration/migration.c')
-rw-r--r--migration/migration.c137
1 files changed, 50 insertions, 87 deletions
diff --git a/migration/migration.c b/migration/migration.c
index b5af6b5105..e1b269624c 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -27,7 +27,6 @@
#include "sysemu/cpu-throttle.h"
#include "rdma.h"
#include "ram.h"
-#include "ram-compress.h"
#include "migration/global_state.h"
#include "migration/misc.h"
#include "migration.h"
@@ -46,7 +45,6 @@
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qnull.h"
#include "qemu/rcu.h"
-#include "block.h"
#include "postcopy-ram.h"
#include "qemu/thread.h"
#include "trace.h"
@@ -72,6 +70,8 @@
#define NOTIFIER_ELEM_INIT(array, elem) \
[elem] = NOTIFIER_WITH_RETURN_LIST_INITIALIZER((array)[elem])
+#define INMIGRATE_DEFAULT_EXIT_ON_ERROR true
+
static NotifierWithReturnList migration_state_notifiers[] = {
NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_NORMAL),
NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_CPR_REBOOT),
@@ -234,9 +234,10 @@ void migration_object_init(void)
qemu_cond_init(&current_incoming->page_request_cond);
current_incoming->page_requested = g_tree_new(page_request_addr_cmp);
+ current_incoming->exit_on_error = INMIGRATE_DEFAULT_EXIT_ON_ERROR;
+
migration_object_check(current_migration, &error_fatal);
- blk_mig_init();
ram_mig_init();
dirty_bitmap_mig_init();
}
@@ -354,7 +355,6 @@ void migration_incoming_state_destroy(void)
struct MigrationIncomingState *mis = migration_incoming_get_current();
multifd_recv_cleanup();
- compress_threads_load_cleanup();
if (mis->to_src_file) {
/* Tell source that we are done */
@@ -513,13 +513,13 @@ void migration_incoming_disable_colo(void)
int migration_incoming_enable_colo(void)
{
#ifndef CONFIG_REPLICATION
- error_report("ENABLE_COLO command come in migration stream, but COLO "
- "module is not built in");
+ error_report("ENABLE_COLO command come in migration stream, but the "
+ "replication module is not built in");
return -ENOTSUP;
#endif
if (!migrate_colo()) {
- error_report("ENABLE_COLO command come in migration stream, but c-colo "
+ error_report("ENABLE_COLO command come in migration stream, but x-colo "
"capability is not set");
return -EINVAL;
}
@@ -647,10 +647,6 @@ static void qemu_start_incoming_migration(const char *uri, bool has_channels,
}
#ifdef CONFIG_RDMA
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
- if (migrate_compress()) {
- error_setg(errp, "RDMA and compression can't be used together");
- return;
- }
if (migrate_xbzrle()) {
error_setg(errp, "RDMA and XBZRLE can't be used together");
return;
@@ -735,17 +731,14 @@ static void process_incoming_migration_bh(void *opaque)
static void coroutine_fn
process_incoming_migration_co(void *opaque)
{
+ MigrationState *s = migrate_get_current();
MigrationIncomingState *mis = migration_incoming_get_current();
PostcopyState ps;
int ret;
+ Error *local_err = NULL;
assert(mis->from_src_file);
- if (compress_threads_load_setup(mis->from_src_file)) {
- error_report("Failed to setup decompress threads");
- goto fail;
- }
-
mis->largest_page_size = qemu_ram_pagesize_largest();
postcopy_state_set(POSTCOPY_INCOMING_NONE);
migrate_set_state(&mis->state, MIGRATION_STATUS_SETUP,
@@ -779,19 +772,13 @@ process_incoming_migration_co(void *opaque)
}
if (ret < 0) {
- MigrationState *s = migrate_get_current();
-
- if (migrate_has_error(s)) {
- WITH_QEMU_LOCK_GUARD(&s->error_mutex) {
- error_report_err(s->error);
- }
- }
- error_report("load of migration failed: %s", strerror(-ret));
+ error_setg(&local_err, "load of migration failed: %s", strerror(-ret));
goto fail;
}
- if (colo_incoming_co() < 0) {
- goto fail;
+ if (migration_incoming_colo_enabled()) {
+ /* yield until COLO exit */
+ colo_incoming_co();
}
migration_bh_schedule(process_incoming_migration_bh, mis);
@@ -799,12 +786,19 @@ process_incoming_migration_co(void *opaque)
fail:
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
MIGRATION_STATUS_FAILED);
- qemu_fclose(mis->from_src_file);
+ migrate_set_error(s, local_err);
+ error_free(local_err);
- multifd_recv_cleanup();
- compress_threads_load_cleanup();
+ migration_incoming_state_destroy();
+
+ if (mis->exit_on_error) {
+ WITH_QEMU_LOCK_GUARD(&s->error_mutex) {
+ error_report_err(s->error);
+ s->error = NULL;
+ }
- exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
+ }
}
/**
@@ -1149,8 +1143,6 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s)
info->ram->transferred = migration_transferred_bytes();
info->ram->total = ram_bytes_total();
info->ram->duplicate = stat64_get(&mig_stats.zero_pages);
- /* legacy value. It is not used anymore */
- info->ram->skipped = 0;
info->ram->normal = stat64_get(&mig_stats.normal_pages);
info->ram->normal_bytes = info->ram->normal * page_size;
info->ram->mbps = s->mbps;
@@ -1178,8 +1170,6 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s)
info->xbzrle_cache->overflow = xbzrle_counters.overflow;
}
- populate_compress(info);
-
if (cpu_throttle_active()) {
info->has_cpu_throttle_percentage = true;
info->cpu_throttle_percentage = cpu_throttle_get_percentage();
@@ -1201,16 +1191,6 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s)
}
}
-static void populate_disk_info(MigrationInfo *info)
-{
- if (blk_mig_active()) {
- info->disk = g_malloc0(sizeof(*info->disk));
- info->disk->transferred = blk_mig_bytes_transferred();
- info->disk->remaining = blk_mig_bytes_remaining();
- info->disk->total = blk_mig_bytes_total();
- }
-}
-
static void fill_source_migration_info(MigrationInfo *info)
{
MigrationState *s = migrate_get_current();
@@ -1253,7 +1233,6 @@ static void fill_source_migration_info(MigrationInfo *info)
/* TODO add some postcopy stats */
populate_time_info(info, s);
populate_ram_info(info, s);
- populate_disk_info(info);
migration_populate_vfio_info(info);
break;
case MIGRATION_STATUS_COLO:
@@ -1313,6 +1292,15 @@ static void fill_destination_migration_info(MigrationInfo *info)
break;
}
info->status = mis->state;
+
+ if (!info->error_desc) {
+ MigrationState *s = migrate_get_current();
+ QEMU_LOCK_GUARD(&s->error_mutex);
+
+ if (s->error) {
+ info->error_desc = g_strdup(error_get_pretty(s->error));
+ }
+ }
}
MigrationInfo *qmp_query_migrate(Error **errp)
@@ -1409,7 +1397,6 @@ static void migrate_fd_cleanup(MigrationState *s)
type = migration_has_failed(s) ? MIG_EVENT_PRECOPY_FAILED :
MIG_EVENT_PRECOPY_DONE;
migration_call_notifiers(s, type, NULL);
- block_cleanup_parameters();
yank_unregister_instance(MIGRATION_YANK_INSTANCE);
}
@@ -1421,6 +1408,9 @@ static void migrate_fd_cleanup_bh(void *opaque)
void migrate_set_error(MigrationState *s, const Error *error)
{
QEMU_LOCK_GUARD(&s->error_mutex);
+
+ trace_migrate_error(error_get_pretty(error));
+
if (!s->error) {
s->error = error_copy(error);
}
@@ -1444,7 +1434,6 @@ static void migrate_error_free(MigrationState *s)
static void migrate_fd_error(MigrationState *s, const Error *error)
{
- trace_migrate_fd_error(error_get_pretty(error));
assert(s->to_dst_file == NULL);
migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
MIGRATION_STATUS_FAILED);
@@ -1794,10 +1783,13 @@ void migrate_del_blocker(Error **reasonp)
}
void qmp_migrate_incoming(const char *uri, bool has_channels,
- MigrationChannelList *channels, Error **errp)
+ MigrationChannelList *channels,
+ bool has_exit_on_error, bool exit_on_error,
+ Error **errp)
{
Error *local_err = NULL;
static bool once = true;
+ MigrationIncomingState *mis = migration_incoming_get_current();
if (!once) {
error_setg(errp, "The incoming migration has already been started");
@@ -1812,6 +1804,9 @@ void qmp_migrate_incoming(const char *uri, bool has_channels,
return;
}
+ mis->exit_on_error =
+ has_exit_on_error ? exit_on_error : INMIGRATE_DEFAULT_EXIT_ON_ERROR;
+
qemu_start_incoming_migration(uri, has_channels, channels, &local_err);
if (local_err) {
@@ -1913,19 +1908,8 @@ bool migration_is_blocked(Error **errp)
}
/* Returns true if continue to migrate, or false if error detected */
-static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
- bool resume, Error **errp)
+static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
{
- if (blk_inc) {
- warn_report("parameter 'inc' is deprecated;"
- " use blockdev-mirror with NBD instead");
- }
-
- if (blk) {
- warn_report("parameter 'blk' is deprecated;"
- " use blockdev-mirror with NBD instead");
- }
-
if (resume) {
if (s->state != MIGRATION_STATUS_POSTCOPY_PAUSED) {
error_setg(errp, "Cannot resume if there is no "
@@ -2010,26 +1994,6 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
}
}
- if (blk || blk_inc) {
- if (migrate_colo()) {
- error_setg(errp, "No disk migration is required in COLO mode");
- return false;
- }
- if (migrate_block() || migrate_block_incremental()) {
- error_setg(errp, "Command options are incompatible with "
- "current migration capabilities");
- return false;
- }
- if (!migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, true, errp)) {
- return false;
- }
- s->must_remove_block_options = true;
- }
-
- if (blk_inc) {
- migrate_set_block_incremental(true);
- }
-
if (migrate_init(s, errp)) {
return false;
}
@@ -2038,8 +2002,7 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
}
void qmp_migrate(const char *uri, bool has_channels,
- MigrationChannelList *channels, bool has_blk, bool blk,
- bool has_inc, bool inc, bool has_detach, bool detach,
+ MigrationChannelList *channels, bool has_detach, bool detach,
bool has_resume, bool resume, Error **errp)
{
bool resume_requested;
@@ -2079,8 +2042,7 @@ void qmp_migrate(const char *uri, bool has_channels,
}
resume_requested = has_resume && resume;
- if (!migrate_prepare(s, has_blk && blk, has_inc && inc,
- resume_requested, errp)) {
+ if (!migrate_prepare(s, resume_requested, errp)) {
/* Error detected, put into errp */
return;
}
@@ -2113,7 +2075,6 @@ void qmp_migrate(const char *uri, bool has_channels,
"a valid migration protocol");
migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
MIGRATION_STATUS_FAILED);
- block_cleanup_parameters();
}
if (local_err) {
@@ -3033,13 +2994,15 @@ static MigThrError postcopy_pause(MigrationState *s)
}
}
-void migration_file_set_error(int err)
+void migration_file_set_error(int ret, Error *err)
{
MigrationState *s = current_migration;
WITH_QEMU_LOCK_GUARD(&s->qemu_file_lock) {
if (s->to_dst_file) {
- qemu_file_set_error(s->to_dst_file, err);
+ qemu_file_set_error_obj(s->to_dst_file, ret, err);
+ } else if (err) {
+ error_report_err(err);
}
}
}