[libvirt] [PATCH 7/7] VolumeCreateXMLFrom FS storage backend implementation.
Daniel P. Berrange
berrange at redhat.com
Mon May 11 13:05:52 UTC 2009
On Mon, May 04, 2009 at 01:43:02PM -0400, Cole Robinson wrote:
> Add an extra 'inputvol' parameter to the file volume building routines. This
> allows us to easily reuse the duplicate functionality.
>
> @@ -1032,15 +1046,68 @@ static int createRaw(virConnectPtr conn,
> virReportSystemError(conn, errno,
> _("cannot extend file '%s'"),
> vol->target.path);
> - close(fd);
> - return -1;
> + goto cleanup;
> + }
> +
> + remain = vol->capacity;
> +
> + if (inputfd != -1) {
> + size_t bytes = 1024 * 1024;
> + int sparse_interval = 512;
> + int amtread = -1;
> +
> + while (amtread != 0) {
> + char buf[bytes];
Preferrable not to allocate 1 MB on the stack, since not all OS
default to such large stacks as Linux does for threads.
> + char *tmp;
> + int newamt;
> +
> + if (remain < bytes)
> + bytes = remain;
> +
> + if ((amtread = saferead(inputfd, buf, bytes)) < 0) {
> + virReportSystemError(conn, errno,
> + _("failed reading from file '%s'"),
> + inputvol->target.path);
> + goto cleanup;
> + }
> + remain -= amtread;
> +
> + /* Loop over amt read in 512 byte increments, looking for sparse
> + * blocks */
> + tmp = buf;
> + newamt = amtread;
> + do {
> + int interval = ((sparse_interval > newamt) ? newamt
> + : sparse_interval );
> + int sparse_counter = interval;
> +
> + while (sparse_counter-- && *(tmp+sparse_counter) == '\0')
> + continue;
> +
> + if (sparse_counter < 0) {
> + if (lseek(fd, interval, SEEK_CUR) < 0) {
> + virReportSystemError(conn, errno,
> + _("cannot extend file '%s'"),
> + vol->target.path);
> + goto cleanup;
> + }
> + } else if (safewrite(fd, tmp, interval) < 0) {
> + virReportSystemError(conn, errno,
> + _("failed writing to file '%s'"),
> + vol->target.path);
> + goto cleanup;
> +
> + }
> +
> + tmp += interval;
> + } while ((newamt -= sparse_interval) > 0);
> + }
I'm finding this bit of code a little hard to follow. Since you're scanning
in fixed 512 byte chunks, how about just doing
char buf[512];
memset(buf, 0, sizeof buf);
and then just doing a simple loop using memcmp(tmp, buf) over the 1 MB
data. Sure, the current code allows for detection of chunks of zeros
< 512 in size, but since data is allocated in underlying FS in at least
that size chunks, its not worth trying to detect zeros < 512 in length
Regards,
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
More information about the libvir-list
mailing list