Patchwork [RFC,24/24] qemu-img: add inplace conversion to qemu-img

login
register
mail settings
Submitter Devin Nakamura
Date July 29, 2011, 4:49 a.m.
Message ID <1311914994-20482-25-git-send-email-devin122@gmail.com>
Download mbox | patch
Permalink /patch/107334/
State New
Headers show

Comments

Devin Nakamura - July 29, 2011, 4:49 a.m.
Signed-off-by: Devin Nakamura <devin122@gmail.com>
---
 Makefile         |    2 +
 qemu-img-cmds.hx |    6 +++++
 qemu-img.c       |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 0 deletions(-)

Patch

diff --git a/Makefile b/Makefile
index daa3aa0..243c818 100644
--- a/Makefile
+++ b/Makefile
@@ -148,6 +148,8 @@  qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-ob
 
 qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
+qemu-convert$(EXESUF): qemu-convert.o cmd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
+
 qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
 	$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $@")
 
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 1299e83..ea97f83 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -33,6 +33,12 @@  STEXI
 @item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("convert-inplace", img_convert_inplace,
+    "convert-inplace filename target_format")
+STEXI
+@item convert-inplace @var{filename} @var{target_format}
+ETEXI
+
 DEF("info", img_info,
     "info [-f fmt] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index b205e98..c22066e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1024,6 +1024,70 @@  out:
     return 0;
 }
 
+static int img_convert_inplace(int argc, char **argv)
+{
+    int ret;
+    BlockDriverState *bs_src, *bs_tgt;
+    QEMUOptionParameter *options = NULL;
+    BlockConversionOptions drv_options;
+    uint64_t guest_offset, host_offset, count;
+    guest_offset = host_offset = count = 0;
+    bs_src = bdrv_new("");
+    ret = bdrv_open(bs_src, argv[1], BDRV_O_RDWR, NULL);
+    if (ret) {
+        printf("Failed to open source image: %s\n", argv[1]);
+        return ret;
+    }
+
+    ret = bdrv_get_conversion_options(bs_src, &drv_options);
+    if (ret) {
+        printf("Failed getting conversion options\n");
+        goto end_before_tgt;
+    }
+
+    ret = bdrv_open_conversion_target(&bs_tgt, bs_src->file, &drv_options, options, argv[2]);
+    if (ret) {
+        printf("Failed to open conversion target, format: %s\n", argv[2]);
+        switch(ret) {
+            case -ENOENT:
+                printf("No block driver found\n"); break;
+            case -ENOTSUP:
+                printf("Not supported by block driver\n"); break;
+            default:
+                printf("Unknown error (%i)\n", ret);
+        }
+        goto end_before_tgt;
+    }
+
+    do {
+        ret = bdrv_get_mapping(bs_src, &guest_offset, &host_offset, &count);
+        if (!ret) {
+            ret = bdrv_map(bs_tgt, guest_offset, host_offset, count);
+        }
+    } while (count != 0);
+
+    if (ret) {
+        printf("An error occured during mapping process\n");
+        goto end;
+    }
+    ret = bdrv_copy_header(bs_tgt);
+    if (ret) {
+        printf("An error occured during header copy\n");
+        goto end;
+    }
+
+    ret = 0;
+
+end:
+    bdrv_close(bs_tgt);
+end_before_tgt:
+    bdrv_close(bs_src);
+    return ret;
+
+
+
+}
+
 
 static void dump_snapshots(BlockDriverState *bs)
 {