From patchwork Fri Sep 9 20:25:41 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 114134 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id EA11EB70B1 for ; Sat, 10 Sep 2011 06:27:23 +1000 (EST) Received: from localhost ([::1]:50728 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R27fP-0006KD-Tt for incoming@patchwork.ozlabs.org; Fri, 09 Sep 2011 16:27:15 -0400 Received: from eggs.gnu.org ([140.186.70.92]:41720) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R27eF-0002ju-WF for qemu-devel@nongnu.org; Fri, 09 Sep 2011 16:26:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R27eD-0001rk-Qj for qemu-devel@nongnu.org; Fri, 09 Sep 2011 16:26:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40666) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R27eD-0001rX-9I for qemu-devel@nongnu.org; Fri, 09 Sep 2011 16:26:01 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p89KPwNR026766 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 9 Sep 2011 16:25:58 -0400 Received: from localhost (ovpn-113-92.phx2.redhat.com [10.3.113.92]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p89KPvrV031313; Fri, 9 Sep 2011 16:25:57 -0400 From: Luiz Capitulino To: qemu-devel@nongnu.org Date: Fri, 9 Sep 2011 17:25:41 -0300 Message-Id: <1315599946-27081-5-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1315599946-27081-1-git-send-email-lcapitulino@redhat.com> References: <1315599946-27081-1-git-send-email-lcapitulino@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-MIME-Autoconverted: from 8bit to quoted-printable by mx1.redhat.com id p89KPwNR026766 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, aliguori@us.ibm.com, jan.kiszka@siemens.com, armbru@redhat.com, amit.shah@redhat.com, vilanova@ac.upc.edu Subject: [Qemu-devel] [PATCH 4/9] runstate_set(): Check for valid transitions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- sysemu.h | 1 + vl.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletions(-) diff --git a/sysemu.h b/sysemu.h index 19088aa..a01ddac 100644 --- a/sysemu.h +++ b/sysemu.h @@ -36,6 +36,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 9926d2a..4a8edc7 100644 --- a/vl.c +++ b/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; } @@ -2218,6 +2288,8 @@ int main(int argc, char **argv, char **envp) g_mem_set_vtable(&mem_trace); + runstate_init(); + init_clocks(); qemu_cache_utils_init(envp);