diff mbox

[RFC] savevm only saves disk state

Message ID 1284083014-8198-1-git-send-email-disheng.su@gmail.com
State New
Headers show

Commit Message

disheng.su@gmail.com Sept. 10, 2010, 1:43 a.m. UTC
From: edison <edison@cloud.com>

Add a new option when "savevm": savevm -n snapshotName, which only takes snapshot on disk, but doesn't save vm state(memory,cpu,devices...).
Saving vm state on QCOW2 disk will take a long time, per my test, it will take 1~2 minutes to "savevm" on VM with 1G memory. Even worse, the VM is wholely stopped at that time, makes "savevm" not that useful.
All we know the side effect of it:) but does it make sense to give user the choice?
---
 qemu-monitor.hx |    6 +++---
 savevm.c        |   34 ++++++++++++++++++++++------------
 2 files changed, 25 insertions(+), 15 deletions(-)

Comments

Anthony Liguori Sept. 10, 2010, 2:08 a.m. UTC | #1
On 09/09/2010 08:43 PM, disheng.su@gmail.com wrote:
> From: edison<edison@cloud.com>
>
> Add a new option when "savevm": savevm -n snapshotName, which only takes snapshot on disk, but doesn't save vm state(memory,cpu,devices...).
> Saving vm state on QCOW2 disk will take a long time, per my test, it will take 1~2 minutes to "savevm" on VM with 1G memory. Even worse, the VM is wholely stopped at that time, makes "savevm" not that useful.
> All we know the side effect of it:) but does it make sense to give user the choice?
>    

I think it would be better to explore ways to make savevm live.  A round 
about option would be to combine a disk-only snapshot with a live 
migration to disk and somehow allow qcow2 to refer to an external memory 
snapshot.

A better alternative would be a live snapshot within qcow2.  I think 
Kevin has some good ideas about how to do this with qcow2 today but 
provided we had a nice interface to do this, the changes to the live 
migration code should be fairly straight forward.

Regards,

Anthony Liguori
disheng.su@gmail.com Sept. 15, 2010, 6:24 p.m. UTC | #2
On Thu, Sep 9, 2010 at 7:08 PM, Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 09/09/2010 08:43 PM, disheng.su@gmail.com wrote:
>>
>> From: edison<edison@cloud.com>
>>
>> Add a new option when "savevm": savevm -n snapshotName, which only takes
>> snapshot on disk, but doesn't save vm state(memory,cpu,devices...).
>> Saving vm state on QCOW2 disk will take a long time, per my test, it will
>> take 1~2 minutes to "savevm" on VM with 1G memory. Even worse, the VM is
>> wholely stopped at that time, makes "savevm" not that useful.
>> All we know the side effect of it:) but does it make sense to give user
>> the choice?
>>
>
> I think it would be better to explore ways to make savevm live.  A round
> about option would be to combine a disk-only snapshot with a live migration
> to disk and somehow allow qcow2 to refer to an external memory snapshot.
>

My point is we still need an interface to take online snapshot for
disk-only(flush pending I/O, take QCOW2 snapshot, no savevm, no live
migration), which is the fastest , lowest down time and easy to
manage.
Look like VMware supports such kind of operation: take a snapshot
without saving memory(http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1015180).

Of cause, it's better to cooperate with pv driver, or tools inside
guest, which can hold I/O, flush disk cache, etc. If without such
co-operation, the bare disk snapshot is just like saving the disk
state when loosing power, not that bad, right?

> A better alternative would be a live snapshot within qcow2.  I think Kevin
> has some good ideas about how to do this with qcow2 today but provided we
> had a nice interface to do this, the changes to the live migration code
> should be fairly straight forward.

Hi Kevin, any idea about it? Live snapshot is very useful. Do you
already have ideas/plans about it? I want to take a look at it, make
it live!


>
> Regards,
>
> Anthony Liguori
>
>
Kevin Wolf Sept. 16, 2010, 10:03 a.m. UTC | #3
Am 15.09.2010 20:24, schrieb edison:
> On Thu, Sep 9, 2010 at 7:08 PM, Anthony Liguori <anthony@codemonkey.ws> wrote:
>> On 09/09/2010 08:43 PM, disheng.su@gmail.com wrote:
>>>
>>> From: edison<edison@cloud.com>
>>>
>>> Add a new option when "savevm": savevm -n snapshotName, which only takes
>>> snapshot on disk, but doesn't save vm state(memory,cpu,devices...).
>>> Saving vm state on QCOW2 disk will take a long time, per my test, it will
>>> take 1~2 minutes to "savevm" on VM with 1G memory. Even worse, the VM is
>>> wholely stopped at that time, makes "savevm" not that useful.
>>> All we know the side effect of it:) but does it make sense to give user
>>> the choice?
>>>
>>
>> I think it would be better to explore ways to make savevm live.  A round
>> about option would be to combine a disk-only snapshot with a live migration
>> to disk and somehow allow qcow2 to refer to an external memory snapshot.
>>
> 
> My point is we still need an interface to take online snapshot for
> disk-only(flush pending I/O, take QCOW2 snapshot, no savevm, no live
> migration), which is the fastest , lowest down time and easy to
> manage.
> Look like VMware supports such kind of operation: take a snapshot
> without saving memory(http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1015180).
> 
> Of cause, it's better to cooperate with pv driver, or tools inside
> guest, which can hold I/O, flush disk cache, etc. If without such
> co-operation, the bare disk snapshot is just like saving the disk
> state when loosing power, not that bad, right?

I agree that disk-only snapshots probably have their place. We already
create them with qemu-img snapshot -c, so I think it would be
appropriate to expose the option in the monitor, too.

>> A better alternative would be a live snapshot within qcow2.  I think Kevin
>> has some good ideas about how to do this with qcow2 today but provided we
>> had a nice interface to do this, the changes to the live migration code
>> should be fairly straight forward.
> 
> Hi Kevin, any idea about it? Live snapshot is very useful. Do you
> already have ideas/plans about it? I want to take a look at it, make
> it live!

I haven't taken a very close look at this yet, but in theory it should
be really straightforward.

The one thing you need to know is how VM state is saved in qcow2: It is
stored just like the normal data on the virtual disk, but at offsets
greater than the virtual size of the disk, so that guests don't see it.
For example if you have an 8 GB image (virtual size), the VM state might
start at 10 GB.

Currently when you do a savevm, we save the state of all these devices
to the VM state area (using bdrv_save_vmstate()) and then take a disk
snapshot (which magically includes the VM state, because it's just some
data on the disk).

So when making snapshots live, what you need to do is basically a live
migration into this part of the virtual disk (should be very similar to
migrating into an external file, which is possible today). Once the VM
state is saved to the virtual disk, you can take the good old disk
snapshot and you're done.

Kevin
diff mbox

Patch

diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 49bcd8d..724e0a2 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -327,9 +327,9 @@  ETEXI
 
     {
         .name       = "savevm",
-        .args_type  = "name:s?",
-        .params     = "[tag|id]",
-        .help       = "save a VM snapshot. If no tag or id are provided, a new snapshot is created",
+        .args_type  = "nostate:-n,name:s?",
+        .params     = "[-n] [tag|id]",
+        .help       = "save a VM snapshot. If no tag or id are provided, a new snapshot is created. If -n is specified, do not save vm state",
         .mhandler.cmd = do_savevm,
     },
 
diff --git a/savevm.c b/savevm.c
index 6fa7a5f..b0963b5 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1834,7 +1834,8 @@  void do_savevm(Monitor *mon, const QDict *qdict)
     int ret;
     QEMUFile *f;
     int saved_vm_running;
-    uint32_t vm_state_size;
+    uint32_t vm_state_size = 0;
+    
 #ifdef _WIN32
     struct _timeb tb;
     struct tm *ptm;
@@ -1844,6 +1845,8 @@  void do_savevm(Monitor *mon, const QDict *qdict)
 #endif
     const char *name = qdict_get_try_str(qdict, "name");
 
+    int nostate = qdict_get_try_bool(qdict, "nostate", 0);
+
     /* Verify if there is a device that doesn't support snapshots and is writable */
     bs = NULL;
     while ((bs = bdrv_next(bs))) {
@@ -1909,17 +1912,19 @@  void do_savevm(Monitor *mon, const QDict *qdict)
     }
 
     /* save the VM state */
-    f = qemu_fopen_bdrv(bs, 1);
-    if (!f) {
-        monitor_printf(mon, "Could not open VM state file\n");
-        goto the_end;
-    }
-    ret = qemu_savevm_state(mon, f);
-    vm_state_size = qemu_ftell(f);
-    qemu_fclose(f);
-    if (ret < 0) {
-        monitor_printf(mon, "Error %d while writing VM\n", ret);
-        goto the_end;
+    if (!nostate) {
+        f = qemu_fopen_bdrv(bs, 1);
+        if (!f) {
+            monitor_printf(mon, "Could not open VM state file\n");
+            goto the_end;
+        }
+        ret = qemu_savevm_state(mon, f);
+        vm_state_size = qemu_ftell(f);
+        qemu_fclose(f);
+        if (ret < 0) {
+            monitor_printf(mon, "Error %d while writing VM\n", ret);
+            goto the_end;
+        }
     }
 
     /* create the snapshots */
@@ -1984,6 +1989,11 @@  int load_vmstate(const char *name)
                            bdrv_get_device_name(bs), name);
             return ret;
         }
+        
+        if (sn.vm_state_size == 0) {
+            error_report("No vm state stored on snapshot: '%s'.", name);
+            return -ENOTSUP;
+        }
     }
 
     /* Flush all IO requests so they don't interfere with the new state.  */