xref: /qemu/migration/global_state.c (revision 44b1ff319c4781c7ab13f7e119b3114a1e6a52e2)
184a899deSJuan Quintela /*
284a899deSJuan Quintela  * Global State configuration
384a899deSJuan Quintela  *
484a899deSJuan Quintela  * Copyright (c) 2014-2017 Red Hat Inc
584a899deSJuan Quintela  *
684a899deSJuan Quintela  * Authors:
784a899deSJuan Quintela  *  Juan Quintela <quintela@redhat.com>
884a899deSJuan Quintela  *
984a899deSJuan Quintela  * This work is licensed under the terms of the GNU GPL, version 2 or later.
1084a899deSJuan Quintela  * See the COPYING file in the top-level directory.
1184a899deSJuan Quintela  */
1284a899deSJuan Quintela 
1384a899deSJuan Quintela #include "qemu/osdep.h"
1484a899deSJuan Quintela #include "qemu/cutils.h"
1584a899deSJuan Quintela #include "qemu/error-report.h"
1684a899deSJuan Quintela #include "qapi/error.h"
175272298cSPeter Xu #include "migration.h"
1884a899deSJuan Quintela #include "migration/global_state.h"
1984a899deSJuan Quintela #include "migration/vmstate.h"
2084a899deSJuan Quintela #include "trace.h"
2184a899deSJuan Quintela 
2284a899deSJuan Quintela typedef struct {
2384a899deSJuan Quintela     uint32_t size;
2484a899deSJuan Quintela     uint8_t runstate[100];
2584a899deSJuan Quintela     RunState state;
2684a899deSJuan Quintela     bool received;
2784a899deSJuan Quintela } GlobalState;
2884a899deSJuan Quintela 
2984a899deSJuan Quintela static GlobalState global_state;
3084a899deSJuan Quintela 
3184a899deSJuan Quintela int global_state_store(void)
3284a899deSJuan Quintela {
3384a899deSJuan Quintela     if (!runstate_store((char *)global_state.runstate,
3484a899deSJuan Quintela                         sizeof(global_state.runstate))) {
3584a899deSJuan Quintela         error_report("runstate name too big: %s", global_state.runstate);
3684a899deSJuan Quintela         trace_migrate_state_too_big();
3784a899deSJuan Quintela         return -EINVAL;
3884a899deSJuan Quintela     }
3984a899deSJuan Quintela     return 0;
4084a899deSJuan Quintela }
4184a899deSJuan Quintela 
4284a899deSJuan Quintela void global_state_store_running(void)
4384a899deSJuan Quintela {
44977c736fSMarkus Armbruster     const char *state = RunState_str(RUN_STATE_RUNNING);
4584a899deSJuan Quintela     strncpy((char *)global_state.runstate,
4684a899deSJuan Quintela            state, sizeof(global_state.runstate));
4784a899deSJuan Quintela }
4884a899deSJuan Quintela 
4984a899deSJuan Quintela bool global_state_received(void)
5084a899deSJuan Quintela {
5184a899deSJuan Quintela     return global_state.received;
5284a899deSJuan Quintela }
5384a899deSJuan Quintela 
5484a899deSJuan Quintela RunState global_state_get_runstate(void)
5584a899deSJuan Quintela {
5684a899deSJuan Quintela     return global_state.state;
5784a899deSJuan Quintela }
5884a899deSJuan Quintela 
5984a899deSJuan Quintela static bool global_state_needed(void *opaque)
6084a899deSJuan Quintela {
6184a899deSJuan Quintela     GlobalState *s = opaque;
6284a899deSJuan Quintela     char *runstate = (char *)s->runstate;
6384a899deSJuan Quintela 
6484a899deSJuan Quintela     /* If it is not optional, it is mandatory */
6584a899deSJuan Quintela 
665272298cSPeter Xu     if (migrate_get_current()->store_global_state) {
6784a899deSJuan Quintela         return true;
6884a899deSJuan Quintela     }
6984a899deSJuan Quintela 
7084a899deSJuan Quintela     /* If state is running or paused, it is not needed */
7184a899deSJuan Quintela 
7284a899deSJuan Quintela     if (strcmp(runstate, "running") == 0 ||
7384a899deSJuan Quintela         strcmp(runstate, "paused") == 0) {
7484a899deSJuan Quintela         return false;
7584a899deSJuan Quintela     }
7684a899deSJuan Quintela 
7784a899deSJuan Quintela     /* for any other state it is needed */
7884a899deSJuan Quintela     return true;
7984a899deSJuan Quintela }
8084a899deSJuan Quintela 
8184a899deSJuan Quintela static int global_state_post_load(void *opaque, int version_id)
8284a899deSJuan Quintela {
8384a899deSJuan Quintela     GlobalState *s = opaque;
8484a899deSJuan Quintela     Error *local_err = NULL;
8584a899deSJuan Quintela     int r;
8684a899deSJuan Quintela     char *runstate = (char *)s->runstate;
8784a899deSJuan Quintela 
8884a899deSJuan Quintela     s->received = true;
8984a899deSJuan Quintela     trace_migrate_global_state_post_load(runstate);
9084a899deSJuan Quintela 
91f7abe0ecSMarc-André Lureau     r = qapi_enum_parse(&RunState_lookup, runstate, -1, &local_err);
9284a899deSJuan Quintela 
9384a899deSJuan Quintela     if (r == -1) {
9484a899deSJuan Quintela         if (local_err) {
9584a899deSJuan Quintela             error_report_err(local_err);
9684a899deSJuan Quintela         }
9784a899deSJuan Quintela         return -EINVAL;
9884a899deSJuan Quintela     }
9984a899deSJuan Quintela     s->state = r;
10084a899deSJuan Quintela 
10184a899deSJuan Quintela     return 0;
10284a899deSJuan Quintela }
10384a899deSJuan Quintela 
104*44b1ff31SDr. David Alan Gilbert static int global_state_pre_save(void *opaque)
10584a899deSJuan Quintela {
10684a899deSJuan Quintela     GlobalState *s = opaque;
10784a899deSJuan Quintela 
10884a899deSJuan Quintela     trace_migrate_global_state_pre_save((char *)s->runstate);
10984a899deSJuan Quintela     s->size = strlen((char *)s->runstate) + 1;
110*44b1ff31SDr. David Alan Gilbert 
111*44b1ff31SDr. David Alan Gilbert     return 0;
11284a899deSJuan Quintela }
11384a899deSJuan Quintela 
11484a899deSJuan Quintela static const VMStateDescription vmstate_globalstate = {
11584a899deSJuan Quintela     .name = "globalstate",
11684a899deSJuan Quintela     .version_id = 1,
11784a899deSJuan Quintela     .minimum_version_id = 1,
11884a899deSJuan Quintela     .post_load = global_state_post_load,
11984a899deSJuan Quintela     .pre_save = global_state_pre_save,
12084a899deSJuan Quintela     .needed = global_state_needed,
12184a899deSJuan Quintela     .fields = (VMStateField[]) {
12284a899deSJuan Quintela         VMSTATE_UINT32(size, GlobalState),
12384a899deSJuan Quintela         VMSTATE_BUFFER(runstate, GlobalState),
12484a899deSJuan Quintela         VMSTATE_END_OF_LIST()
12584a899deSJuan Quintela     },
12684a899deSJuan Quintela };
12784a899deSJuan Quintela 
12884a899deSJuan Quintela void register_global_state(void)
12984a899deSJuan Quintela {
13084a899deSJuan Quintela     /* We would use it independently that we receive it */
13184a899deSJuan Quintela     strcpy((char *)&global_state.runstate, "");
13284a899deSJuan Quintela     global_state.received = false;
13384a899deSJuan Quintela     vmstate_register(NULL, 0, &vmstate_globalstate, &global_state);
13484a899deSJuan Quintela }
135