提交 172c4356 编写于 作者: J Juan Quintela

migration: Only change state after migration has finished

On previous change, we changed state at post load time if it was not
running, special casing the "running" change.  Now, we change any states
at the end of the migration.
Signed-off-by: NJuan Quintela <quintela@redhat.com>
Tested-by: NChristian Borntraeger <borntraeger@de.ibm.com>
上级 661725da
...@@ -104,6 +104,8 @@ typedef struct { ...@@ -104,6 +104,8 @@ typedef struct {
bool optional; bool optional;
uint32_t size; uint32_t size;
uint8_t runstate[100]; uint8_t runstate[100];
RunState state;
bool received;
} GlobalState; } GlobalState;
static GlobalState global_state; static GlobalState global_state;
...@@ -119,9 +121,14 @@ static int global_state_store(void) ...@@ -119,9 +121,14 @@ static int global_state_store(void)
return 0; 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) void global_state_set_optional(void)
...@@ -154,26 +161,25 @@ static bool global_state_needed(void *opaque) ...@@ -154,26 +161,25 @@ static bool global_state_needed(void *opaque)
static int global_state_post_load(void *opaque, int version_id) static int global_state_post_load(void *opaque, int version_id)
{ {
GlobalState *s = opaque; GlobalState *s = opaque;
int ret = 0; Error *local_err = NULL;
int r;
char *runstate = (char *)s->runstate; char *runstate = (char *)s->runstate;
s->received = true;
trace_migrate_global_state_post_load(runstate); trace_migrate_global_state_post_load(runstate);
if (strcmp(runstate, "running") != 0) { r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE_MAX,
Error *local_err = NULL;
int r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE_MAX,
-1, &local_err); -1, &local_err);
if (r == -1) { if (r == -1) {
if (local_err) { if (local_err) {
error_report_err(local_err); error_report_err(local_err);
}
return -EINVAL;
} }
ret = vm_stop_force_state(r); return -EINVAL;
} }
s->state = r;
return ret; return 0;
} }
static void global_state_pre_save(void *opaque) static void global_state_pre_save(void *opaque)
...@@ -202,6 +208,7 @@ void register_global_state(void) ...@@ -202,6 +208,7 @@ void register_global_state(void)
{ {
/* We would use it independently that we receive it */ /* We would use it independently that we receive it */
strcpy((char *)&global_state.runstate, ""); strcpy((char *)&global_state.runstate, "");
global_state.received = false;
vmstate_register(NULL, 0, &vmstate_globalstate, &global_state); vmstate_register(NULL, 0, &vmstate_globalstate, &global_state);
} }
...@@ -283,20 +290,19 @@ static void process_incoming_migration_co(void *opaque) ...@@ -283,20 +290,19 @@ static void process_incoming_migration_co(void *opaque)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/* runstate == "" means that we haven't received it through the /* If global state section was not received or we are in running
* wire, so we obey autostart. runstate == runing means that we state, we need to obey autostart. Any other state is set with
* need to run it, we need to make sure that we do it after runstate_set. */
* everything else has finished. Every other state change is done
* at the post_load function */
if (strcmp(global_state_get_runstate(), "running") == 0) { if (!global_state_received() ||
vm_start(); global_state_get_runstate() == RUN_STATE_RUNNING) {
} else if (strcmp(global_state_get_runstate(), "") == 0) {
if (autostart) { if (autostart) {
vm_start(); vm_start();
} else { } else {
runstate_set(RUN_STATE_PAUSED); runstate_set(RUN_STATE_PAUSED);
} }
} else {
runstate_set(global_state_get_runstate());
} }
migrate_decompress_threads_join(); migrate_decompress_threads_join();
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册