[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1 of 8 RESEND] blktap3/vhd: Introduce VHD-relatred headers
This patch adds the vhd.h and libvhd.h header files related to VHD manipulation. They are based on blktap2, with most changes coming from blktap2.5, with some additional clean up. Signed-off-by: Thanos Makatos <thanos.makatos@xxxxxxxxxx> diff --git a/tools/blktap2/include/libvhd.h b/tools/blktap3/include/libvhd.h copy from tools/blktap2/include/libvhd.h copy to tools/blktap3/include/libvhd.h --- a/tools/blktap2/include/libvhd.h +++ b/tools/blktap3/include/libvhd.h @@ -1,4 +1,5 @@ /* Copyright (c) 2008, XenSource Inc. + * Copyright (c) 2010, Citrix Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,48 +29,31 @@ #define _VHD_LIB_H_ #include <string.h> -#if defined(__linux__) #include <endian.h> #include <byteswap.h> -#elif defined(__NetBSD__) -#include <sys/endian.h> -#include <sys/bswap.h> +#include <uuid/uuid.h> +#include <sys/param.h> +#include "blktap3.h" + +#if BYTE_ORDER == LITTLE_ENDIAN +#define BE16_IN(foo) (*(foo)) = bswap_16(*(foo)) +#define BE32_IN(foo) (*(foo)) = bswap_32(*(foo)) +#define BE64_IN(foo) (*(foo)) = bswap_64(*(foo)) +#define BE16_OUT(foo) (*(foo)) = bswap_16(*(foo)) +#define BE32_OUT(foo) (*(foo)) = bswap_32(*(foo)) +#define BE64_OUT(foo) (*(foo)) = bswap_64(*(foo)) +#else +#define BE16_IN(foo) +#define BE32_IN(foo) +#define BE64_IN(foo) +#define BE32_OUT(foo) +#define BE32_OUT(foo) +#define BE64_OUT(foo) #endif -#include "vhd-uuid.h" #include "vhd.h" -#ifndef O_LARGEFILE -#define O_LARGEFILE 0 -#endif - -#if BYTE_ORDER == LITTLE_ENDIAN -#if defined(__linux__) - #define BE16_IN(foo) (*(foo)) = bswap_16(*(foo)) - #define BE32_IN(foo) (*(foo)) = bswap_32(*(foo)) - #define BE64_IN(foo) (*(foo)) = bswap_64(*(foo)) - #define BE16_OUT(foo) (*(foo)) = bswap_16(*(foo)) - #define BE32_OUT(foo) (*(foo)) = bswap_32(*(foo)) - #define BE64_OUT(foo) (*(foo)) = bswap_64(*(foo)) -#elif defined(__NetBSD__) - #define BE16_IN(foo) (*(foo)) = bswap16(*(foo)) - #define BE32_IN(foo) (*(foo)) = bswap32(*(foo)) - #define BE64_IN(foo) (*(foo)) = bswap64(*(foo)) - #define BE16_OUT(foo) (*(foo)) = bswap16(*(foo)) - #define BE32_OUT(foo) (*(foo)) = bswap32(*(foo)) - #define BE64_OUT(foo) (*(foo)) = bswap64(*(foo)) -#endif -#else - #define BE16_IN(foo) - #define BE32_IN(foo) - #define BE64_IN(foo) - #define BE32_OUT(foo) - #define BE32_OUT(foo) - #define BE64_OUT(foo) -#endif - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define BIT_MASK 0x80 #define VHD_MAX_NAME_LEN 1024 @@ -85,8 +69,11 @@ #define VHD_OPEN_FAST 0x00004 #define VHD_OPEN_STRICT 0x00008 #define VHD_OPEN_IGNORE_DISABLED 0x00010 +#define VHD_OPEN_CACHED 0x00020 +#define VHD_OPEN_IO_WRITE_SPARSE 0x00040 -#define VHD_FLAG_CREAT_PARENT_RAW 0x00001 +#define VHD_FLAG_CREAT_FILE_SIZE_FIXED 0x00001 +#define VHD_FLAG_CREAT_PARENT_RAW 0x00002 #define vhd_flag_set(word, flag) ((word) |= (flag)) #define vhd_flag_clear(word, flag) ((word) &= ~(flag)) @@ -103,6 +90,9 @@ #define FAIL_RESIZE_END 6 #define NUM_FAIL_TESTS 7 +/* + * TODO check whether this is still valid + */ #ifdef ENABLE_FAILURE_TESTING #define TEST_FAIL_AT(point) \ if (TEST_FAIL[point]) { \ @@ -138,6 +128,7 @@ struct vhd_batmap { char *map; }; +TAILQ_HEAD(tq_vhd_ctx, vhd_context); struct vhd_context { int fd; char *file; @@ -151,8 +142,25 @@ struct vhd_context { vhd_footer_t footer; vhd_bat_t bat; vhd_batmap_t batmap; + + struct vhd_context *parent; }; +static inline int test_bit(volatile char *addr, int nr) +{ + return ((addr[nr >> 3] << (nr & 7)) & BIT_MASK) != 0; +} + +static inline void set_bit(volatile char *addr, int nr) +{ + addr[nr >> 3] |= (BIT_MASK >> (nr & 7)); +} + +static inline void clear_bit(volatile char *addr, int nr) +{ + addr[nr >> 3] &= ~(BIT_MASK >> (nr & 7)); +} + static inline uint32_t secs_round_up(uint64_t bytes) { @@ -216,7 +224,7 @@ vhd_parent_locator_size(vhd_parent_locat static inline int vhd_parent_raw(vhd_context_t *ctx) { - return vhd_uuid_is_nil(&ctx->header.prt_uuid); + return uuid_is_null(ctx->header.prt_uuid); } void libvhd_set_log_level(int); @@ -229,7 +237,7 @@ uint32_t vhd_chs(uint64_t size); uint32_t vhd_checksum_footer(vhd_footer_t *); uint32_t vhd_checksum_header(vhd_header_t *); -uint32_t vhd_checksum_batmap(vhd_batmap_t *); +uint32_t vhd_checksum_batmap(vhd_context_t *, vhd_batmap_t *); void vhd_footer_in(vhd_footer_t *); void vhd_footer_out(vhd_footer_t *); @@ -243,30 +251,36 @@ void vhd_batmap_header_out(vhd_batmap_t int vhd_validate_footer(vhd_footer_t *footer); int vhd_validate_header(vhd_header_t *header); int vhd_validate_batmap_header(vhd_batmap_t *batmap); -int vhd_validate_batmap(vhd_batmap_t *batmap); +int vhd_validate_batmap(vhd_context_t *, vhd_batmap_t *batmap); int vhd_validate_platform_code(uint32_t code); int vhd_open(vhd_context_t *, const char *file, int flags); void vhd_close(vhd_context_t *); -int vhd_create(const char *name, uint64_t bytes, int type, vhd_flag_creat_t); +/* vhd_create: mbytes is the virtual size for BAT/batmap preallocation - see + * vhd-util-resize.c + */ +int vhd_create(const char *name, uint64_t bytes, int type, uint64_t mbytes, + vhd_flag_creat_t); /* vhd_snapshot: the bytes parameter is optional and can be 0 if the snapshot * is to have the same size as the (first non-empty) parent */ int vhd_snapshot(const char *snapshot, uint64_t bytes, const char *parent, - vhd_flag_creat_t); + uint64_t mbytes, vhd_flag_creat_t); int vhd_hidden(vhd_context_t *, int *); int vhd_chain_depth(vhd_context_t *, int *); +int vhd_marker(vhd_context_t *, char *); +int vhd_set_marker(vhd_context_t *, char); -off_t vhd_position(vhd_context_t *); -int vhd_seek(vhd_context_t *, off_t, int); +off64_t vhd_position(vhd_context_t *); +int vhd_seek(vhd_context_t *, off64_t, int); int vhd_read(vhd_context_t *, void *, size_t); int vhd_write(vhd_context_t *, void *, size_t); int vhd_offset(vhd_context_t *, uint32_t, uint32_t *); -int vhd_end_of_headers(vhd_context_t *ctx, off_t *off); -int vhd_end_of_data(vhd_context_t *ctx, off_t *off); -int vhd_batmap_header_offset(vhd_context_t *ctx, off_t *off); +int vhd_end_of_headers(vhd_context_t *ctx, off64_t *off); +int vhd_end_of_data(vhd_context_t *ctx, off64_t *off); +int vhd_batmap_header_offset(vhd_context_t *ctx, off64_t *off); int vhd_get_header(vhd_context_t *); int vhd_get_footer(vhd_context_t *); @@ -283,38 +297,45 @@ int vhd_batmap_test(vhd_context_t *, vhd void vhd_batmap_set(vhd_context_t *, vhd_batmap_t *, uint32_t); void vhd_batmap_clear(vhd_context_t *, vhd_batmap_t *, uint32_t); -int vhd_get_phys_size(vhd_context_t *, off_t *); -int vhd_set_phys_size(vhd_context_t *, off_t); +int vhd_file_size_fixed(vhd_context_t *); +int vhd_get_phys_size(vhd_context_t *, off64_t *); +int vhd_set_phys_size(vhd_context_t *, off64_t); +int vhd_set_virt_size(vhd_context_t *, uint64_t); int vhd_bitmap_test(vhd_context_t *, char *, uint32_t); void vhd_bitmap_set(vhd_context_t *, char *, uint32_t); void vhd_bitmap_clear(vhd_context_t *, char *, uint32_t); +int vhd_initialize_header_parent_name(vhd_context_t *, const char *); +int vhd_write_parent_locators(vhd_context_t *, const char *); int vhd_parent_locator_count(vhd_context_t *); int vhd_parent_locator_get(vhd_context_t *, char **); -int vhd_parent_locator_read(vhd_context_t *, vhd_parent_locator_t *, char **); +int vhd_parent_locator_read(vhd_context_t *, vhd_parent_locator_t *, + char **); int vhd_find_parent(vhd_context_t *, const char *, char **); int vhd_parent_locator_write_at(vhd_context_t *, const char *, - off_t, uint32_t, size_t, + off64_t, uint32_t, size_t, vhd_parent_locator_t *); int vhd_header_decode_parent(vhd_context_t *, vhd_header_t *, char **); int vhd_change_parent(vhd_context_t *, char *parent_path, int raw); +int vhd_macx_encode_location(char *name, char **out, int *outlen); +int vhd_w2u_encode_location(char *name, char **out, int *outlen); int vhd_read_footer(vhd_context_t *, vhd_footer_t *); -int vhd_read_footer_at(vhd_context_t *, vhd_footer_t *, off_t); +int vhd_read_footer_at(vhd_context_t *, vhd_footer_t *, off64_t); int vhd_read_footer_strict(vhd_context_t *, vhd_footer_t *); int vhd_read_header(vhd_context_t *, vhd_header_t *); -int vhd_read_header_at(vhd_context_t *, vhd_header_t *, off_t); +int vhd_read_header_at(vhd_context_t *, vhd_header_t *, off64_t); int vhd_read_bat(vhd_context_t *, vhd_bat_t *); int vhd_read_batmap(vhd_context_t *, vhd_batmap_t *); int vhd_read_bitmap(vhd_context_t *, uint32_t block, char **bufp); int vhd_read_block(vhd_context_t *, uint32_t block, char **bufp); int vhd_write_footer(vhd_context_t *, vhd_footer_t *); -int vhd_write_footer_at(vhd_context_t *, vhd_footer_t *, off_t); +int vhd_write_footer_at(vhd_context_t *, vhd_footer_t *, off64_t); int vhd_write_header(vhd_context_t *, vhd_header_t *); -int vhd_write_header_at(vhd_context_t *, vhd_header_t *, off_t); +int vhd_write_header_at(vhd_context_t *, vhd_header_t *, off64_t); int vhd_write_bat(vhd_context_t *, vhd_bat_t *); int vhd_write_batmap(vhd_context_t *, vhd_batmap_t *); int vhd_write_bitmap(vhd_context_t *, uint32_t block, char *bitmap); @@ -322,5 +343,7 @@ int vhd_write_block(vhd_context_t *, uin int vhd_io_read(vhd_context_t *, char *, uint64_t, uint32_t); int vhd_io_write(vhd_context_t *, char *, uint64_t, uint32_t); +int vhd_io_read_bytes(vhd_context_t *, void *, size_t, uint64_t); +int vhd_io_write_bytes(vhd_context_t *, void *, size_t, uint64_t); #endif diff --git a/tools/blktap2/include/vhd.h b/tools/blktap3/include/vhd.h copy from tools/blktap2/include/vhd.h copy to tools/blktap3/include/vhd.h --- a/tools/blktap2/include/vhd.h +++ b/tools/blktap3/include/vhd.h @@ -1,4 +1,5 @@ /* Copyright (c) 2008, XenSource Inc. + * Copyright (c) 2010, Citrix Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,13 +25,12 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #ifndef __VHD_H__ #define __VHD_H__ #include <inttypes.h> - -typedef uint32_t u32; -typedef uint64_t u64; +#include <uuid/uuid.h> #define DEBUG 1 @@ -41,28 +41,94 @@ typedef uint64_t u64; #define VHD_SECTOR_SIZE 512 #define VHD_SECTOR_SHIFT 9 -/* ---------------------------------------------------------------------- */ -/* This is the generic disk footer, used by all disks. */ -/* ---------------------------------------------------------------------- */ +/** + * This is the generic disk footer, used by all disks. + */ +struct hd_ftr { + /** + * Identifies original creator of the disk + */ + char cookie[8]; -struct hd_ftr { - char cookie[8]; /* Identifies original creator of the disk */ - u32 features; /* Feature Support -- see below */ - u32 ff_version; /* (major,minor) version of disk file */ - u64 data_offset; /* Abs. offset from SOF to next structure */ - u32 timestamp; /* Creation time. secs since 1/1/2000GMT */ - char crtr_app[4]; /* Creator application */ - u32 crtr_ver; /* Creator version (major,minor) */ - u32 crtr_os; /* Creator host OS */ - u64 orig_size; /* Size at creation (bytes) */ - u64 curr_size; /* Current size of disk (bytes) */ - u32 geometry; /* Disk geometry */ - u32 type; /* Disk type */ - u32 checksum; /* 1's comp sum of this struct. */ - vhd_uuid_t uuid; /* Unique disk ID, used for naming parents */ - char saved; /* one-bit -- is this disk/VM in a saved state? */ - char hidden; /* tapdisk-specific field: is this vdi hidden? */ - char reserved[426]; /* padding */ + /** + * Feature Support -- see below + */ + uint32_t features; + + /** + * (major,minor) version of disk file + */ + uint32_t ff_version; + + /** + * Abs. offset from SOF to next structure + */ + uint64_t data_offset; + + /** + * Creation time. secs since 1/1/2000GMT + */ + uint32_t timestamp; + + /** + * Creator application + */ + char crtr_app[4]; + + /** + * Creator version (major,minor) + */ + uint32_t crtr_ver; + + /** + * Creator host OS + */ + uint32_t crtr_os; + + /** + * Size at creation (bytes) + */ + uint64_t orig_size; + + /** + * Current size of disk (bytes) + */ + uint64_t curr_size; + + /** + * Disk geometry + */ + uint32_t geometry; + + /** + * Disk type + */ + uint32_t type; + + /** + * 1's comp sum of this struct. + */ + uint32_t checksum; + + /** + * Unique disk ID, used for naming parents + */ + uuid_t uuid; + + /** + * one-bit -- is this disk/VM in a saved state? + */ + char saved; + + /** + * tapdisk-specific field: is this vdi hidden? + */ + char hidden; + + /** + * padding + */ + char reserved[426]; }; /* VHD cookie string. */ @@ -104,26 +170,33 @@ static const char HD_COOKIE[9] = "cone #define HD_TYPE_FIXED 2 /* fixed-allocation disk */ #define HD_TYPE_DYNAMIC 3 /* dynamic disk */ #define HD_TYPE_DIFF 4 /* differencing disk */ - -/* String table for hd.type */ -static const char *HD_TYPE_STR[7] = { - "None", /* 0 */ - "Reserved (deprecated)", /* 1 */ - "Fixed hard disk", /* 2 */ - "Dynamic hard disk", /* 3 */ - "Differencing hard disk", /* 4 */ - "Reserved (deprecated)", /* 5 */ - "Reserved (deprecated)" /* 6 */ -}; - #define HD_TYPE_MAX 6 struct prt_loc { - u32 code; /* Platform code -- see defines below. */ - u32 data_space; /* Number of 512-byte sectors to store locator */ - u32 data_len; /* Actual length of parent locator in bytes */ - u32 res; /* Must be zero */ - u64 data_offset; /* Absolute offset of locator data (bytes) */ + /** + * Platform code -- see defines below. + */ + uint32_t code; + + /** + * Number of 512-byte sectors to store locator + */ + uint32_t data_space; + + /** + * Actual length of parent locator in bytes + */ + uint32_t data_len; + + /** + * Must be zero + */ + uint32_t res; + + /** + * Absolute offset of locator data (bytes) + */ + uint64_t data_offset; }; /* Platform Codes */ @@ -135,24 +208,74 @@ struct prt_loc { #define PLAT_CODE_MAC 0x4D616320 /* MacOS alias stored as a blob. */ #define PLAT_CODE_MACX 0x4D616358 /* File URL (UTF-8), see RFC 2396. */ -/* ---------------------------------------------------------------------- */ -/* This is the dynamic disk header. */ -/* ---------------------------------------------------------------------- */ +/** + * This is the dynamic disk header. + */ +struct dd_hdr { + /** + * Should contain "cxsparse" + */ + char cookie[8]; -struct dd_hdr { - char cookie[8]; /* Should contain "cxsparse" */ - u64 data_offset; /* Byte offset of next record. (Unused) 0xffs */ - u64 table_offset; /* Absolute offset to the BAT. */ - u32 hdr_ver; /* Version of the dd_hdr (major,minor) */ - u32 max_bat_size; /* Maximum number of entries in the BAT */ - u32 block_size; /* Block size in bytes. Must be power of 2. */ - u32 checksum; /* Header checksum. 1's comp of all fields. */ - vhd_uuid_t prt_uuid; /* ID of the parent disk. */ - u32 prt_ts; /* Modification time of the parent disk */ - u32 res1; /* Reserved. */ - char prt_name[512]; /* Parent unicode name. */ - struct prt_loc loc[8]; /* Parent locator entries. */ - char res2[256]; /* Reserved. */ + /** + * Byte offset of next record. (Unused) 0xffs + */ + uint64_t data_offset; + + /** + * Absolute offset to the BAT + */ + uint64_t table_offset; + + /** + * Version of the dd_hdr (major,minor) + */ + uint32_t hdr_ver; + + /** + * Maximum number of entries in the BAT + */ + uint32_t max_bat_size; + + /** + * Block size in bytes. Must be power of 2. + */ + uint32_t block_size; + + /** + * Header checksum. 1's comp of all fields. + */ + uint32_t checksum; + + /** + * ID of the parent disk. + */ + uuid_t prt_uuid; + + /** + * Modification time of the parent disk + */ + uint32_t prt_ts; + + /** + * Reserved. + */ + uint32_t res1; + + /** + * Parent unicode name. + */ + char prt_name[512]; + + /** + * Parent locator entries. + */ + struct prt_loc loc[8]; + + /** + * Reserved. + */ + char res2[256]; }; /* VHD cookie string. */ @@ -167,11 +290,35 @@ static const char DD_COOKIE[9] = "cxsp #define DD_BLK_UNUSED 0xFFFFFFFF struct dd_batmap_hdr { - char cookie[8]; /* should contain "tdbatmap" */ - u64 batmap_offset; /* byte offset to batmap */ - u32 batmap_size; /* batmap size in sectors */ - u32 batmap_version; /* version of batmap */ - u32 checksum; /* batmap checksum -- 1's complement of batmap */ + /** + * should contain "tdbatmap" + */ + char cookie[8]; + + /** + * byte offset to batmap + */ + uint64_t batmap_offset; + + /** + * batmap size in sectors + */ + uint32_t batmap_size; + + /** + * version of batmap + */ + uint32_t batmap_version; + + /** + * batmap checksum -- 1's complement of batmap + */ + uint32_t checksum; + + /** + * generic marker field + */ + char marker; }; static const char VHD_BATMAP_COOKIE[9] = "tdbatmap"; @@ -180,6 +327,7 @@ static const char VHD_BATMAP_COOKIE[9] = * version 1.1: signed char checksum */ #define VHD_BATMAP_VERSION(major, minor) (((major) << 16) | ((minor) & 0x0000FFFF)) + #define VHD_BATMAP_CURRENT_VERSION VHD_BATMAP_VERSION(1, 2) /* Layout of a dynamic disk: @@ -191,7 +339,7 @@ static const char VHD_BATMAP_COOKIE[9] = * +-------------------------------------------------+ * | BAT (Block allocation table) | * | - Array of absolute sector offsets into the | - * | file (u32). | + * | file (uint32_t). | * | - Rounded up to a sector boundary. | * | - Unused entries are marked as 0xFFFFFFFF | * | - max entries in dd_hdr->max_bat_size | _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |