qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, peter.crosthwaite@xilinx.com, jcody@redhat.com,
	mreitz@redhat.com, stefanha@redhat.com,
	Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH V11 6/8] qcow2: rollback on fail in qcow2_snapshot_create()
Date: Tue, 11 Feb 2014 14:23:06 -0500	[thread overview]
Message-ID: <1392146588-12120-7-git-send-email-xiawenc@linux.vnet.ibm.com> (raw)
In-Reply-To: <1392146588-12120-1-git-send-email-xiawenc@linux.vnet.ibm.com>

A new variable *err_rollback is added to detect sub function's
rollback failure. If one step in rollback procedure fails, following
steps will be skipped, and the error message will be appended
to errp.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
 block/qcow2-snapshot.c |   37 ++++++++++++++++++++++++++++++++-----
 1 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index ee8f990..12938a0 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -423,6 +423,7 @@ void qcow2_snapshot_create(BlockDriverState *bs,
     int i, ret;
     uint64_t *l1_table = NULL;
     int64_t l1_table_offset;
+    Error *err_rollback = NULL;
 
     memset(sn, 0, sizeof(*sn));
 
@@ -471,7 +472,7 @@ void qcow2_snapshot_create(BlockDriverState *bs,
                          PRIu64 " with size %" PRIu64,
                          sn->l1_table_offset,
                          (uint64_t)(s->l1_size * sizeof(uint64_t)));
-        goto fail;
+        goto dealloc_l1_table;
     }
 
     ret = bdrv_pwrite(bs->file, sn->l1_table_offset, l1_table,
@@ -482,7 +483,7 @@ void qcow2_snapshot_create(BlockDriverState *bs,
                          PRIu64 " with size %" PRIu64,
                          sn->l1_table_offset,
                          (uint64_t)(s->l1_size * sizeof(uint64_t)));
-        goto fail;
+        goto dealloc_l1_table;
     }
 
     g_free(l1_table);
@@ -499,7 +500,7 @@ void qcow2_snapshot_create(BlockDriverState *bs,
                          "Failed in update of refcount for snapshot at %"
                          PRIu64 " with size %d",
                          s->l1_table_offset, s->l1_size);
-        goto fail;
+        goto dealloc_l1_table;
     }
 
     /* Append the new snapshot to the snapshot list */
@@ -512,12 +513,18 @@ void qcow2_snapshot_create(BlockDriverState *bs,
     s->snapshots = new_snapshot_list;
     s->snapshots[s->nb_snapshots++] = *sn;
 
-    ret = qcow2_write_snapshots(bs, errp, NULL);
+    ret = qcow2_write_snapshots(bs, errp, &err_rollback);
     if (ret < 0) {
         g_free(s->snapshots);
         s->snapshots = old_snapshot_list;
         s->nb_snapshots--;
-        goto fail;
+        if (error_is_set(&err_rollback)) {
+            error_append(errp, "%s", error_get_pretty(err_rollback));
+            error_free(err_rollback);
+            goto fail;
+        } else {
+            goto restore_refcount;
+        }
     }
 
     g_free(old_snapshot_list);
@@ -537,6 +544,26 @@ void qcow2_snapshot_create(BlockDriverState *bs,
 #endif
     return;
 
+restore_refcount:
+    if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, -1)
+        < 0) {
+        /* Nothing can be done now, need image check later, skip following
+           rollback action. */
+        error_append(errp,
+                    "Failed to restore refcounts during rollback");
+        goto fail;
+    }
+
+dealloc_l1_table:
+    ret = qcow2_free_clusters(bs, sn->l1_table_offset,
+                              sn->l1_size * sizeof(uint64_t),
+                              QCOW2_DISCARD_ALWAYS);
+    if (ret < 0) {
+        error_append(errp,
+                     "Failed to free the L1 table during rollback: %s",
+                     strerror(-ret));
+    }
+
 fail:
     g_free(sn->id_str);
     g_free(sn->name);
-- 
1.7.1

  parent reply	other threads:[~2014-02-11  6:22 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-11 19:23 [Qemu-devel] [PATCH V11 0/8] qcow2: rollback the modification on fail in snapshot creation Wenchao Xia
2014-02-11 19:23 ` [Qemu-devel] [PATCH V11 1/8] snapshot: add parameter *errp in snapshot create Wenchao Xia
2014-02-11 19:23 ` [Qemu-devel] [PATCH V11 2/8] qcow2: add error message in qcow2_write_snapshots() Wenchao Xia
2014-02-11 19:23 ` [Qemu-devel] [PATCH V11 3/8] util: add error_append() Wenchao Xia
2014-02-11 19:23 ` [Qemu-devel] [PATCH V11 4/8] qcow2: return int for qcow2_free_clusters() Wenchao Xia
2014-02-11 19:23 ` [Qemu-devel] [PATCH V11 5/8] qcow2: full rollback on fail in qcow2_write_snapshots() Wenchao Xia
2014-02-11 19:23 ` Wenchao Xia [this message]
2014-02-11 19:23 ` [Qemu-devel] [PATCH V11 7/8] blkdebug: add debug events for snapshot Wenchao Xia
2014-02-11 19:23 ` [Qemu-devel] [PATCH V11 8/8] qemu-iotests: add test for qcow2 snapshot Wenchao Xia
2014-02-13  7:22 ` [Qemu-devel] [PATCH V11 0/8] qcow2: rollback the modification on fail in snapshot creation Wenchao Xia
2014-02-21  0:11 ` Wenchao Xia

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=1392146588-12120-7-git-send-email-xiawenc@linux.vnet.ibm.com \
    --to=xiawenc@linux.vnet.ibm.com \
    --cc=jcody@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=peter.crosthwaite@xilinx.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /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).