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