From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Lon44-0000s1-4y for qemu-devel@nongnu.org; Tue, 31 Mar 2009 19:08:16 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Lon3y-0000rm-Lv for qemu-devel@nongnu.org; Tue, 31 Mar 2009 19:08:14 -0400 Received: from [199.232.76.173] (port=33925 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Lon3y-0000rj-GW for qemu-devel@nongnu.org; Tue, 31 Mar 2009 19:08:10 -0400 Received: from phong.sigbus.net ([65.49.35.42]:44496) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Lon3x-0003nz-Oe for qemu-devel@nongnu.org; Tue, 31 Mar 2009 19:08:10 -0400 Received: from [192.168.0.3] (c-71-202-202-194.hsd1.ca.comcast.net [71.202.202.194]) by phong.sigbus.net (Postfix) with ESMTPSA id A84DF95C0A1 for ; Tue, 31 Mar 2009 16:08:08 -0700 (PDT) From: Nolan Content-Type: text/plain Date: Tue, 31 Mar 2009 16:08:07 -0700 Message-Id: <1238540887.15350.577.camel@voxel> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH] [RESEND] Add host_device support to qemu-img. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "qemu-devel@nongnu.org" This patch allows the use a host_device as the destination for "qemu-img convert". I added a ->bdrv_create function host_device. It merely verifies that the device exists and is large enough. A check is needed in the qemu-img convert loop to ensure that we write out all 0 sectors to the host_device if they were allocated in the source. I also made the check against bdrv_is_allocated unconditional, since there is no point in making the block backend write a bunch of zeros just so that we can memcmp them immediately afterwards. Finally, there is an unrelated fix for a typo in the error message printed if the destination device does not support ->bdrv_create. Signed-off-by: Nolan Leake sigbus.net> Index: block-raw-posix.c =================================================================== --- block-raw-posix.c (revision 6963) +++ block-raw-posix.c (working copy) @@ -1378,11 +1378,47 @@ } #endif /* !linux && !FreeBSD */ +#if defined(__linux__) || defined(__FreeBSD__) +static int hdev_create(const char *filename, int64_t total_size, + const char *backing_file, int flags) +{ + int fd; + int ret = 0; + struct stat stat_buf; + + if (flags || backing_file) + return -ENOTSUP; + + fd = open(filename, O_WRONLY | O_BINARY); + if (fd < 0) + return -EIO; + + if (fstat(fd, &stat_buf) < 0) + ret = -EIO; + else if (!S_ISBLK(stat_buf.st_mode)) + ret = -EIO; + else if (lseek(fd, 0, SEEK_END) < total_size * 512) + ret = -ENOSPC; + + close(fd); + return ret; +} + +#else /* !(linux || freebsd) */ + +static int hdev_create(const char *filename, int64_t total_size, + const char *backing_file, int flags) +{ + return -ENOTSUP; +} +#endif + BlockDriver bdrv_host_device = { .format_name = "host_device", .instance_size = sizeof(BDRVRawState), .bdrv_open = hdev_open, .bdrv_close = raw_close, + .bdrv_create = hdev_create, .bdrv_flush = raw_flush, #ifdef CONFIG_AIO Index: qemu-img.c =================================================================== --- qemu-img.c (revision 6963) +++ qemu-img.c (working copy) @@ -493,7 +493,7 @@ ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags); if (ret < 0) { if (ret == -ENOTSUP) { - error("Formatting not supported for file format '%s'", fmt); + error("Formatting not supported for file format '%s'", out_fmt); } else { error("Error while formatting '%s'", out_filename); } @@ -592,19 +592,13 @@ if (n > bs_offset + bs_sectors - sector_num) n = bs_offset + bs_sectors - sector_num; - /* If the output image is being created as a copy on write image, - assume that sectors which are unallocated in the input image - are present in both the output's and input's base images (no - need to copy them). */ - if (out_baseimg) { - if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) { - sector_num += n1; - continue; - } - /* The next 'n1' sectors are allocated in the input image. Copy - only those as they may be followed by unallocated sectors. */ - n = n1; + if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) { + sector_num += n1; + continue; } + /* The next 'n1' sectors are allocated in the input image. Copy + only those as they may be followed by unallocated sectors. */ + n = n1; if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) error("error while reading"); @@ -615,8 +609,13 @@ while (n > 0) { /* If the output image is being created as a copy on write image, copy all sectors even the ones containing only NUL bytes, - because they may differ from the sectors in the base image. */ - if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) { + because they may differ from the sectors in the base image. + + If the output is to a host device, we also write out + sectors that are entirely 0, since whatever data was + already there is garbage, not 0s. */ + if (drv == &bdrv_host_device || out_baseimg || + is_allocated_sectors(buf1, n, &n1)) { if (bdrv_write(out_bs, sector_num, buf1, n1) < 0) error("error while writing"); }