summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-05 17:40:43 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-05 17:40:43 +0000
commit93c65b47a6fb9ba0e2b89269a751ba3433a33427 (patch)
tree3a52c01909f7e281d3e70546d0034c1bc9cd629c /qemu-img.c
parentFix (at least one cause of) qcow2 corruption. (Nolan Leake) (diff)
downloadqemu-kvm-93c65b47a6fb9ba0e2b89269a751ba3433a33427.tar.gz
qemu-kvm-93c65b47a6fb9ba0e2b89269a751ba3433a33427.tar.bz2
qemu-kvm-93c65b47a6fb9ba0e2b89269a751ba3433a33427.zip
Add host_device support to qemu-img. (Nolan Leake)
This patch allows the use a host_device as the destination for "qemu-img convert". I added a ->bdrv_create function host_device. It merely verifies that the device exists and is large enough. A check is needed in the qemu-img convert loop to ensure that we write out all 0 sectors to the host_device. Otherwise they end up with stale garbage where all zero sectors were expected. I also made the check against bdrv_is_allocated enabled for everything _except_ host devices, since there is no point in making the block backend write a bunch of zeros just so that we can memcmp them immediately afterwards. Host devices can't benefit from this because there is no way to differentiate between a sector being unallocated because it was never written, or because it was written with all zeros and then made a trip through qemu-img convert. Finally, there is an unrelated fix for a typo in the error message printed if the destination device does not support ->bdrv_create. Signed-off-by: Nolan Leake <nolan <at> sigbus.net> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6978 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'qemu-img.c')
-rw-r--r--qemu-img.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/qemu-img.c b/qemu-img.c
index ab380c8a4..913ad34bf 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -493,7 +493,7 @@ static int img_convert(int argc, char **argv)
ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
if (ret < 0) {
if (ret == -ENOTSUP) {
- error("Formatting not supported for file format '%s'", fmt);
+ error("Formatting not supported for file format '%s'", out_fmt);
} else {
error("Error while formatting '%s'", out_filename);
}
@@ -592,18 +592,17 @@ static int img_convert(int argc, char **argv)
if (n > bs_offset + bs_sectors - sector_num)
n = bs_offset + bs_sectors - sector_num;
- /* If the output image is being created as a copy on write image,
- assume that sectors which are unallocated in the input image
- 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)) {
- sector_num += n1;
- continue;
- }
- /* The next 'n1' sectors are allocated in the input image. Copy
- only those as they may be followed by unallocated sectors. */
- n = n1;
+ if (drv != &bdrv_host_device) {
+ if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
+ n, &n1)) {
+ sector_num += n1;
+ continue;
+ }
+ /* The next 'n1' sectors are allocated in the input image. Copy
+ only those as they may be followed by unallocated sectors. */
+ n = n1;
+ } else {
+ n1 = n;
}
if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0)
@@ -615,8 +614,13 @@ static int img_convert(int argc, char **argv)
while (n > 0) {
/* If the output image is being created as a copy on write image,
copy all sectors even the ones containing only NUL bytes,
- because they may differ from the sectors in the base image. */
- if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) {
+ because they may differ from the sectors in the base image.
+
+ If the output is to a host device, we also write out
+ sectors that are entirely 0, since whatever data was
+ already there is garbage, not 0s. */
+ if (drv == &bdrv_host_device || out_baseimg ||
+ is_allocated_sectors(buf1, n, &n1)) {
if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
error("error while writing");
}