diff options
author | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-04-05 17:40:43 +0000 |
---|---|---|
committer | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-04-05 17:40:43 +0000 |
commit | 93c65b47a6fb9ba0e2b89269a751ba3433a33427 (patch) | |
tree | 3a52c01909f7e281d3e70546d0034c1bc9cd629c /block-raw-posix.c | |
parent | f8de16605cf9864e258d91e95be0ed76bdeac744 (diff) |
Add host_device support to qemu-img. (Nolan Leake)
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. Otherwise they end up with stale
garbage where all zero sectors were expected.
I also made the check against bdrv_is_allocated enabled for everything
_except_ host devices, since there is no point in making the block
backend write a bunch of zeros just so that we can memcmp them
immediately afterwards. Host devices can't benefit from this because
there is no way to differentiate between a sector being unallocated
because it was never written, or because it was written with all zeros
and then made a trip through qemu-img convert.
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 <nolan <at> sigbus.net>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6978 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'block-raw-posix.c')
-rw-r--r-- | block-raw-posix.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/block-raw-posix.c b/block-raw-posix.c index 4874b8e4a4..bff822ea65 100644 --- a/block-raw-posix.c +++ b/block-raw-posix.c @@ -1378,11 +1378,47 @@ static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs, } #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 |