[libvirt] [PATCH] Fix performance problem of virStorageVolCreateXMLFrom()

Minoru Usui usui at mxm.nes.nec.co.jp
Tue Mar 8 10:31:49 UTC 2011


Hi, Daniel.

Thank you for your comment.

> > @@ -119,8 +126,10 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
> >      int amtread = -1;
> >      int ret = 0;
> >      unsigned long long remain;
> > -    size_t rbytes = 1024 * 1024; /* For Read */
> > -    char zerobuf[512];
> > +    size_t rbytes = READ_BLOCK_SIZE_DEFAULT;
> > +    size_t wbytes = WRITE_BLOCK_SIZE_DEFAULT;
> > +    int interval;
> > +    char zerobuf[WRITE_BLOCK_SIZE_DEFAULT];
> 
> Here there is a fixed size buffer which will be written...
> 
> >      char *buf = NULL;
> >  
> >      if ((inputfd = open(inputvol->target.path, O_RDONLY)) < 0) {
> > @@ -131,6 +140,12 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
> >          goto cleanup;
> >      }
> >  
> > +#ifdef __linux__
> > +    if (ioctl(fd, BLKBSZGET, &wbytes) < 0) {
> > +        wbytes = WRITE_BLOCK_SIZE_DEFAULT;
> > +    }
> > +#endif
> 
> ...but the amount written is variable. So this will have an
> out of bounds array access if the returned 'wbytes' is greater
> than WRITE_BLOCK_SIZE_DEFAULT. I think you need to change
> 'zerobuf' to be a heap-allocated variable, instead of fixed
> sized stack allocated variable. eg
> 
>      char *zerobuf;
>      if (VIR_ALLOC_N(zerobuf, wbytes) < 0) {
>          virReportOOMError();
>          goto cleanup;
>      }
>      ....

Ouch, I make a big mistake.
You are right. I'll remake a patch.

> > +
> >      bzero(&zerobuf, sizeof(zerobuf));
> 
> VIR_ALLOC_N zeros, so this line could then be removed.

OK. I'll remove this.

> >  
> >      if (VIR_ALLOC_N(buf, rbytes) < 0) {
> > @@ -160,7 +175,7 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
> >           * blocks */
> >          amtleft = amtread;
> >          do {
> > -            int interval = ((512 > amtleft) ? amtleft : 512);
> > +            interval = ((wbytes > amtleft) ? amtleft : wbytes);
> >              int offset = amtread - amtleft;
> >  
> >              if (is_dest_file && memcmp(buf+offset, zerobuf, interval) == 0) {
> > @@ -179,7 +194,7 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
> >                  goto cleanup;
> >  
> >              }
> > -        } while ((amtleft -= 512) > 0);
> > +        } while ((amtleft -= interval) > 0);
> >      }
> >  
> >      if (VIR_CLOSE(inputfd) < 0) {
> 
> 
> Daniel
> -- 
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
> |: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|


-- 
Minoru Usui <usui at mxm.nes.nec.co.jp>




More information about the libvir-list mailing list