[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.