summary refs log tree commit diff stats
path: root/qemu-img.c
diff options
context:
space:
mode:
authorMax Reitz <mreitz@redhat.com>2014-10-24 15:57:38 +0200
committerStefan Hajnoczi <stefanha@redhat.com>2014-11-03 11:41:48 +0000
commit9a86fe489552d47b57c92782471ddfb9e7f702e2 (patch)
tree0edb41317a86504e14eb769a3a102342aadabee2 /qemu-img.c
parentd4a3238af567939f4c51bb074af1ce8839e2ce2d (diff)
downloadfocaccia-qemu-9a86fe489552d47b57c92782471ddfb9e7f702e2.tar.gz
focaccia-qemu-9a86fe489552d47b57c92782471ddfb9e7f702e2.zip
qemu-img: Empty image after commit
After the top image has been committed, it should be emptied unless
specified otherwise.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 1414159063-25977-10-git-send-email-mreitz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'qemu-img.c')
-rw-r--r--qemu-img.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/qemu-img.c b/qemu-img.c
index 494146d6bb..cf8c01c13e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -757,14 +757,14 @@ static int img_commit(int argc, char **argv)
     const char *filename, *fmt, *cache;
     BlockBackend *blk;
     BlockDriverState *bs, *base_bs;
-    bool quiet = false;
+    bool quiet = false, drop = false;
     Error *local_err = NULL;
     CommonBlockJobCBInfo cbi;
 
     fmt = NULL;
     cache = BDRV_DEFAULT_CACHE;
     for(;;) {
-        c = getopt(argc, argv, "f:ht:q");
+        c = getopt(argc, argv, "f:ht:dq");
         if (c == -1) {
             break;
         }
@@ -779,6 +779,9 @@ static int img_commit(int argc, char **argv)
         case 't':
             cache = optarg;
             break;
+        case 'd':
+            drop = true;
+            break;
         case 'q':
             quiet = true;
             break;
@@ -789,7 +792,7 @@ static int img_commit(int argc, char **argv)
     }
     filename = argv[optind++];
 
-    flags = BDRV_O_RDWR;
+    flags = BDRV_O_RDWR | BDRV_O_UNMAP;
     ret = bdrv_parse_cache_flags(cache, &flags);
     if (ret < 0) {
         error_report("Invalid cache option: %s", cache);
@@ -822,7 +825,32 @@ static int img_commit(int argc, char **argv)
         goto done;
     }
 
+    /* The block job will swap base_bs and bs (which is not what we really want
+     * here, but okay) and unref base_bs (after the swap, i.e., the old top
+     * image). In order to still be able to empty that top image afterwards,
+     * increment the reference counter here preemptively. */
+    if (!drop) {
+        bdrv_ref(base_bs);
+    }
+
     run_block_job(bs->job, &local_err);
+    if (local_err) {
+        goto unref_backing;
+    }
+
+    if (!drop && base_bs->drv->bdrv_make_empty) {
+        ret = base_bs->drv->bdrv_make_empty(base_bs);
+        if (ret) {
+            error_setg_errno(&local_err, -ret, "Could not empty %s",
+                             filename);
+            goto unref_backing;
+        }
+    }
+
+unref_backing:
+    if (!drop) {
+        bdrv_unref(base_bs);
+    }
 
 done:
     blk_unref(blk);