From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LPEtA-0007b8-Fi for qemu-devel@nongnu.org; Tue, 20 Jan 2009 06:35:24 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LPEt9-0007aM-93 for qemu-devel@nongnu.org; Tue, 20 Jan 2009 06:35:23 -0500 Received: from [199.232.76.173] (port=36514 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LPEt8-0007a2-5f for qemu-devel@nongnu.org; Tue, 20 Jan 2009 06:35:22 -0500 Received: from mx2.redhat.com ([66.187.237.31]:38433) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LPEt7-000470-LR for qemu-devel@nongnu.org; Tue, 20 Jan 2009 06:35:21 -0500 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n0KBZLjB017409 for ; Tue, 20 Jan 2009 06:35:21 -0500 From: Uri Lublin Date: Tue, 20 Jan 2009 13:35:17 +0200 Message-Id: <1232451317-16532-1-git-send-email-uril@redhat.com> Subject: [Qemu-devel] [MIGRATION_TO_FILE_ALTERNATIVE] savevm/loadvm to/from a file Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Uri Lublin Sometimes we do not want to save VM state internally (within the image). For example raw images (and any other non qcow images) are not capable of savevm'ing. This patch enables saving/loading the VM state in/from a file. It introduces two monitor commands savevm_file and loadvm_file (should I just add flags or add prefix to savevm/loadvm ?). When saving VM state, upon successful operation, the VM is left in stopped mode (such that it does not change the disk image). When loading VM state, upon a failure, the VM is left in stopped mode; The user or a management-app should send a quit command, as otherwise the VM state may be inconsistent. Signed-off-by: Uri Lublin --- monitor.c | 4 ++++ savevm.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sysemu.h | 2 ++ 3 files changed, 64 insertions(+), 0 deletions(-) diff --git a/monitor.c b/monitor.c index 7ff9890..02274bc 100644 --- a/monitor.c +++ b/monitor.c @@ -1454,6 +1454,10 @@ static const term_cmd_t term_cmds[] = { "tag|id", "restore a VM snapshot from its tag or id" }, { "delvm", "s", do_delvm, "tag|id", "delete a VM snapshot from its tag or id" }, + { "savevm_file", "F", do_savevm_file, + "filename", "save a VM state in a file." }, + { "loadvm_file", "F", do_loadvm_file, + "filename", "load a VM state from a file" }, { "stop", "", do_stop, "", "stop emulation", }, { "c|cont", "", do_cont, diff --git a/savevm.c b/savevm.c index 729e849..98f73ce 100644 --- a/savevm.c +++ b/savevm.c @@ -1114,6 +1114,37 @@ void do_savevm(const char *name) vm_start(); } +void do_savevm_file(const char *filename) +{ + int saved_vm_running = vm_running; + int ret; + QEMUFile *f; + + umask(00600); /* rw for user only */ + + /* save the VM state */ + f = qemu_fopen(filename, "wb"); + if (!f) { + term_printf("Could not open VM state file %s\n", filename); + return; + } + qemu_aio_flush(); + vm_stop(0); + ret = qemu_savevm_state(f); + qemu_fclose(f); + if (ret < 0) { + term_printf("Error %d while writing VM\n", ret); + unlink(filename); + /* continue only upon failure */ + if (saved_vm_running) + vm_start(); + } + else { + term_printf("completed successfully savevm_file %s\n", filename); + } +} + + void do_loadvm(const char *name) { BlockDriverState *bs, *bs1; @@ -1190,6 +1221,33 @@ void do_loadvm(const char *name) vm_start(); } +void do_loadvm_file(const char *filename) +{ + int ret; + QEMUFile *f; + + f = qemu_fopen(filename, "rb"); + if (!f) { + term_printf("Could not open VM state file %s\n", filename); + return; + } + + /* Flush all IO requests so they don't interfere with the new state. */ + qemu_aio_flush(); + vm_stop(0); + + ret = qemu_loadvm_state(f); + qemu_fclose(f); + if (ret < 0) { + term_printf("Error %d while writing VM\n", ret); + } + else { + /* continue only upon success */ + term_printf("completed successfully loadvm_file %s\n", filename); + vm_start(); + } +} + void do_delvm(const char *name) { BlockDriverState *bs, *bs1; diff --git a/sysemu.h b/sysemu.h index 56eb9b3..f27058b 100644 --- a/sysemu.h +++ b/sysemu.h @@ -47,6 +47,8 @@ void do_savevm(const char *name); void do_loadvm(const char *name); void do_delvm(const char *name); void do_info_snapshots(void); +void do_savevm_file(const char *filename); +void do_loadvm_file(const char *filename); void qemu_announce_self(void); -- 1.6.0.6