qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Qemu-img convert with -B


From: Brad Campbell
Subject: Re: [Qemu-devel] Qemu-img convert with -B
Date: Thu, 28 Apr 2011 10:06:48 +0800
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110223 Lightning/1.0b2 Thunderbird/3.1.8

On 27/04/11 22:02, Brad Campbell wrote:
On 27/04/11 21:56, Kevin Wolf wrote:

When you don't have a backing file, leaving an cluster unallocated means
that it's zero. When you have a backing file, it could be anything. So
if qemu-img convert wanted to save this space, it would have to read
from the backing file and leave the cluster unallocated if it reads as
zero.

This is something that qemu-img doesn't do today.


This passes cursory testing, but I'm just wondering if this is along the right lines?

diff --git a/qemu-img.c b/qemu-img.c
index d9c2c12..ab4c70c 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1,4 +1,4 @@
-/*
+ /*
  * QEMU disk image utility
  *
  * Copyright (c) 2003-2008 Fabrice Bellard
@@ -571,11 +571,12 @@ static int img_convert(int argc, char **argv)
     int progress = 0;
     const char *fmt, *out_fmt, *out_baseimg, *out_filename;
     BlockDriver *drv, *proto_drv;
-    BlockDriverState **bs = NULL, *out_bs = NULL;
+    BlockDriverState **bs = NULL, *out_bs = NULL, *out_bf = NULL;
     int64_t total_sectors, nb_sectors, sector_num, bs_offset;
     uint64_t bs_sectors;
     uint8_t * buf = NULL;
     const uint8_t *buf1;
+    uint8_t * buf3 = NULL;
     BlockDriverInfo bdi;
     QEMUOptionParameter *param = NULL, *create_options = NULL;
     QEMUOptionParameter *out_baseimg_param;
@@ -719,6 +720,12 @@ static int img_convert(int argc, char **argv)
out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
     if (out_baseimg_param) {
         out_baseimg = out_baseimg_param->value.s;
+       out_bf = bdrv_new_open(out_baseimg, NULL, BDRV_O_FLAGS);
+       if (!out_bf) {
+            error_report("Could not open backing file '%s'", out_baseimg);
+            ret = -1;
+            goto out;
+        }
     }

     /* Check if compression is supported */
@@ -767,6 +774,9 @@ static int img_convert(int argc, char **argv)
     bs_offset = 0;
     bdrv_get_geometry(bs[0], &bs_sectors);
     buf = qemu_malloc(IO_BUF_SIZE);
+    if (out_baseimg) {
+        buf3 = qemu_malloc(IO_BUF_SIZE);
+    }

     if (compress) {
         ret = bdrv_get_info(out_bs, &bdi);
@@ -889,9 +899,17 @@ static int img_convert(int argc, char **argv)
are present in both the output's and input's base images (no
                    need to copy them). */
                 if (out_baseimg) {
- if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
-                                           n, &n1)) {
+ if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) {
+                        error_report("error while reading input file");
+                        goto out;
+                    }
+ if (bdrv_read(out_bf, sector_num - bs_offset, buf3, n) < 0) {
+                        error_report("error while reading backing file");
+                        goto out;
+                    }
+                    if (!compare_sectors(buf, buf3, n, &n1)) {
                         sector_num += n1;
+    //                    printf("Skipping %u sectors\n",n1);
                         continue;
                     }
/* The next 'n1' sectors are allocated in the input image. Copy
@@ -939,9 +957,16 @@ out:
     free_option_parameters(create_options);
     free_option_parameters(param);
     qemu_free(buf);
+    if (buf3) {
+        qemu_free(buf3);
+    }
     if (out_bs) {
         bdrv_delete(out_bs);
     }
+    if (out_bf) {
+        bdrv_delete(out_bf);
+    }
+
     if (bs) {
         for (bs_i = 0; bs_i < bs_n; bs_i++) {
             if (bs[bs_i]) {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]