Re: [Qemu-devel] [PATCH v5] block:add-cow file format
On Tue, Nov 15, 2011 at 01:28:51PM +0800, Dong Xu Wang wrote: From: Dong Xu Wang wdon...@linux.vnet.ibm.com Provide a new file format: add-cow. The usage can be found in add-cow.txt of this patch. Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com --- Makefile.objs |1 + block.c|2 +- block.h|1 + block/add-cow.c| 417 block_int.h|1 + docs/specs/add-cow.txt | 57 +++ 6 files changed, 478 insertions(+), 1 deletions(-) create mode 100644 block/add-cow.c create mode 100644 docs/specs/add-cow.txt diff --git a/Makefile.objs b/Makefile.objs index d7a6539..ad99243 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o +block-nested-y += add-cow.o block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o block-nested-y += qed-check.o block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o diff --git a/block.c b/block.c index 86910b0..a2be27b 100644 --- a/block.c +++ b/block.c @@ -106,7 +106,7 @@ int is_windows_drive(const char *filename) #endif /* check if the path starts with protocol: */ -static int path_has_protocol(const char *path) +int path_has_protocol(const char *path) { #ifdef _WIN32 if (is_windows_drive(path) || diff --git a/block.h b/block.h index 051a25d..836284f 100644 --- a/block.h +++ b/block.h @@ -276,6 +276,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn); char *get_human_readable_size(char *buf, int buf_size, int64_t size); int path_is_absolute(const char *path); +int path_has_protocol(const char *path); void path_combine(char *dest, int dest_size, const char *base_path, const char *filename); diff --git a/block/add-cow.c b/block/add-cow.c new file mode 100644 index 000..54d30a9 --- /dev/null +++ b/block/add-cow.c @@ -0,0 +1,417 @@ +#include qemu-common.h +#include block_int.h +#include module.h + +#define ADD_COW_MAGIC (((uint64_t)'A' 56) | ((uint64_t)'D' 48) | \ +((uint64_t)'D' 40) | ((uint64_t)'_' 32) | \ +((uint64_t)'C' 24) | ((uint64_t)'O' 16) | \ +((uint64_t)'W' 8) | 0xFF) +#define ADD_COW_VERSION 1 +#define ADD_COW_FILE_LEN1024 + +typedef struct AddCowHeader { +uint64_tmagic; +uint32_tversion; +charbacking_file[ADD_COW_FILE_LEN]; +charimage_file[ADD_COW_FILE_LEN]; +uint64_tsize; +} QEMU_PACKED AddCowHeader; + +typedef struct BDRVAddCowState { +charimage_file[ADD_COW_FILE_LEN]; +BlockDriverState*image_hd; +uint8_t *bitmap; +uint64_tbitmap_size; +CoMutex lock; +} BDRVAddCowState; + +static int add_cow_probe(const uint8_t *buf, int buf_size, const char *filename) +{ +const AddCowHeader *header = (const void *)buf; + +if (be64_to_cpu(header-magic) == ADD_COW_MAGIC +be32_to_cpu(header-version) == ADD_COW_VERSION) { +return 100; +} else { +return 0; +} +} + +static int add_cow_open(BlockDriverState *bs, int flags) +{ +AddCowHeaderheader; +int64_t size; +charimage_filename[ADD_COW_FILE_LEN]; +int image_flags; +BlockDriver *image_drv = NULL; +int ret; +BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque); + +ret = bdrv_pread(bs-file, 0, header, sizeof(header)); +if (ret != sizeof(header)) { +goto fail; +} + +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC || +be32_to_cpu(header.version) != ADD_COW_VERSION) { +ret = -EINVAL; +goto fail; +} + +size = be64_to_cpu(header.size); +bs-total_sectors = size / BDRV_SECTOR_SIZE; + +QEMU_BUILD_BUG_ON(sizeof(state-image_file) != sizeof(header.image_file)); +pstrcpy(bs-backing_file, sizeof(bs-backing_file), +header.backing_file); +pstrcpy(state-image_file, sizeof(state-image_file), +header.image_file); + +state-bitmap_size = ((bs-total_sectors + 7) 3); +state-bitmap = g_malloc0(state-bitmap_size); + +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap, +state-bitmap_size); +if (ret != state-bitmap_size) { +goto fail; +} Reading the entire bitmap in memory is not acceptable, it may be huge. Better mmap it and use msync(MS_SYNC) when writing it back. This way the host can free memory easily upon pressure. + /* If
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
Am 06.12.2011 13:48, schrieb Marcelo Tosatti: On Tue, Nov 15, 2011 at 01:28:51PM +0800, Dong Xu Wang wrote: From: Dong Xu Wang wdon...@linux.vnet.ibm.com Provide a new file format: add-cow. The usage can be found in add-cow.txt of this patch. Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com --- Makefile.objs |1 + block.c|2 +- block.h|1 + block/add-cow.c| 417 block_int.h|1 + docs/specs/add-cow.txt | 57 +++ 6 files changed, 478 insertions(+), 1 deletions(-) create mode 100644 block/add-cow.c create mode 100644 docs/specs/add-cow.txt diff --git a/Makefile.objs b/Makefile.objs index d7a6539..ad99243 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o +block-nested-y += add-cow.o block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o block-nested-y += qed-check.o block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o diff --git a/block.c b/block.c index 86910b0..a2be27b 100644 --- a/block.c +++ b/block.c @@ -106,7 +106,7 @@ int is_windows_drive(const char *filename) #endif /* check if the path starts with protocol: */ -static int path_has_protocol(const char *path) +int path_has_protocol(const char *path) { #ifdef _WIN32 if (is_windows_drive(path) || diff --git a/block.h b/block.h index 051a25d..836284f 100644 --- a/block.h +++ b/block.h @@ -276,6 +276,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn); char *get_human_readable_size(char *buf, int buf_size, int64_t size); int path_is_absolute(const char *path); +int path_has_protocol(const char *path); void path_combine(char *dest, int dest_size, const char *base_path, const char *filename); diff --git a/block/add-cow.c b/block/add-cow.c new file mode 100644 index 000..54d30a9 --- /dev/null +++ b/block/add-cow.c @@ -0,0 +1,417 @@ +#include qemu-common.h +#include block_int.h +#include module.h + +#define ADD_COW_MAGIC (((uint64_t)'A' 56) | ((uint64_t)'D' 48) | \ +((uint64_t)'D' 40) | ((uint64_t)'_' 32) | \ +((uint64_t)'C' 24) | ((uint64_t)'O' 16) | \ +((uint64_t)'W' 8) | 0xFF) +#define ADD_COW_VERSION 1 +#define ADD_COW_FILE_LEN1024 + +typedef struct AddCowHeader { +uint64_tmagic; +uint32_tversion; +charbacking_file[ADD_COW_FILE_LEN]; +charimage_file[ADD_COW_FILE_LEN]; +uint64_tsize; +} QEMU_PACKED AddCowHeader; + +typedef struct BDRVAddCowState { +charimage_file[ADD_COW_FILE_LEN]; +BlockDriverState*image_hd; +uint8_t *bitmap; +uint64_tbitmap_size; +CoMutex lock; +} BDRVAddCowState; + +static int add_cow_probe(const uint8_t *buf, int buf_size, const char *filename) +{ +const AddCowHeader *header = (const void *)buf; + +if (be64_to_cpu(header-magic) == ADD_COW_MAGIC +be32_to_cpu(header-version) == ADD_COW_VERSION) { +return 100; +} else { +return 0; +} +} + +static int add_cow_open(BlockDriverState *bs, int flags) +{ +AddCowHeaderheader; +int64_t size; +charimage_filename[ADD_COW_FILE_LEN]; +int image_flags; +BlockDriver *image_drv = NULL; +int ret; +BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque); + +ret = bdrv_pread(bs-file, 0, header, sizeof(header)); +if (ret != sizeof(header)) { +goto fail; +} + +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC || +be32_to_cpu(header.version) != ADD_COW_VERSION) { +ret = -EINVAL; +goto fail; +} + +size = be64_to_cpu(header.size); +bs-total_sectors = size / BDRV_SECTOR_SIZE; + +QEMU_BUILD_BUG_ON(sizeof(state-image_file) != sizeof(header.image_file)); +pstrcpy(bs-backing_file, sizeof(bs-backing_file), +header.backing_file); +pstrcpy(state-image_file, sizeof(state-image_file), +header.image_file); + +state-bitmap_size = ((bs-total_sectors + 7) 3); +state-bitmap = g_malloc0(state-bitmap_size); + +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap, +state-bitmap_size); +if (ret != state-bitmap_size) { +goto fail; +} Reading the entire bitmap in memory is not acceptable, it may be huge. Better mmap it and use msync(MS_SYNC) when writing it back. This way the host
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
Am 15.11.2011 06:28, schrieb Dong Xu Wang: From: Dong Xu Wang wdon...@linux.vnet.ibm.com Provide a new file format: add-cow. The usage can be found in add-cow.txt of this patch. Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com --- Makefile.objs |1 + block.c|2 +- block.h|1 + block/add-cow.c| 417 block_int.h|1 + docs/specs/add-cow.txt | 57 +++ 6 files changed, 478 insertions(+), 1 deletions(-) create mode 100644 block/add-cow.c create mode 100644 docs/specs/add-cow.txt diff --git a/Makefile.objs b/Makefile.objs index d7a6539..ad99243 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o +block-nested-y += add-cow.o block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o block-nested-y += qed-check.o block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o diff --git a/block.c b/block.c index 86910b0..a2be27b 100644 --- a/block.c +++ b/block.c @@ -106,7 +106,7 @@ int is_windows_drive(const char *filename) #endif /* check if the path starts with protocol: */ -static int path_has_protocol(const char *path) +int path_has_protocol(const char *path) { #ifdef _WIN32 if (is_windows_drive(path) || diff --git a/block.h b/block.h index 051a25d..836284f 100644 --- a/block.h +++ b/block.h @@ -276,6 +276,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn); char *get_human_readable_size(char *buf, int buf_size, int64_t size); int path_is_absolute(const char *path); +int path_has_protocol(const char *path); void path_combine(char *dest, int dest_size, const char *base_path, const char *filename); diff --git a/block/add-cow.c b/block/add-cow.c new file mode 100644 index 000..54d30a9 --- /dev/null +++ b/block/add-cow.c @@ -0,0 +1,417 @@ +#include qemu-common.h +#include block_int.h +#include module.h + +#define ADD_COW_MAGIC (((uint64_t)'A' 56) | ((uint64_t)'D' 48) | \ +((uint64_t)'D' 40) | ((uint64_t)'_' 32) | \ +((uint64_t)'C' 24) | ((uint64_t)'O' 16) | \ +((uint64_t)'W' 8) | 0xFF) +#define ADD_COW_VERSION 1 +#define ADD_COW_FILE_LEN1024 + +typedef struct AddCowHeader { +uint64_tmagic; +uint32_tversion; +charbacking_file[ADD_COW_FILE_LEN]; +charimage_file[ADD_COW_FILE_LEN]; +uint64_tsize; +} QEMU_PACKED AddCowHeader; + +typedef struct BDRVAddCowState { +charimage_file[ADD_COW_FILE_LEN]; +BlockDriverState*image_hd; +uint8_t *bitmap; +uint64_tbitmap_size; +CoMutex lock; +} BDRVAddCowState; + +static int add_cow_probe(const uint8_t *buf, int buf_size, const char *filename) +{ +const AddCowHeader *header = (const void *)buf; + +if (be64_to_cpu(header-magic) == ADD_COW_MAGIC +be32_to_cpu(header-version) == ADD_COW_VERSION) { +return 100; +} else { +return 0; +} +} + +static int add_cow_open(BlockDriverState *bs, int flags) +{ +AddCowHeaderheader; +int64_t size; +charimage_filename[ADD_COW_FILE_LEN]; +int image_flags; +BlockDriver *image_drv = NULL; +int ret; +BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque); + +ret = bdrv_pread(bs-file, 0, header, sizeof(header)); +if (ret != sizeof(header)) { +goto fail; +} + +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC || +be32_to_cpu(header.version) != ADD_COW_VERSION) { +ret = -EINVAL; +goto fail; +} Please have a look at qcow2 for better handling of newer version numbers. We should try to give a good error message for this case. + +size = be64_to_cpu(header.size); +bs-total_sectors = size / BDRV_SECTOR_SIZE; + +QEMU_BUILD_BUG_ON(sizeof(state-image_file) != sizeof(header.image_file)); +pstrcpy(bs-backing_file, sizeof(bs-backing_file), +header.backing_file); +pstrcpy(state-image_file, sizeof(state-image_file), +header.image_file); You need the same QEMU_BUILD_BUG_ON for the backing file, or you can't assume that header.image_file is large enough that it doesn't matter that it isn't necessarily correctly terminated. + +state-bitmap_size = ((bs-total_sectors + 7) 3); +state-bitmap = g_malloc0(state-bitmap_size); qemu_blockalign is better if you're using it as a buffer for
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote: + +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap, +state-bitmap_size); +if (ret != state-bitmap_size) { +goto fail; +} Reading the entire bitmap in memory is not acceptable, it may be huge. Better mmap it and use msync(MS_SYNC) when writing it back. This way the host can free memory easily upon pressure. You can't use mmap in block drivers. It would only work with raw-posix backends, if at all. Kevin This is just the bitmap, a plain file. Why would you want to use anything other than a plain file to use as storage for the bitmap?
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
On Tue, Dec 06, 2011 at 12:53:16PM -0200, Marcelo Tosatti wrote: On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote: + +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap, +state-bitmap_size); +if (ret != state-bitmap_size) { +goto fail; +} Reading the entire bitmap in memory is not acceptable, it may be huge. Better mmap it and use msync(MS_SYNC) when writing it back. This way the host can free memory easily upon pressure. You can't use mmap in block drivers. It would only work with raw-posix backends, if at all. Kevin This is just the bitmap, a plain file. Why would you want to use anything other than a plain file to use as storage for the bitmap? Well, mmap'ing would make life much simpler, but it has limitations such as portability. Then what is necessary is a cache similar to qcow2's metadata cache.
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
Am 06.12.2011 15:53, schrieb Marcelo Tosatti: On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote: + +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap, +state-bitmap_size); +if (ret != state-bitmap_size) { +goto fail; +} Reading the entire bitmap in memory is not acceptable, it may be huge. Better mmap it and use msync(MS_SYNC) when writing it back. This way the host can free memory easily upon pressure. You can't use mmap in block drivers. It would only work with raw-posix backends, if at all. This is just the bitmap, a plain file. Why would you want to use anything other than a plain file to use as storage for the bitmap? The obvious case is raw-win32. There are probably not so obvious, but still valid use cases that involve things like NBD, iSCSI, blkdebug or whatever. Kevin
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
Am 06.12.2011 16:06, schrieb Marcelo Tosatti: On Tue, Dec 06, 2011 at 12:53:16PM -0200, Marcelo Tosatti wrote: On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote: + +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap, +state-bitmap_size); +if (ret != state-bitmap_size) { +goto fail; +} Reading the entire bitmap in memory is not acceptable, it may be huge. Better mmap it and use msync(MS_SYNC) when writing it back. This way the host can free memory easily upon pressure. You can't use mmap in block drivers. It would only work with raw-posix backends, if at all. Kevin This is just the bitmap, a plain file. Why would you want to use anything other than a plain file to use as storage for the bitmap? Well, mmap'ing would make life much simpler, but it has limitations such as portability. Then what is necessary is a cache similar to qcow2's metadata cache. Right, we can probably generalise the qcow2 code and make it available for other drivers as well. Kevin
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
On Tue, Dec 06, 2011 at 04:20:55PM +0100, Kevin Wolf wrote: Am 06.12.2011 16:06, schrieb Marcelo Tosatti: On Tue, Dec 06, 2011 at 12:53:16PM -0200, Marcelo Tosatti wrote: On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote: + +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap, +state-bitmap_size); +if (ret != state-bitmap_size) { +goto fail; +} Reading the entire bitmap in memory is not acceptable, it may be huge. Better mmap it and use msync(MS_SYNC) when writing it back. This way the host can free memory easily upon pressure. You can't use mmap in block drivers. It would only work with raw-posix backends, if at all. Kevin This is just the bitmap, a plain file. Why would you want to use anything other than a plain file to use as storage for the bitmap? Well, mmap'ing would make life much simpler, but it has limitations such as portability. Then what is necessary is a cache similar to qcow2's metadata cache. Right, we can probably generalise the qcow2 code and make it available for other drivers as well. Hum, generalising sounds overly complicated (and there is a time constraint to this). IMHO a cache internal to add-cow.c just to avoid reading the entire bitmap would do the trick.
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
Am 06.12.2011 17:35, schrieb Marcelo Tosatti: On Tue, Dec 06, 2011 at 04:20:55PM +0100, Kevin Wolf wrote: Am 06.12.2011 16:06, schrieb Marcelo Tosatti: On Tue, Dec 06, 2011 at 12:53:16PM -0200, Marcelo Tosatti wrote: On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote: + +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap, +state-bitmap_size); +if (ret != state-bitmap_size) { +goto fail; +} Reading the entire bitmap in memory is not acceptable, it may be huge. Better mmap it and use msync(MS_SYNC) when writing it back. This way the host can free memory easily upon pressure. You can't use mmap in block drivers. It would only work with raw-posix backends, if at all. Kevin This is just the bitmap, a plain file. Why would you want to use anything other than a plain file to use as storage for the bitmap? Well, mmap'ing would make life much simpler, but it has limitations such as portability. Then what is necessary is a cache similar to qcow2's metadata cache. Right, we can probably generalise the qcow2 code and make it available for other drivers as well. Hum, generalising sounds overly complicated (and there is a time constraint to this). IMHO a cache internal to add-cow.c just to avoid reading the entire bitmap would do the trick. The cache is mostly self-contained. But maybe we should get the locking right (instead of always locking the whole BlockDriverState) before using it in more drivers. I think this might need some change to it. Kevin
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
On Tue, Dec 06, 2011 at 02:35:03PM -0200, Marcelo Tosatti wrote: Right, we can probably generalise the qcow2 code and make it available for other drivers as well. Hum, generalising sounds overly complicated (and there is a time constraint to this). IMHO a cache internal to add-cow.c just to avoid reading the entire bitmap would do the trick. (and writes must go through the cache too, of course).
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
Ping... 2011/11/28 Dong Xu Wang wdon...@linux.vnet.ibm.com Any comment? Thanks. 2011/11/15 Dong Xu Wang wdon...@linux.vnet.ibm.com From: Dong Xu Wang wdon...@linux.vnet.ibm.com Provide a new file format: add-cow. The usage can be found in add-cow.txt of this patch. Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com --- Makefile.objs |1 + block.c|2 +- block.h|1 + block/add-cow.c| 417 block_int.h|1 + docs/specs/add-cow.txt | 57 +++ 6 files changed, 478 insertions(+), 1 deletions(-) create mode 100644 block/add-cow.c create mode 100644 docs/specs/add-cow.txt diff --git a/Makefile.objs b/Makefile.objs index d7a6539..ad99243 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o +block-nested-y += add-cow.o block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o block-nested-y += qed-check.o block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o diff --git a/block.c b/block.c index 86910b0..a2be27b 100644 --- a/block.c +++ b/block.c @@ -106,7 +106,7 @@ int is_windows_drive(const char *filename) #endif /* check if the path starts with protocol: */ -static int path_has_protocol(const char *path) +int path_has_protocol(const char *path) { #ifdef _WIN32 if (is_windows_drive(path) || diff --git a/block.h b/block.h index 051a25d..836284f 100644 --- a/block.h +++ b/block.h @@ -276,6 +276,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn); char *get_human_readable_size(char *buf, int buf_size, int64_t size); int path_is_absolute(const char *path); +int path_has_protocol(const char *path); void path_combine(char *dest, int dest_size, const char *base_path, const char *filename); diff --git a/block/add-cow.c b/block/add-cow.c new file mode 100644 index 000..54d30a9 --- /dev/null +++ b/block/add-cow.c @@ -0,0 +1,417 @@ +#include qemu-common.h +#include block_int.h +#include module.h + +#define ADD_COW_MAGIC (((uint64_t)'A' 56) | ((uint64_t)'D' 48) | \ +((uint64_t)'D' 40) | ((uint64_t)'_' 32) | \ +((uint64_t)'C' 24) | ((uint64_t)'O' 16) | \ +((uint64_t)'W' 8) | 0xFF) +#define ADD_COW_VERSION 1 +#define ADD_COW_FILE_LEN1024 + +typedef struct AddCowHeader { +uint64_tmagic; +uint32_tversion; +charbacking_file[ADD_COW_FILE_LEN]; +charimage_file[ADD_COW_FILE_LEN]; +uint64_tsize; +} QEMU_PACKED AddCowHeader; + +typedef struct BDRVAddCowState { +charimage_file[ADD_COW_FILE_LEN]; +BlockDriverState*image_hd; +uint8_t *bitmap; +uint64_tbitmap_size; +CoMutex lock; +} BDRVAddCowState; + +static int add_cow_probe(const uint8_t *buf, int buf_size, const char *filename) +{ +const AddCowHeader *header = (const void *)buf; + +if (be64_to_cpu(header-magic) == ADD_COW_MAGIC +be32_to_cpu(header-version) == ADD_COW_VERSION) { +return 100; +} else { +return 0; +} +} + +static int add_cow_open(BlockDriverState *bs, int flags) +{ +AddCowHeaderheader; +int64_t size; +charimage_filename[ADD_COW_FILE_LEN]; +int image_flags; +BlockDriver *image_drv = NULL; +int ret; +BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque); + +ret = bdrv_pread(bs-file, 0, header, sizeof(header)); +if (ret != sizeof(header)) { +goto fail; +} + +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC || +be32_to_cpu(header.version) != ADD_COW_VERSION) { +ret = -EINVAL; +goto fail; +} + +size = be64_to_cpu(header.size); +bs-total_sectors = size / BDRV_SECTOR_SIZE; + +QEMU_BUILD_BUG_ON(sizeof(state-image_file) != sizeof(header.image_file)); +pstrcpy(bs-backing_file, sizeof(bs-backing_file), +header.backing_file); +pstrcpy(state-image_file, sizeof(state-image_file), +header.image_file); + +state-bitmap_size = ((bs-total_sectors + 7) 3); +state-bitmap = g_malloc0(state-bitmap_size); + +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap, +state-bitmap_size); +if (ret != state-bitmap_size) { +goto fail; +} + /* If there is a image_file, must be together with backing_file */ +if (state-image_file[0] != '\0') { +state-image_hd =
Re: [Qemu-devel] [PATCH v5] block:add-cow file format
Any comment? Thanks. 2011/11/15 Dong Xu Wang wdon...@linux.vnet.ibm.com From: Dong Xu Wang wdon...@linux.vnet.ibm.com Provide a new file format: add-cow. The usage can be found in add-cow.txt of this patch. Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com --- Makefile.objs |1 + block.c|2 +- block.h|1 + block/add-cow.c| 417 block_int.h|1 + docs/specs/add-cow.txt | 57 +++ 6 files changed, 478 insertions(+), 1 deletions(-) create mode 100644 block/add-cow.c create mode 100644 docs/specs/add-cow.txt diff --git a/Makefile.objs b/Makefile.objs index d7a6539..ad99243 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o +block-nested-y += add-cow.o block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o block-nested-y += qed-check.o block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o diff --git a/block.c b/block.c index 86910b0..a2be27b 100644 --- a/block.c +++ b/block.c @@ -106,7 +106,7 @@ int is_windows_drive(const char *filename) #endif /* check if the path starts with protocol: */ -static int path_has_protocol(const char *path) +int path_has_protocol(const char *path) { #ifdef _WIN32 if (is_windows_drive(path) || diff --git a/block.h b/block.h index 051a25d..836284f 100644 --- a/block.h +++ b/block.h @@ -276,6 +276,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn); char *get_human_readable_size(char *buf, int buf_size, int64_t size); int path_is_absolute(const char *path); +int path_has_protocol(const char *path); void path_combine(char *dest, int dest_size, const char *base_path, const char *filename); diff --git a/block/add-cow.c b/block/add-cow.c new file mode 100644 index 000..54d30a9 --- /dev/null +++ b/block/add-cow.c @@ -0,0 +1,417 @@ +#include qemu-common.h +#include block_int.h +#include module.h + +#define ADD_COW_MAGIC (((uint64_t)'A' 56) | ((uint64_t)'D' 48) | \ +((uint64_t)'D' 40) | ((uint64_t)'_' 32) | \ +((uint64_t)'C' 24) | ((uint64_t)'O' 16) | \ +((uint64_t)'W' 8) | 0xFF) +#define ADD_COW_VERSION 1 +#define ADD_COW_FILE_LEN1024 + +typedef struct AddCowHeader { +uint64_tmagic; +uint32_tversion; +charbacking_file[ADD_COW_FILE_LEN]; +charimage_file[ADD_COW_FILE_LEN]; +uint64_tsize; +} QEMU_PACKED AddCowHeader; + +typedef struct BDRVAddCowState { +charimage_file[ADD_COW_FILE_LEN]; +BlockDriverState*image_hd; +uint8_t *bitmap; +uint64_tbitmap_size; +CoMutex lock; +} BDRVAddCowState; + +static int add_cow_probe(const uint8_t *buf, int buf_size, const char *filename) +{ +const AddCowHeader *header = (const void *)buf; + +if (be64_to_cpu(header-magic) == ADD_COW_MAGIC +be32_to_cpu(header-version) == ADD_COW_VERSION) { +return 100; +} else { +return 0; +} +} + +static int add_cow_open(BlockDriverState *bs, int flags) +{ +AddCowHeaderheader; +int64_t size; +charimage_filename[ADD_COW_FILE_LEN]; +int image_flags; +BlockDriver *image_drv = NULL; +int ret; +BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque); + +ret = bdrv_pread(bs-file, 0, header, sizeof(header)); +if (ret != sizeof(header)) { +goto fail; +} + +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC || +be32_to_cpu(header.version) != ADD_COW_VERSION) { +ret = -EINVAL; +goto fail; +} + +size = be64_to_cpu(header.size); +bs-total_sectors = size / BDRV_SECTOR_SIZE; + +QEMU_BUILD_BUG_ON(sizeof(state-image_file) != sizeof(header.image_file)); +pstrcpy(bs-backing_file, sizeof(bs-backing_file), +header.backing_file); +pstrcpy(state-image_file, sizeof(state-image_file), +header.image_file); + +state-bitmap_size = ((bs-total_sectors + 7) 3); +state-bitmap = g_malloc0(state-bitmap_size); + +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap, +state-bitmap_size); +if (ret != state-bitmap_size) { +goto fail; +} + /* If there is a image_file, must be together with backing_file */ +if (state-image_file[0] != '\0') { +state-image_hd = bdrv_new(); + +if (path_has_protocol(state-image_file))