[libvirt] [PATCH] storage: Don't unsparsify images when cloning

Cole Robinson crobinso at redhat.com
Tue Feb 7 20:01:01 UTC 2012


On 02/07/2012 02:55 PM, Cole Robinson wrote:
> Input to the volume cloning code is a source volume and an XML
> descriptor for the new volume. It is possible for the new volume
> to have a greater size than source volume, at which point libvirt
> will just stick 0s on the end of the new image (for raw format
> anyways).
> 
> Unfortunately a logic error messed up our tracking of the of the
> excess amount that needed to be written: end result is that sparse
> clones were made very much non-sparse, and cloning regular disk
> images could end up excessively sized (though data unaltered).
> 
> Drop the 'remain' variable entriely here since it's redundant, and
> track actual allocation directly against the desired 'total'.

There's a RHEL bug here:

https://bugzilla.redhat.com/show_bug.cgi?id=783184

And in fact we've had numerous reports about this in fedora (see the dupes):

https://bugzilla.redhat.com/show_bug.cgi?id=522720

- Cole

> ---
>  src/storage/storage_backend.c |   11 +++--------
>  1 files changed, 3 insertions(+), 8 deletions(-)
> 
> diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
> index 1c22112..caac2f8 100644
> --- a/src/storage/storage_backend.c
> +++ b/src/storage/storage_backend.c
> @@ -127,7 +127,6 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
>      int inputfd = -1;
>      int amtread = -1;
>      int ret = 0;
> -    unsigned long long remain;
>      size_t rbytes = READ_BLOCK_SIZE_DEFAULT;
>      size_t wbytes = 0;
>      int interval;
> @@ -165,13 +164,11 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
>          goto cleanup;
>      }
>  
> -    remain = *total;
> -
>      while (amtread != 0) {
>          int amtleft;
>  
> -        if (remain < rbytes)
> -            rbytes = remain;
> +        if (*total < rbytes)
> +            rbytes = *total;
>  
>          if ((amtread = saferead(inputfd, buf, rbytes)) < 0) {
>              ret = -errno;
> @@ -180,7 +177,7 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
>                                   inputvol->target.path);
>              goto cleanup;
>          }
> -        remain -= amtread;
> +        *total -= amtread;
>  
>          /* Loop over amt read in 512 byte increments, looking for sparse
>           * blocks */
> @@ -225,8 +222,6 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
>      }
>      inputfd = -1;
>  
> -    *total -= remain;
> -
>  cleanup:
>      VIR_FORCE_CLOSE(inputfd);
>  




More information about the libvir-list mailing list