From owner-svn-src-head@FreeBSD.ORG Tue Jul 15 04:39:25 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 0D731804; Tue, 15 Jul 2014 04:39:25 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E2CE6277F; Tue, 15 Jul 2014 04:39:24 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s6F4dOCl012340; Tue, 15 Jul 2014 04:39:24 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s6F4dOba012333; Tue, 15 Jul 2014 04:39:24 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201407150439.s6F4dOba012333@svn.freebsd.org> From: Marcel Moolenaar Date: Tue, 15 Jul 2014 04:39:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r268646 - head/usr.bin/mkimg X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jul 2014 04:39:25 -0000 Author: marcel Date: Tue Jul 15 04:39:23 2014 New Revision: 268646 URL: http://svnweb.freebsd.org/changeset/base/268646 Log: Add image_data() for checking whether a sequence of blocks has data. Use this for VHD and VMDK to avoid allocating space in the image for empty sectors. Note that this negatively affects performance because mkimg uses a temporary file for the intermediate storage. When mkimg has better internal book keeping, performance can be significantly improved. Modified: head/usr.bin/mkimg/image.c head/usr.bin/mkimg/image.h head/usr.bin/mkimg/vhd.c head/usr.bin/mkimg/vmdk.c Modified: head/usr.bin/mkimg/image.c ============================================================================== --- head/usr.bin/mkimg/image.c Tue Jul 15 04:33:11 2014 (r268645) +++ head/usr.bin/mkimg/image.c Tue Jul 15 04:39:23 2014 (r268646) @@ -94,12 +94,19 @@ image_copyin(lba_t blk, int fd, uint64_t int image_copyout(int fd) { - off_t ofs; int error; error = image_copyout_region(fd, 0, image_size); - if (error) - return (error); + if (!error) + error = image_copyout_done(fd); + return (error); +} + +int +image_copyout_done(int fd) +{ + off_t ofs; + int error; ofs = lseek(fd, 0L, SEEK_CUR); if (ofs == -1) @@ -148,6 +155,33 @@ image_copyout_region(int fd, lba_t blk, return (error); } +int +image_data(lba_t blk, lba_t size) +{ + char *buffer, *p; + + blk *= secsz; + if (lseek(image_fd, blk, SEEK_SET) != blk) + return (1); + + size *= secsz; + buffer = malloc(size); + if (buffer == NULL) + return (1); + + if (read(image_fd, buffer, size) != (ssize_t)size) { + free(buffer); + return (1); + } + + p = buffer; + while (size > 0 && *p == '\0') + size--, p++; + + free(buffer); + return ((size == 0) ? 0 : 1); +} + lba_t image_get_size(void) { Modified: head/usr.bin/mkimg/image.h ============================================================================== --- head/usr.bin/mkimg/image.h Tue Jul 15 04:33:11 2014 (r268645) +++ head/usr.bin/mkimg/image.h Tue Jul 15 04:39:23 2014 (r268646) @@ -33,7 +33,9 @@ typedef int64_t lba_t; int image_copyin(lba_t blk, int fd, uint64_t *sizep); int image_copyout(int fd); +int image_copyout_done(int fd); int image_copyout_region(int fd, lba_t blk, lba_t size); +int image_data(lba_t blk, lba_t size); lba_t image_get_size(void); int image_init(void); int image_set_size(lba_t blk); Modified: head/usr.bin/mkimg/vhd.c ============================================================================== --- head/usr.bin/mkimg/vhd.c Tue Jul 15 04:33:11 2014 (r268645) +++ head/usr.bin/mkimg/vhd.c Tue Jul 15 04:39:23 2014 (r268646) @@ -214,7 +214,7 @@ vhd_write(int fd) struct vhd_dyn_header header; uuid_t id; uint64_t imgsz; - lba_t blk, nblks; + lba_t blk, blkcnt, nblks; uint32_t *bat; void *bitmap; size_t batsz; @@ -260,10 +260,14 @@ vhd_write(int fd) if (bat == NULL) return (errno); memset(bat, 0xff, batsz); + blkcnt = VHD_BLOCK_SIZE / secsz; sector = (sizeof(footer) + sizeof(header) + batsz) / VHD_SECTOR_SIZE; for (entry = 0; entry < bat_entries; entry++) { - be32enc(&bat[entry], sector); - sector += (VHD_BLOCK_SIZE / VHD_SECTOR_SIZE) + 1; + blk = entry * blkcnt; + if (image_data(blk, blkcnt)) { + be32enc(&bat[entry], sector); + sector += (VHD_BLOCK_SIZE / VHD_SECTOR_SIZE) + 1; + } } if (sparse_write(fd, bat, batsz) < 0) { free(bat); @@ -277,16 +281,21 @@ vhd_write(int fd) memset(bitmap, 0xff, VHD_SECTOR_SIZE); blk = 0; + blkcnt = VHD_BLOCK_SIZE / secsz; nblks = image_get_size(); while (blk < nblks) { + if (!image_data(blk, blkcnt)) { + blk += blkcnt; + continue; + } if (sparse_write(fd, bitmap, VHD_SECTOR_SIZE) < 0) { error = errno; break; } - error = image_copyout_region(fd, blk, VHD_BLOCK_SIZE / secsz); + error = image_copyout_region(fd, blk, blkcnt); if (error) break; - blk += VHD_BLOCK_SIZE / secsz; + blk += blkcnt; } free(bitmap); if (blk != nblks) Modified: head/usr.bin/mkimg/vmdk.c ============================================================================== --- head/usr.bin/mkimg/vmdk.c Tue Jul 15 04:33:11 2014 (r268645) +++ head/usr.bin/mkimg/vmdk.c Tue Jul 15 04:39:23 2014 (r268646) @@ -114,8 +114,9 @@ vmdk_write(int fd) char *buf, *desc; off_t cur, lim; uint64_t imagesz; + lba_t blkofs, blkcnt; size_t gdsz, gtsz; - uint32_t sec; + uint32_t sec, cursec; int error, desc_len, n, ngrains, ngts; imagesz = (image_get_size() * secsz) / VMDK_SECTOR_SIZE; @@ -178,8 +179,15 @@ vmdk_write(int fd) return (ENOMEM); } - for (n = 0; n < ngrains; n++) - le32enc(gt + n, sec + n * grainsz); + cursec = sec; + blkcnt = (grainsz * VMDK_SECTOR_SIZE) / secsz; + for (n = 0; n < ngrains; n++) { + blkofs = n * blkcnt; + if (image_data(blkofs, blkcnt)) { + le32enc(gt + n, cursec); + cursec += grainsz; + } + } error = 0; if (!error && sparse_write(fd, &hdr, VMDK_SECTOR_SIZE) < 0) @@ -210,9 +218,19 @@ vmdk_write(int fd) if (buf != NULL) free(buf); } - if (!error) - error = image_copyout(fd); - return (error); + if (error) + return (error); + + blkcnt = (grainsz * VMDK_SECTOR_SIZE) / secsz; + for (n = 0; n < ngrains; n++) { + blkofs = n * blkcnt; + if (image_data(blkofs, blkcnt)) { + error = image_copyout_region(fd, blkofs, blkcnt); + if (error) + return (error); + } + } + return (image_copyout_done(fd)); } static struct mkimg_format vmdk_format = {