From 864530ac93c85fa62137e5236bbb79a602cb4ffa Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Wed, 19 Oct 2011 14:53:49 +0200 Subject: [PATCH 03/13] runstate_set(): Check for valid transitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Luiz Capitulino Message-id: <1319036039-4358-4-git-send-email-lcapitulino@redhat.com> Patchwork-id: 34407 O-Subject: [PATCH RHEL6.2 qemu-kvm v3 03/13] runstate_set(): Check for valid transitions Bugzilla: 617889 RH-Acked-by: Paolo Bonzini RH-Acked-by: Markus Armbruster RH-Acked-by: Kevin Wolf 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 (cherry picked from commit 5db9d4d18612bd5852bf663a40cf7bcf1ddc1b03) Conflicts: vl.c Signed-off-by: Luiz Capitulino --- sysemu.h | 1 + vl.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletions(-) Signed-off-by: Michal Novotny --- sysemu.h | 1 + vl.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletions(-) diff --git a/sysemu.h b/sysemu.h index c82934b..b32603a 100644 --- a/sysemu.h +++ b/sysemu.h @@ -44,6 +44,7 @@ extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" +void runstate_init(void); bool runstate_check(RunState state); void runstate_set(RunState new_state); typedef struct vm_change_state_entry VMChangeStateEntry; diff --git a/vl.c b/vl.c index a1016a4..d8dc0dc 100644 --- a/vl.c +++ b/vl.c @@ -363,14 +363,84 @@ PicState2 *isa_pic; 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; } @@ -4926,6 +4996,8 @@ int main(int argc, char **argv, char **envp) atexit(qemu_run_exit_notifiers); error_set_progname(argv[0]); + runstate_init(); + init_clocks(); qemu_cache_utils_init(envp); -- 1.7.4.4