[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 23/46] MIG_STATE_POSTCOPY_ACTIVE: Add new migration
From: |
Dr. David Alan Gilbert (git) |
Subject: |
[Qemu-devel] [PATCH 23/46] MIG_STATE_POSTCOPY_ACTIVE: Add new migration state |
Date: |
Fri, 4 Jul 2014 18:41:34 +0100 |
From: "Dr. David Alan Gilbert" <address@hidden>
'MIG_STATE_POSTCOPY_ACTIVE' is entered after the precopy timelimit
has expired and migration switches to postcopy.
'migration_postcopy_phase' is provided for other sections to know if
they're in postcopy.
Signed-off-by: Dr. David Alan Gilbert <address@hidden>
---
include/migration/migration.h | 2 ++
migration.c | 76 +++++++++++++++++++++++++++++++++++++++----
2 files changed, 71 insertions(+), 7 deletions(-)
diff --git a/include/migration/migration.h b/include/migration/migration.h
index d2754f7..71442d8 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -146,6 +146,8 @@ MigrationState *migrate_init(const MigrationParams *params);
bool migration_in_setup(MigrationState *);
bool migration_has_finished(MigrationState *);
bool migration_has_failed(MigrationState *);
+/* True if outgoing migration has entered postcopy phase */
+bool migration_postcopy_phase(MigrationState *);
MigrationState *migrate_get_current(void);
uint64_t ram_bytes_remaining(void);
diff --git a/migration.c b/migration.c
index 20ed6fa..d9a9e5b 100644
--- a/migration.c
+++ b/migration.c
@@ -38,13 +38,14 @@
do { } while (0)
#endif
-enum {
+enum MigrationPhase {
MIG_STATE_ERROR = -1,
MIG_STATE_NONE,
MIG_STATE_SETUP,
MIG_STATE_CANCELLING,
MIG_STATE_CANCELLED,
MIG_STATE_ACTIVE,
+ MIG_STATE_POSTCOPY_ACTIVE,
MIG_STATE_COMPLETED,
};
@@ -226,13 +227,30 @@ MigrationCapabilityStatusList
*qmp_query_migrate_capabilities(Error **errp)
return head;
}
+/* Return true if we're already in the middle of a migration
+ * (i.e. any of the active or setup states)
+ */
+static bool migration_already_active(MigrationState *ms)
+{
+ switch (ms->state) {
+ case MIG_STATE_ACTIVE:
+ case MIG_STATE_POSTCOPY_ACTIVE:
+ case MIG_STATE_SETUP:
+ return true;
+
+ default:
+ return false;
+
+ }
+}
+
void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
Error **errp)
{
MigrationState *s = migrate_get_current();
MigrationCapabilityStatusList *cap;
- if (s->state == MIG_STATE_ACTIVE || s->state == MIG_STATE_SETUP) {
+ if (migration_already_active(s)) {
error_set(errp, QERR_MIGRATION_ACTIVE);
return;
}
@@ -248,7 +266,7 @@ void qmp_migrate_set_parameters(MigrationParameterList
*params,
MigrationState *s = migrate_get_current();
MigrationParameterList *parm;
- if (s->state == MIG_STATE_ACTIVE || s->state == MIG_STATE_SETUP) {
+ if (migration_already_active(s)) {
error_set(errp, QERR_MIGRATION_ACTIVE);
return;
}
@@ -347,6 +365,40 @@ MigrationInfo *qmp_query_migrate(Error **errp)
get_xbzrle_cache_stats(info);
break;
+ case MIG_STATE_POSTCOPY_ACTIVE:
+ /* Mostly the same as active; TODO add some postcopy stats */
+ info->has_status = true;
+ info->status = g_strdup("postcopy-active");
+ info->has_total_time = true;
+ info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
+ - s->total_time;
+ info->has_expected_downtime = true;
+ info->expected_downtime = s->expected_downtime;
+ info->has_setup_time = true;
+ info->setup_time = s->setup_time;
+
+ info->has_ram = true;
+ info->ram = g_malloc0(sizeof(*info->ram));
+ info->ram->transferred = ram_bytes_transferred();
+ info->ram->remaining = ram_bytes_remaining();
+ info->ram->total = ram_bytes_total();
+ info->ram->duplicate = dup_mig_pages_transferred();
+ info->ram->skipped = skipped_mig_pages_transferred();
+ info->ram->normal = norm_mig_pages_transferred();
+ info->ram->normal_bytes = norm_mig_bytes_transferred();
+ info->ram->dirty_pages_rate = s->dirty_pages_rate;
+ info->ram->mbps = s->mbps;
+
+ if (blk_mig_active()) {
+ info->has_disk = true;
+ 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();
+ }
+
+ get_xbzrle_cache_stats(info);
+ break;
case MIG_STATE_COMPLETED:
get_xbzrle_cache_stats(info);
@@ -423,7 +475,8 @@ static void migrate_fd_cleanup(void *opaque)
s->file = NULL;
}
- assert(s->state != MIG_STATE_ACTIVE);
+ assert((s->state != MIG_STATE_ACTIVE) &&
+ (s->state != MIG_STATE_POSTCOPY_ACTIVE));
if (s->state != MIG_STATE_COMPLETED) {
qemu_savevm_state_cancel();
@@ -451,7 +504,8 @@ static void migrate_fd_cancel(MigrationState *s)
do {
old_state = s->state;
- if (old_state != MIG_STATE_SETUP && old_state != MIG_STATE_ACTIVE) {
+ if (old_state != MIG_STATE_SETUP && old_state != MIG_STATE_ACTIVE &&
+ old_state != MIG_STATE_POSTCOPY_ACTIVE) {
break;
}
migrate_set_state(s, old_state, MIG_STATE_CANCELLING);
@@ -484,6 +538,11 @@ bool migration_has_failed(MigrationState *s)
s->state == MIG_STATE_ERROR);
}
+bool migration_postcopy_phase(MigrationState *s)
+{
+ return (s->state == MIG_STATE_POSTCOPY_ACTIVE);
+}
+
MigrationState *migrate_init(const MigrationParams *params)
{
MigrationState *s = migrate_get_current();
@@ -536,7 +595,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
params.blk = has_blk && blk;
params.shared = has_inc && inc;
- if (s->state == MIG_STATE_ACTIVE || s->state == MIG_STATE_SETUP ||
+ if (migration_already_active(s) ||
s->state == MIG_STATE_CANCELLING) {
error_set(errp, QERR_MIGRATION_ACTIVE);
return;
@@ -847,7 +906,10 @@ static void *migration_thread(void *opaque)
s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
migrate_set_state(s, MIG_STATE_SETUP, MIG_STATE_ACTIVE);
- while (s->state == MIG_STATE_ACTIVE) {
+ DPRINTF("setup complete\n");
+
+ while (s->state == MIG_STATE_ACTIVE ||
+ s->state == MIG_STATE_POSTCOPY_ACTIVE) {
int64_t current_time;
uint64_t pending_size;
--
1.9.3
- [Qemu-devel] [PATCH 06/46] Create MigrationIncomingState, (continued)
- [Qemu-devel] [PATCH 06/46] Create MigrationIncomingState, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 05/46] Add qemu_get_counted_string to read a string prefixed by a count byte, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 07/46] Return path: Open a return path on QEMUFile for sockets, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 09/46] Migration commands, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 08/46] Return path: socket_writev_buffer: Block even on non-blocking fd's, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 10/46] Return path: Control commands, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 12/46] Return path: Source handling of return path, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 11/46] Return path: Send responses from destination to source, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 23/46] MIG_STATE_POSTCOPY_ACTIVE: Add new migration state,
Dr. David Alan Gilbert (git) <=
- [Qemu-devel] [PATCH 24/46] qemu_savevm_state_complete: Postcopy changes, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 25/46] Postcopy: Maintain sentmap during postcopy pre phase, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 26/46] Postcopy page-map-incoming (PMI) structure, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 27/46] postcopy: Add incoming_init/cleanup functions, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 29/46] postcopy: ram_enable_notify to switch on userfault, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 28/46] postcopy: Incoming initialisation, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 30/46] Postcopy: postcopy_start, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 32/46] mig fd_connect: open return path, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 31/46] Postcopy: Rework migration thread for postcopy mode, Dr. David Alan Gilbert (git), 2014/07/04