diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-07-15 12:22:31 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-07-15 12:22:31 +0100 |
commit | f5dec79ee88034b2da52463145a2056500db9ff2 (patch) | |
tree | aa575a5d07c70c0674498a69e606e5307f121d7f | |
parent | 661725da09f47eb92d356fac10a4cf3b7ad1f61d (diff) | |
parent | 560d027b54067ffa4e79c6f7c0a499abb0d749a3 (diff) |
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20150715-1' into staging
migration/next for 20150715
# gpg: Signature made Wed Jul 15 11:23:33 2015 BST using RSA key ID 5872D723
# gpg: Good signature from "Juan Quintela <quintela@redhat.com>"
# gpg: aka "Juan Quintela <quintela@trasno.org>"
* remotes/juanquintela/tags/migration/20150715-1:
migration: We also want to store the global state for savevm
migration: reduce the count of strlen call
migration: Register global state section before loadvm
migration: Write documetation for events capabilites
migration: Trace event and migration event are different things
migration: Only change state after migration has finished
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | include/migration/migration.h | 1 | ||||
-rw-r--r-- | migration/migration.c | 52 | ||||
-rw-r--r-- | migration/ram.c | 10 | ||||
-rw-r--r-- | migration/savevm.c | 6 | ||||
-rw-r--r-- | qmp-commands.hx | 1 | ||||
-rw-r--r-- | vl.c | 2 |
6 files changed, 43 insertions, 29 deletions
diff --git a/include/migration/migration.h b/include/migration/migration.h index b2711ef305..a2f8ed093c 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -202,4 +202,5 @@ void savevm_skip_section_footers(void); void register_global_state(void); void global_state_set_optional(void); void savevm_skip_configuration(void); +int global_state_store(void); #endif diff --git a/migration/migration.c b/migration/migration.c index 45719a0f5f..86ca099ac4 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -104,11 +104,13 @@ typedef struct { bool optional; uint32_t size; uint8_t runstate[100]; + RunState state; + bool received; } GlobalState; static GlobalState global_state; -static int global_state_store(void) +int global_state_store(void) { if (!runstate_store((char *)global_state.runstate, sizeof(global_state.runstate))) { @@ -119,9 +121,14 @@ static int global_state_store(void) return 0; } -static char *global_state_get_runstate(void) +static bool global_state_received(void) { - return (char *)global_state.runstate; + return global_state.received; +} + +static RunState global_state_get_runstate(void) +{ + return global_state.state; } void global_state_set_optional(void) @@ -154,26 +161,25 @@ static bool global_state_needed(void *opaque) static int global_state_post_load(void *opaque, int version_id) { GlobalState *s = opaque; - int ret = 0; + Error *local_err = NULL; + int r; char *runstate = (char *)s->runstate; + s->received = true; trace_migrate_global_state_post_load(runstate); - if (strcmp(runstate, "running") != 0) { - Error *local_err = NULL; - int r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE_MAX, + r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE_MAX, -1, &local_err); - if (r == -1) { - if (local_err) { - error_report_err(local_err); - } - return -EINVAL; + if (r == -1) { + if (local_err) { + error_report_err(local_err); } - ret = vm_stop_force_state(r); + return -EINVAL; } + s->state = r; - return ret; + return 0; } static void global_state_pre_save(void *opaque) @@ -202,6 +208,7 @@ void register_global_state(void) { /* We would use it independently that we receive it */ strcpy((char *)&global_state.runstate, ""); + global_state.received = false; vmstate_register(NULL, 0, &vmstate_globalstate, &global_state); } @@ -209,7 +216,6 @@ static void migrate_generate_event(int new_state) { if (migrate_use_events()) { qapi_event_send_migration(new_state, &error_abort); - trace_migrate_set_state(new_state); } } @@ -283,20 +289,19 @@ static void process_incoming_migration_co(void *opaque) exit(EXIT_FAILURE); } - /* runstate == "" means that we haven't received it through the - * wire, so we obey autostart. runstate == runing means that we - * need to run it, we need to make sure that we do it after - * everything else has finished. Every other state change is done - * at the post_load function */ + /* If global state section was not received or we are in running + state, we need to obey autostart. Any other state is set with + runstate_set. */ - if (strcmp(global_state_get_runstate(), "running") == 0) { - vm_start(); - } else if (strcmp(global_state_get_runstate(), "") == 0) { + if (!global_state_received() || + global_state_get_runstate() == RUN_STATE_RUNNING) { if (autostart) { vm_start(); } else { runstate_set(RUN_STATE_PAUSED); } + } else { + runstate_set(global_state_get_runstate()); } migrate_decompress_threads_join(); } @@ -522,6 +527,7 @@ void qmp_migrate_set_parameters(bool has_compress_level, static void migrate_set_state(MigrationState *s, int old_state, int new_state) { if (atomic_cmpxchg(&s->state, old_state, new_state) == old_state) { + trace_migrate_set_state(new_state); migrate_generate_event(new_state); } } diff --git a/migration/ram.c b/migration/ram.c index 1e58cd3924..7f007e6432 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -382,16 +382,16 @@ void migrate_compress_threads_create(void) */ static size_t save_page_header(QEMUFile *f, RAMBlock *block, ram_addr_t offset) { - size_t size; + size_t size, len; qemu_put_be64(f, offset); size = 8; if (!(offset & RAM_SAVE_FLAG_CONTINUE)) { - qemu_put_byte(f, strlen(block->idstr)); - qemu_put_buffer(f, (uint8_t *)block->idstr, - strlen(block->idstr)); - size += 1 + strlen(block->idstr); + len = strlen(block->idstr); + qemu_put_byte(f, len); + qemu_put_buffer(f, (uint8_t *)block->idstr, len); + size += 1 + len; } return size; } diff --git a/migration/savevm.c b/migration/savevm.c index 86735fc53a..81dbe5879f 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1315,6 +1315,12 @@ void hmp_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running = runstate_is_running(); + + ret = global_state_store(); + if (ret) { + monitor_printf(mon, "Error saving global state\n"); + return; + } vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); diff --git a/qmp-commands.hx b/qmp-commands.hx index e1bcc60380..ba630b1e7f 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3406,6 +3406,7 @@ Enable/Disable migration capabilities - "rdma-pin-all": pin all pages when using RDMA during migration - "auto-converge": throttle down guest to help convergence of migration - "zero-blocks": compress zero blocks during block migration +- "events": generate events for each migration state change Arguments: @@ -4615,6 +4615,7 @@ int main(int argc, char **argv, char **envp) } qemu_system_reset(VMRESET_SILENT); + register_global_state(); if (loadvm) { if (load_vmstate(loadvm) < 0) { autostart = 0; @@ -4628,7 +4629,6 @@ int main(int argc, char **argv, char **envp) return 0; } - register_global_state(); if (incoming) { Error *local_err = NULL; qemu_start_incoming_migration(incoming, &local_err); |