mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 01:03:55 -06:00
runstate_set(): Check for valid transitions
This commit could have been folded with the previous one, however doing it separately will allow for easy bisect and revert if needed. Checking and testing all valid transitions wasn't trivial, chances are this will need broader testing to become more stable. This is a transition table as suggested by Lluís Vilanova. Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
parent
f5bbfba1eb
commit
5db9d4d186
2 changed files with 74 additions and 1 deletions
74
vl.c
74
vl.c
|
@ -327,14 +327,84 @@ static int default_driver_check(QemuOpts *opts, void *opaque)
|
|||
|
||||
static RunState current_run_state = RSTATE_NO_STATE;
|
||||
|
||||
typedef struct {
|
||||
RunState from;
|
||||
RunState to;
|
||||
} RunStateTransition;
|
||||
|
||||
static const RunStateTransition runstate_transitions_def[] = {
|
||||
/* from -> to */
|
||||
{ RSTATE_NO_STATE, RSTATE_RUNNING },
|
||||
{ RSTATE_NO_STATE, RSTATE_IN_MIGRATE },
|
||||
{ RSTATE_NO_STATE, RSTATE_PRE_LAUNCH },
|
||||
|
||||
{ RSTATE_DEBUG, RSTATE_RUNNING },
|
||||
|
||||
{ RSTATE_IN_MIGRATE, RSTATE_RUNNING },
|
||||
{ RSTATE_IN_MIGRATE, RSTATE_PRE_LAUNCH },
|
||||
|
||||
{ RSTATE_PANICKED, RSTATE_PAUSED },
|
||||
|
||||
{ RSTATE_IO_ERROR, RSTATE_RUNNING },
|
||||
|
||||
{ RSTATE_PAUSED, RSTATE_RUNNING },
|
||||
|
||||
{ RSTATE_POST_MIGRATE, RSTATE_RUNNING },
|
||||
|
||||
{ RSTATE_PRE_LAUNCH, RSTATE_RUNNING },
|
||||
{ RSTATE_PRE_LAUNCH, RSTATE_POST_MIGRATE },
|
||||
|
||||
{ RSTATE_PRE_MIGRATE, RSTATE_RUNNING },
|
||||
{ RSTATE_PRE_MIGRATE, RSTATE_POST_MIGRATE },
|
||||
|
||||
{ RSTATE_RESTORE, RSTATE_RUNNING },
|
||||
|
||||
{ RSTATE_RUNNING, RSTATE_DEBUG },
|
||||
{ RSTATE_RUNNING, RSTATE_PANICKED },
|
||||
{ RSTATE_RUNNING, RSTATE_IO_ERROR },
|
||||
{ RSTATE_RUNNING, RSTATE_PAUSED },
|
||||
{ RSTATE_RUNNING, RSTATE_PRE_MIGRATE },
|
||||
{ RSTATE_RUNNING, RSTATE_RESTORE },
|
||||
{ RSTATE_RUNNING, RSTATE_SAVEVM },
|
||||
{ RSTATE_RUNNING, RSTATE_SHUTDOWN },
|
||||
{ RSTATE_RUNNING, RSTATE_WATCHDOG },
|
||||
|
||||
{ RSTATE_SAVEVM, RSTATE_RUNNING },
|
||||
|
||||
{ RSTATE_SHUTDOWN, RSTATE_PAUSED },
|
||||
|
||||
{ RSTATE_WATCHDOG, RSTATE_RUNNING },
|
||||
|
||||
{ RSTATE_MAX, RSTATE_MAX },
|
||||
};
|
||||
|
||||
static bool runstate_valid_transitions[RSTATE_MAX][RSTATE_MAX];
|
||||
|
||||
bool runstate_check(RunState state)
|
||||
{
|
||||
return current_run_state == state;
|
||||
}
|
||||
|
||||
void runstate_init(void)
|
||||
{
|
||||
const RunStateTransition *p;
|
||||
|
||||
memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
|
||||
|
||||
for (p = &runstate_transitions_def[0]; p->from != RSTATE_MAX; p++) {
|
||||
runstate_valid_transitions[p->from][p->to] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function will abort() on invalid state transitions */
|
||||
void runstate_set(RunState new_state)
|
||||
{
|
||||
assert(new_state < RSTATE_MAX);
|
||||
if (new_state >= RSTATE_MAX ||
|
||||
!runstate_valid_transitions[current_run_state][new_state]) {
|
||||
fprintf(stderr, "invalid runstate transition\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
current_run_state = new_state;
|
||||
}
|
||||
|
||||
|
@ -2219,6 +2289,8 @@ int main(int argc, char **argv, char **envp)
|
|||
g_mem_set_vtable(&mem_trace);
|
||||
g_thread_init(NULL);
|
||||
|
||||
runstate_init();
|
||||
|
||||
init_clocks();
|
||||
|
||||
qemu_cache_utils_init(envp);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue