qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Miguel Di Ciurcio Filho <miguel.filho@gmail.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com,
	Miguel Di Ciurcio Filho <miguel.filho@gmail.com>,
	armbru@redhat.com, lcapitulino@redhat.com
Subject: [Qemu-devel] [PATCH 3/3] savevm: prevent snapshot overwriting and generate a default name
Date: Wed, 28 Jul 2010 16:30:24 -0300	[thread overview]
Message-ID: <1280345424-12918-4-git-send-email-miguel.filho@gmail.com> (raw)
In-Reply-To: <1280345424-12918-1-git-send-email-miguel.filho@gmail.com>

This patch address two issues.

1) When savevm is run using an previously saved snapshot id or name, it will
delete the original and create a new one, using the same id and name and not
prompting the user of what just happened.

This behaviour is not good, IMHO.

We add a '-f' parameter to savevm, to really force that to happen, in case the
user really wants to.

New behavior:
(qemu) savevm snap1
An snapshot named 'snap1' already exists

(qemu) savevm -f snap1

We do better error reporting in case '-f' is used too than before.

2) When savevm is run without a name or id, the name stays blank.

This is a first step to hide the internal id, because I don't see a reason to
expose this kind of internals to the user.

The new behavior is when savevm is run without parameters a name will be
created automaticaly, so the snapshot is accessible to the user without needing
the id when loadvm is run.

(qemu) savevm
(qemu) info snapshots
ID        TAG                 VM SIZE                DATE       VM CLOCK
1         vm-20100728134640      978K 2010-07-28 13:46:40   00:00:08.603

We use a name with the format 'vm-YYYYMMDDHHMMSS'.

TODO: I have no clue on how to create a timestamp string when using Windows.

Signed-off-by: Miguel Di Ciurcio Filho <miguel.filho@gmail.com>
---
 qemu-monitor.hx |    9 ++++---
 savevm.c        |   59 ++++++++++++++++++++++++++++++++----------------------
 2 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 9c27b31..94e8178 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -275,14 +275,15 @@ 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  = "force:-f,name:s?",
+        .params     = "[-f] [name]",
+        .help       = "save a VM snapshot. If no name is provided, a new one will be generated"
+		      "\n\t\t\t -f to overwrite an snapshot if it already exists",
         .mhandler.cmd = do_savevm,
     },
 
 STEXI
-@item savevm [@var{tag}|@var{id}]
+@item savevm [-f] [@var{tag}]
 @findex savevm
 Create a snapshot of the whole virtual machine. If @var{tag} is
 provided, it is used as human readable identifier. If there is already
diff --git a/savevm.c b/savevm.c
index fb38e8a..ae6f29f 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1785,7 +1785,7 @@ static int del_existing_snapshots(Monitor *mon, const char *name)
 
 void do_savevm(Monitor *mon, const QDict *qdict)
 {
-    BlockDriverState *bs, *bs1;
+    BlockDriverState *bs_vm_state, *bs;
     QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
     int ret;
     QEMUFile *f;
@@ -1796,7 +1796,9 @@ void do_savevm(Monitor *mon, const QDict *qdict)
 #else
     struct timeval tv;
 #endif
+    struct tm tm;
     const char *name = qdict_get_try_str(qdict, "name");
+    int force = qdict_get_try_bool(qdict, "force", 0);
 
     /* Verify if there is a device that doesn't support snapshots and is writable */
     bs = NULL;
@@ -1813,8 +1815,8 @@ void do_savevm(Monitor *mon, const QDict *qdict)
         }
     }
 
-    bs = bdrv_snapshots();
-    if (!bs) {
+    bs_vm_state = bdrv_snapshots();
+    if (!bs_vm_state) {
         monitor_printf(mon, "No block device can accept snapshots\n");
         return;
     }
@@ -1825,15 +1827,6 @@ void do_savevm(Monitor *mon, const QDict *qdict)
     vm_stop(0);
 
     memset(sn, 0, sizeof(*sn));
-    if (name) {
-        ret = bdrv_snapshot_find(bs, old_sn, name);
-        if (ret >= 0) {
-            pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
-            pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
-        } else {
-            pstrcpy(sn->name, sizeof(sn->name), name);
-        }
-    }
 
     /* fill auxiliary fields */
 #ifdef _WIN32
@@ -1847,13 +1840,31 @@ void do_savevm(Monitor *mon, const QDict *qdict)
 #endif
     sn->vm_clock_nsec = qemu_get_clock(vm_clock);
 
-    /* Delete old snapshots of the same name */
-    if (name && del_existing_snapshots(mon, name) < 0) {
-        goto the_end;
+    if (name) {
+        ret = bdrv_snapshot_find(bs_vm_state, old_sn, name);
+        if (ret == 0) {
+            if (force) {
+                ret = del_existing_snapshots(mon, name);
+                if (ret < 0) {
+                    monitor_printf(mon, "Error deleting snapshot '%s', error: %d\n",
+                        name, ret);
+                    goto the_end;
+                }
+            } else {
+                monitor_printf(mon, "An snapshot named '%s' already exists\n", name);
+                goto the_end;
+            }
+        }
+
+        pstrcpy(sn->name, sizeof(sn->name), name);
+    } else {
+        /* TODO: handle Windows */
+        localtime_r(&tv.tv_sec, &tm);
+        strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", &tm);
     }
 
     /* save the VM state */
-    f = qemu_fopen_bdrv(bs, 1);
+    f = qemu_fopen_bdrv(bs_vm_state, 1);
     if (!f) {
         monitor_printf(mon, "Could not open VM state file\n");
         goto the_end;
@@ -1867,23 +1878,23 @@ void do_savevm(Monitor *mon, const QDict *qdict)
     }
 
     /* create the snapshots */
-
-    bs1 = NULL;
-    while ((bs1 = bdrv_next(bs1))) {
-        if (bdrv_can_snapshot(bs1)) {
+    bs = NULL;
+    while ((bs = bdrv_next(bs))) {
+        if (bdrv_can_snapshot(bs)) {
             /* Write VM state size only to the image that contains the state */
-            sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
-            ret = bdrv_snapshot_create(bs1, sn);
+            sn->vm_state_size = (bs_vm_state == bs ? vm_state_size : 0);
+            ret = bdrv_snapshot_create(bs, sn);
             if (ret < 0) {
                 monitor_printf(mon, "Error while creating snapshot on '%s'\n",
-                               bdrv_get_device_name(bs1));
+                               bdrv_get_device_name(bs));
             }
         }
     }
 
  the_end:
-    if (saved_vm_running)
+    if (saved_vm_running) {
         vm_start();
+    }
 }
 
 int load_vmstate(const char *name)
-- 
1.7.1

  parent reply	other threads:[~2010-07-28 19:32 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-28 19:30 [Qemu-devel] [PATCH 0/3] savem: various cleanups Miguel Di Ciurcio Filho
2010-07-28 19:30 ` [Qemu-devel] [PATCH 1/3] cleanup: bdrv_snaphost_find() returns zero or -ENOENT Miguel Di Ciurcio Filho
2010-07-30  9:44   ` Markus Armbruster
2010-07-30 13:38     ` Luiz Capitulino
2010-07-28 19:30 ` [Qemu-devel] [PATCH 2/3] cleanup: del_existing_snapshots() must return the upstream error code Miguel Di Ciurcio Filho
2010-07-30  9:45   ` Markus Armbruster
2010-07-30 20:28     ` Miguel Di Ciurcio Filho
2010-08-02 11:06       ` Markus Armbruster
2010-07-28 19:30 ` Miguel Di Ciurcio Filho [this message]
2010-07-30  9:34   ` [Qemu-devel] [PATCH 3/3] savevm: prevent snapshot overwriting and generate a default name Markus Armbruster
2010-07-30 13:43     ` Luiz Capitulino
2010-07-30 14:43       ` Markus Armbruster
2010-07-30 14:52         ` Luiz Capitulino
2010-08-02 14:08       ` Chris Lalancette
2010-07-30 13:39   ` [Qemu-devel] " Luiz Capitulino
2010-07-30 14:42     ` Miguel Di Ciurcio Filho
2010-07-30 14:53       ` Luiz Capitulino

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1280345424-12918-4-git-send-email-miguel.filho@gmail.com \
    --to=miguel.filho@gmail.com \
    --cc=armbru@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=lcapitulino@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).