[libvirt] [PATCH] storage: Don't unsparsify images when cloning
Cole Robinson
crobinso at redhat.com
Tue Feb 7 22:31:28 UTC 2012
On 02/07/2012 03:17 PM, Eric Blake wrote:
> On 02/07/2012 12: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
>
> s/entriely/entirely/
>
>> track actual allocation directly against the desired 'total'.
>> ---
>> src/storage/storage_backend.c | 11 +++--------
>> 1 files changed, 3 insertions(+), 8 deletions(-)
>
> Hmm - given that we just added virStorageVolResize, with a flag
> VIR_STORAGE_VOL_RESIZE_ALLOCATE, where the default operation is a sparse
> resize but the flag requests a non-sparse allocation, I'm wondering if
> virStorageVolCreateXMLFrom should also be taught to use a flag that
> controls whether or not we attempt to sparsify the output (the default
> of sparse is nicer, as it is likely to be faster, but there are some
> cases where a sparse file is undesirable because you want to know up
> front if you are going to hit ENOSPC errors, rather than overcommitting
> due to sparse files that later grow).
>
>>
>> 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;
>
> If I'm understanding you correctly, this line was the logic error: it
> should have been '*total = remain' instead of using -=.
>
> The only reason for using remain instead of total would have then been
> to avoid pointer dereferencing in the loop, but I don't think it's on a
> hot enough path to make a difference, so I'm okay with your patch as-is
> (although we should still be thinking about a flag that controls whether
> the user can request non-sparse clones).
>
As you OK'd this on IRC, I've pushed it now:
http://libvirt.org/git/?p=libvirt.git;a=commit;h=0ed86cfb514fea6d6c6182fec86a632ff0fa3062
Thanks,
Cole
More information about the libvir-list
mailing list