1 /* Copyright (c) 2008, XenSource Inc.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above copyright
9  *       notice, this list of conditions and the following disclaimer in the
10  *       documentation and/or other materials provided with the distribution.
11  *     * Neither the name of XenSource Inc. nor the names of its contributors
12  *       may be used to endorse or promote products derived from this software
13  *       without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 #ifndef __VHD_H__
28 #define __VHD_H__
29 
30 #include <inttypes.h>
31 
32 typedef uint32_t u32;
33 typedef uint64_t u64;
34 
35 #define DEBUG 1
36 
37 /* ---------------------------------------------------------------------- */
38 /* General definitions.                                                   */
39 /* ---------------------------------------------------------------------- */
40 
41 #define VHD_SECTOR_SIZE  512
42 #define VHD_SECTOR_SHIFT   9
43 
44 /* ---------------------------------------------------------------------- */
45 /* This is the generic disk footer, used by all disks.                    */
46 /* ---------------------------------------------------------------------- */
47 
48 struct hd_ftr {
49   char   cookie[8];       /* Identifies original creator of the disk      */
50   u32    features;        /* Feature Support -- see below                 */
51   u32    ff_version;      /* (major,minor) version of disk file           */
52   u64    data_offset;     /* Abs. offset from SOF to next structure       */
53   u32    timestamp;       /* Creation time.  secs since 1/1/2000GMT       */
54   char   crtr_app[4];     /* Creator application                          */
55   u32    crtr_ver;        /* Creator version (major,minor)                */
56   u32    crtr_os;         /* Creator host OS                              */
57   u64    orig_size;       /* Size at creation (bytes)                     */
58   u64    curr_size;       /* Current size of disk (bytes)                 */
59   u32    geometry;        /* Disk geometry                                */
60   u32    type;            /* Disk type                                    */
61   u32    checksum;        /* 1's comp sum of this struct.                 */
62   vhd_uuid_t uuid;        /* Unique disk ID, used for naming parents      */
63   char   saved;           /* one-bit -- is this disk/VM in a saved state? */
64   char   hidden;          /* tapdisk-specific field: is this vdi hidden?  */
65   char   reserved[426];   /* padding                                      */
66 };
67 
68 /* VHD cookie string. */
69 static const char HD_COOKIE[9]  =  "conectix";
70 
71 /* Feature fields in hd_ftr */
72 #define HD_NO_FEATURES     0x00000000
73 #define HD_TEMPORARY       0x00000001 /* disk can be deleted on shutdown */
74 #define HD_RESERVED        0x00000002 /* NOTE: must always be set        */
75 
76 /* Version field in hd_ftr */
77 #define HD_FF_VERSION      0x00010000
78 
79 /* Known creator OS type fields in hd_ftr.crtr_os */
80 #define HD_CR_OS_WINDOWS   0x5769326B /* (Wi2k) */
81 #define HD_CR_OS_MACINTOSH 0x4D616320 /* (Mac ) */
82 
83 /*
84  * version 0.1:  little endian bitmaps
85  * version 1.1:  big endian bitmaps; batmap
86  * version 1.2:  libvhd
87  * version 1.3:  batmap version bump to 1.2
88  */
89 #define VHD_VERSION(major, minor)  (((major) << 16) | ((minor) & 0x0000FFFF))
90 #define VHD_CURRENT_VERSION        VHD_VERSION(1, 3)
91 
92 /* Disk geometry accessor macros. */
93 /* Geometry is a triple of (cylinders (2 bytes), tracks (1 byte), and
94  * secotrs-per-track (1 byte))
95  */
96 #define GEOM_GET_CYLS(_g)  (((_g) >> 16) & 0xffff)
97 #define GEOM_GET_HEADS(_g) (((_g) >> 8)  & 0xff)
98 #define GEOM_GET_SPT(_g)   ((_g) & 0xff)
99 
100 #define GEOM_ENCODE(_c, _h, _s) (((_c) << 16) | ((_h) << 8) | (_s))
101 
102 /* type field in hd_ftr */
103 #define HD_TYPE_NONE       0
104 #define HD_TYPE_FIXED      2  /* fixed-allocation disk */
105 #define HD_TYPE_DYNAMIC    3  /* dynamic disk */
106 #define HD_TYPE_DIFF       4  /* differencing disk */
107 
108 /* String table for hd.type */
109 static const char *HD_TYPE_STR[7] = {
110         "None",                    /* 0 */
111         "Reserved (deprecated)",   /* 1 */
112         "Fixed hard disk",         /* 2 */
113         "Dynamic hard disk",       /* 3 */
114         "Differencing hard disk",  /* 4 */
115         "Reserved (deprecated)",   /* 5 */
116         "Reserved (deprecated)"    /* 6 */
117 };
118 
119 #define HD_TYPE_MAX 6
120 
121 struct prt_loc {
122   u32    code;            /* Platform code -- see defines below.          */
123   u32    data_space;      /* Number of 512-byte sectors to store locator  */
124   u32    data_len;        /* Actual length of parent locator in bytes     */
125   u32    res;             /* Must be zero                                 */
126   u64    data_offset;     /* Absolute offset of locator data (bytes)      */
127 };
128 
129 /* Platform Codes */
130 #define PLAT_CODE_NONE  0x0
131 #define PLAT_CODE_WI2R  0x57693272  /* deprecated                         */
132 #define PLAT_CODE_WI2K  0x5769326B  /* deprecated                         */
133 #define PLAT_CODE_W2RU  0x57327275  /* Windows relative path (UTF-16)     */
134 #define PLAT_CODE_W2KU  0x57326B75  /* Windows absolute path (UTF-16)     */
135 #define PLAT_CODE_MAC   0x4D616320  /* MacOS alias stored as a blob.      */
136 #define PLAT_CODE_MACX  0x4D616358  /* File URL (UTF-8), see RFC 2396.    */
137 
138 /* ---------------------------------------------------------------------- */
139 /* This is the dynamic disk header.                                       */
140 /* ---------------------------------------------------------------------- */
141 
142 struct dd_hdr {
143   char   cookie[8];       /* Should contain "cxsparse"                    */
144   u64    data_offset;     /* Byte offset of next record. (Unused) 0xffs   */
145   u64    table_offset;    /* Absolute offset to the BAT.                  */
146   u32    hdr_ver;         /* Version of the dd_hdr (major,minor)          */
147   u32    max_bat_size;    /* Maximum number of entries in the BAT         */
148   u32    block_size;      /* Block size in bytes. Must be power of 2.     */
149   u32    checksum;        /* Header checksum.  1's comp of all fields.    */
150   vhd_uuid_t prt_uuid;    /* ID of the parent disk.                       */
151   u32    prt_ts;          /* Modification time of the parent disk         */
152   u32    res1;            /* Reserved.                                    */
153   char   prt_name[512];   /* Parent unicode name.                         */
154   struct prt_loc loc[8];  /* Parent locator entries.                      */
155   char   res2[256];       /* Reserved.                                    */
156 };
157 
158 /* VHD cookie string. */
159 static const char DD_COOKIE[9]  =  "cxsparse";
160 
161 /* Version field in hd_ftr */
162 #define DD_VERSION 0x00010000
163 
164 /* Default blocksize is 2 meg. */
165 #define DD_BLOCKSIZE_DEFAULT 0x00200000
166 
167 #define DD_BLK_UNUSED 0xFFFFFFFF
168 
169 struct dd_batmap_hdr {
170   char   cookie[8];       /* should contain "tdbatmap"                    */
171   u64    batmap_offset;   /* byte offset to batmap                        */
172   u32    batmap_size;     /* batmap size in sectors                       */
173   u32    batmap_version;  /* version of batmap                            */
174   u32    checksum;        /* batmap checksum -- 1's complement of batmap  */
175 };
176 
177 static const char VHD_BATMAP_COOKIE[9] = "tdbatmap";
178 
179 /*
180  * version 1.1: signed char checksum
181  */
182 #define VHD_BATMAP_VERSION(major, minor)  (((major) << 16) | ((minor) & 0x0000FFFF))
183 #define VHD_BATMAP_CURRENT_VERSION        VHD_BATMAP_VERSION(1, 2)
184 
185 /* Layout of a dynamic disk:
186  *
187  * +-------------------------------------------------+
188  * | Mirror image of HD footer (hd_ftr) (512 bytes)  |
189  * +-------------------------------------------------+
190  * | Sparse drive header (dd_hdr) (1024 bytes)       |
191  * +-------------------------------------------------+
192  * | BAT (Block allocation table)                    |
193  * |   - Array of absolute sector offsets into the   |
194  * |     file (u32).                                 |
195  * |   - Rounded up to a sector boundary.            |
196  * |   - Unused entries are marked as 0xFFFFFFFF     |
197  * |   - max entries in dd_hdr->max_bat_size         |
198  * +-------------------------------------------------+
199  * | Data Block 0                                    |
200  * | Bitmap (padded to 512 byte sector boundary)     |
201  * |   - each bit indicates whether the associated   |
202  * |     sector within this block is used.           |
203  * | Data                                            |
204  * |   - power-of-two multiple of sectors.           |
205  * |   - default 2MB (4096 * 512)                    |
206  * |   - Any entries with zero in bitmap should be   |
207  * |     zero on disk                                |
208  * +-------------------------------------------------+
209  * | Data Block 1                                    |
210  * +-------------------------------------------------+
211  * | ...                                             |
212  * +-------------------------------------------------+
213  * | Data Block n                                    |
214  * +-------------------------------------------------+
215  * | HD Footer (511 bytes)                           |
216  * +-------------------------------------------------+
217  */
218 
219 #endif
220