From patchwork Wed Jul 27 18:42:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 107139 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 A7B76B6F6B for ; Thu, 28 Jul 2011 04:42:46 +1000 (EST) Received: from localhost ([::1]:45367 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qm946-0007UD-Md for incoming@patchwork.ozlabs.org; Wed, 27 Jul 2011 14:42:42 -0400 Received: from eggs.gnu.org ([140.186.70.92]:35760) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qm940-0007Tx-J5 for qemu-devel@nongnu.org; Wed, 27 Jul 2011 14:42:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Qm93z-00038t-3O for qemu-devel@nongnu.org; Wed, 27 Jul 2011 14:42:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:61225) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qm93y-00038f-SP for qemu-devel@nongnu.org; Wed, 27 Jul 2011 14:42:35 -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 p6RIgWwe016309 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 27 Jul 2011 14:42:32 -0400 Received: from doriath (ovpn-113-114.phx2.redhat.com [10.3.113.114]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p6RIgTFe010534; Wed, 27 Jul 2011 14:42:30 -0400 Date: Wed, 27 Jul 2011 15:42:29 -0300 From: Luiz Capitulino To: qemu-devel Message-ID: <20110727154229.656532d4@doriath> Organization: Red Hat Mime-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Jan Kiszka , Avi Kivity Subject: [Qemu-devel] [RFC] Introduce vm_stop_permanent() 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 function should be used when the VM is not supposed to resume execution (eg. by issuing 'cont' monitor command). Today, we allow the user to resume execution even when: o the guest shuts down and -no-shutdown is used o there's a kvm internal error o loading the VM state with -loadvm or "loadvm" in the monitor fails I think only badness can happen from the cases above. Another possible candidate is migration, that's, when the VM is automatically stopped following a successful migration. Signed-off-by: Luiz Capitulino --- cpus.c | 7 +++++++ kvm-all.c | 2 +- monitor.c | 9 +++++++-- qerror.c | 4 ++++ qerror.h | 3 +++ sysemu.h | 2 ++ vl.c | 4 +++- 7 files changed, 27 insertions(+), 4 deletions(-) diff --git a/cpus.c b/cpus.c index 6bf4e3f..5a4a480 100644 --- a/cpus.c +++ b/cpus.c @@ -535,6 +535,13 @@ static void qemu_tcg_init_cpu_signals(void) } #endif /* _WIN32 */ +void vm_stop_permanent(int reason) +{ + vm_stop(reason); + assert(!vm_permanent_stopped); + vm_permanent_stopped = 1; +} + #ifndef CONFIG_IOTHREAD int qemu_init_main_loop(void) { diff --git a/kvm-all.c b/kvm-all.c index cbc2532..4d0ceb3 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1014,7 +1014,7 @@ int kvm_cpu_exec(CPUState *env) if (ret < 0) { cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE); - vm_stop(VMSTOP_PANIC); + vm_stop_permanent(VMSTOP_PANIC); } env->exit_request = 0; diff --git a/monitor.c b/monitor.c index 718935b..86e146c 100644 --- a/monitor.c +++ b/monitor.c @@ -1307,7 +1307,10 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data) { struct bdrv_iterate_context context = { mon, 0 }; - if (incoming_expected) { + if (vm_permanent_stopped) { + qerror_report(QERR_VM_PERMANENT_STOPPED); + return -1; + } else if (incoming_expected) { qerror_report(QERR_MIGRATION_EXPECTED); return -1; } @@ -2814,7 +2817,9 @@ static void do_loadvm(Monitor *mon, const QDict *qdict) vm_stop(VMSTOP_LOADVM); - if (load_vmstate(name) == 0 && saved_vm_running) { + if (load_vmstate(name) < 0) { + vm_permanent_stopped = 1; + } else if (saved_vm_running) { vm_start(); } } diff --git a/qerror.c b/qerror.c index 69c1bc9..c91f763 100644 --- a/qerror.c +++ b/qerror.c @@ -219,6 +219,10 @@ static const QErrorStringTable qerror_table[] = { "supported by this qemu version: %(feature)", }, { + .error_fmt = QERR_VM_PERMANENT_STOPPED, + .desc = "The Virtual Machine is permanently stopped", + }, + { .error_fmt = QERR_VNC_SERVER_FAILED, .desc = "Could not start VNC server on %(target)", }, diff --git a/qerror.h b/qerror.h index 8058456..c759172 100644 --- a/qerror.h +++ b/qerror.h @@ -181,6 +181,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \ "{ 'class': 'UnknownBlockFormatFeature', 'data': { 'device': %s, 'format': %s, 'feature': %s } }" +#define QERR_VM_PERMANENT_STOPPED \ + "{ 'class': 'PermanentStopped', 'data': {} }" + #define QERR_VNC_SERVER_FAILED \ "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }" diff --git a/sysemu.h b/sysemu.h index d3013f5..af90fa3 100644 --- a/sysemu.h +++ b/sysemu.h @@ -12,6 +12,7 @@ extern const char *bios_name; extern int vm_running; +extern int vm_permanent_stopped; extern const char *qemu_name; extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); @@ -39,6 +40,7 @@ void qemu_del_vm_change_state_handler(VMChangeStateEntry *e); void vm_start(void); void vm_stop(int reason); +void vm_stop_permanent(int reason); void qemu_system_reset_request(void); void qemu_system_shutdown_request(void); diff --git a/vl.c b/vl.c index 4b6688b..96403ac 100644 --- a/vl.c +++ b/vl.c @@ -186,6 +186,7 @@ NICInfo nd_table[MAX_NICS]; int vm_running; int autostart; int incoming_expected; /* Started with -incoming and waiting for incoming */ +int vm_permanent_stopped = 0; /* qemu will never resume if set */ static int rtc_utc = 1; static int rtc_date_offset = -1; /* -1 means no change */ QEMUClock *rtc_clock; @@ -1397,7 +1398,7 @@ static void main_loop(void) qemu_kill_report(); monitor_protocol_event(QEVENT_SHUTDOWN, NULL); if (no_shutdown) { - vm_stop(VMSTOP_SHUTDOWN); + vm_stop_permanent(VMSTOP_SHUTDOWN); } else break; } @@ -3315,6 +3316,7 @@ int main(int argc, char **argv, char **envp) qemu_system_reset(VMRESET_SILENT); if (loadvm) { if (load_vmstate(loadvm) < 0) { + vm_permanent_stopped = 1; autostart = 0; } }