~ubuntu-branches/ubuntu/saucy/qemu/saucy-proposed

« back to all changes in this revision

Viewing changes to block/vhdx.h

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-05-28 08:18:30 UTC
  • mfrom: (1.8.2) (10.1.37 sid)
  • Revision ID: package-import@ubuntu.com-20130528081830-87xl2z9fq516a814
Tags: 1.5.0+dfsg-2ubuntu1
* Merge 1.5.0+dfs-2 from debian unstable.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - Dropped patches:
    * 0001-fix-wrong-output-with-info-chardev-for-tcp-socket.patch
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * gridcentric patch - updated
    * linaro arm patches from qemu-linaro rebasing branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Block driver for Hyper-V VHDX Images
 
3
 *
 
4
 * Copyright (c) 2013 Red Hat, Inc.,
 
5
 *
 
6
 * Authors:
 
7
 *  Jeff Cody <jcody@redhat.com>
 
8
 *
 
9
 *  This is based on the "VHDX Format Specification v0.95", published 4/12/2012
 
10
 *  by Microsoft:
 
11
 *      https://www.microsoft.com/en-us/download/details.aspx?id=29681
 
12
 *
 
13
 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
 
14
 * See the COPYING.LIB file in the top-level directory.
 
15
 *
 
16
 */
 
17
 
 
18
#ifndef BLOCK_VHDX_H
 
19
#define BLOCK_VHDX_H
 
20
 
 
21
/* Structures and fields present in the VHDX file */
 
22
 
 
23
/* The header section has the following blocks,
 
24
 * each block is 64KB:
 
25
 *
 
26
 * _____________________________________________________________________________
 
27
 * | File Id. |   Header 1    | Header 2   | Region Table |  Reserved (768KB)  |
 
28
 * |----------|---------------|------------|--------------|--------------------|
 
29
 * |          |               |            |              |                    |
 
30
 * 0.........64KB...........128KB........192KB..........256KB................1MB
 
31
 */
 
32
 
 
33
#define VHDX_HEADER_BLOCK_SIZE      (64*1024)
 
34
 
 
35
#define VHDX_FILE_ID_OFFSET         0
 
36
#define VHDX_HEADER1_OFFSET         (VHDX_HEADER_BLOCK_SIZE*1)
 
37
#define VHDX_HEADER2_OFFSET         (VHDX_HEADER_BLOCK_SIZE*2)
 
38
#define VHDX_REGION_TABLE_OFFSET    (VHDX_HEADER_BLOCK_SIZE*3)
 
39
 
 
40
 
 
41
/*
 
42
 * A note on the use of MS-GUID fields.  For more details on the GUID,
 
43
 * please see: https://en.wikipedia.org/wiki/Globally_unique_identifier.
 
44
 *
 
45
 * The VHDX specification only states that these are MS GUIDs, and which
 
46
 * bytes are data1-data4. It makes no mention of what algorithm should be used
 
47
 * to generate the GUID, nor what standard.  However, looking at the specified
 
48
 * known GUID fields, it appears the GUIDs are:
 
49
 *  Standard/DCE GUID type  (noted by 10b in the MSB of byte 0 of .data4)
 
50
 *  Random algorithm        (noted by 0x4XXX for .data3)
 
51
 */
 
52
 
 
53
/* ---- HEADER SECTION STRUCTURES ---- */
 
54
 
 
55
/* These structures are ones that are defined in the VHDX specification
 
56
 * document */
 
57
 
 
58
typedef struct VHDXFileIdentifier {
 
59
    uint64_t    signature;              /* "vhdxfile" in ASCII */
 
60
    uint16_t    creator[256];           /* optional; utf-16 string to identify
 
61
                                           the vhdx file creator.  Diagnotistic
 
62
                                           only */
 
63
} VHDXFileIdentifier;
 
64
 
 
65
 
 
66
/* the guid is a 16 byte unique ID - the definition for this used by
 
67
 * Microsoft is not just 16 bytes though - it is a structure that is defined,
 
68
 * so we need to follow it here so that endianness does not trip us up */
 
69
 
 
70
typedef struct MSGUID {
 
71
    uint32_t  data1;
 
72
    uint16_t  data2;
 
73
    uint16_t  data3;
 
74
    uint8_t   data4[8];
 
75
} MSGUID;
 
76
 
 
77
#define guid_eq(a, b) \
 
78
    (memcmp(&(a), &(b), sizeof(MSGUID)) == 0)
 
79
 
 
80
#define VHDX_HEADER_SIZE (4*1024)   /* although the vhdx_header struct in disk
 
81
                                       is only 582 bytes, for purposes of crc
 
82
                                       the header is the first 4KB of the 64KB
 
83
                                       block */
 
84
 
 
85
/* The full header is 4KB, although the actual header data is much smaller.
 
86
 * But for the checksum calculation, it is over the entire 4KB structure,
 
87
 * not just the defined portion of it */
 
88
typedef struct QEMU_PACKED VHDXHeader {
 
89
    uint32_t    signature;              /* "head" in ASCII */
 
90
    uint32_t    checksum;               /* CRC-32C hash of the whole header */
 
91
    uint64_t    sequence_number;        /* Seq number of this header.  Each
 
92
                                           VHDX file has 2 of these headers,
 
93
                                           and only the header with the highest
 
94
                                           sequence number is valid */
 
95
    MSGUID      file_write_guid;       /* 128 bit unique identifier. Must be
 
96
                                           updated to new, unique value before
 
97
                                           the first modification is made to
 
98
                                           file */
 
99
    MSGUID      data_write_guid;        /* 128 bit unique identifier. Must be
 
100
                                           updated to new, unique value before
 
101
                                           the first modification is made to
 
102
                                           visible data.   Visbile data is
 
103
                                           defined as:
 
104
                                                    - system & user metadata
 
105
                                                    - raw block data
 
106
                                                    - disk size
 
107
                                                    - any change that will
 
108
                                                      cause the virtual disk
 
109
                                                      sector read to differ
 
110
 
 
111
                                           This does not need to change if
 
112
                                           blocks are re-arranged */
 
113
    MSGUID      log_guid;               /* 128 bit unique identifier. If zero,
 
114
                                           there is no valid log. If non-zero,
 
115
                                           log entries with this guid are
 
116
                                           valid. */
 
117
    uint16_t    log_version;            /* version of the log format. Mustn't be
 
118
                                           zero, unless log_guid is also zero */
 
119
    uint16_t    version;                /* version of th evhdx file.  Currently,
 
120
                                           only supported version is "1" */
 
121
    uint32_t    log_length;             /* length of the log.  Must be multiple
 
122
                                           of 1MB */
 
123
    uint64_t    log_offset;             /* byte offset in the file of the log.
 
124
                                           Must also be a multiple of 1MB */
 
125
} VHDXHeader;
 
126
 
 
127
/* Header for the region table block */
 
128
typedef struct QEMU_PACKED VHDXRegionTableHeader {
 
129
    uint32_t    signature;              /* "regi" in ASCII */
 
130
    uint32_t    checksum;               /* CRC-32C hash of the 64KB table */
 
131
    uint32_t    entry_count;            /* number of valid entries */
 
132
    uint32_t    reserved;
 
133
} VHDXRegionTableHeader;
 
134
 
 
135
/* Individual region table entry.  There may be a maximum of 2047 of these
 
136
 *
 
137
 *  There are two known region table properties.  Both are required.
 
138
 *  BAT (block allocation table):  2DC27766F62342009D64115E9BFD4A08
 
139
 *  Metadata:                      8B7CA20647904B9AB8FE575F050F886E
 
140
 */
 
141
#define VHDX_REGION_ENTRY_REQUIRED  0x01    /* if set, parser must understand
 
142
                                               this entry in order to open
 
143
                                               file */
 
144
typedef struct QEMU_PACKED VHDXRegionTableEntry {
 
145
    MSGUID      guid;                   /* 128-bit unique identifier */
 
146
    uint64_t    file_offset;            /* offset of the object in the file.
 
147
                                           Must be multiple of 1MB */
 
148
    uint32_t    length;                 /* length, in bytes, of the object */
 
149
    uint32_t    data_bits;
 
150
} VHDXRegionTableEntry;
 
151
 
 
152
 
 
153
/* ---- LOG ENTRY STRUCTURES ---- */
 
154
#define VHDX_LOG_HDR_SIZE 64
 
155
typedef struct QEMU_PACKED VHDXLogEntryHeader {
 
156
    uint32_t    signature;              /* "loge" in ASCII */
 
157
    uint32_t    checksum;               /* CRC-32C hash of the 64KB table */
 
158
    uint32_t    entry_length;           /* length in bytes, multiple of 1MB */
 
159
    uint32_t    tail;                   /* byte offset of first log entry of a
 
160
                                           seq, where this entry is the last
 
161
                                           entry */
 
162
    uint64_t    sequence_number;        /* incremented with each log entry.
 
163
                                           May not be zero. */
 
164
    uint32_t    descriptor_count;       /* number of descriptors in this log
 
165
                                           entry, must be >= 0 */
 
166
    uint32_t    reserved;
 
167
    MSGUID      log_guid;               /* value of the log_guid from
 
168
                                           vhdx_header.  If not found in
 
169
                                           vhdx_header, it is invalid */
 
170
    uint64_t    flushed_file_offset;    /* see spec for full details - this
 
171
                                           sould be vhdx file size in bytes */
 
172
    uint64_t    last_file_offset;       /* size in bytes that all allocated
 
173
                                           file structures fit into */
 
174
} VHDXLogEntryHeader;
 
175
 
 
176
#define VHDX_LOG_DESC_SIZE 32
 
177
 
 
178
typedef struct QEMU_PACKED VHDXLogDescriptor {
 
179
    uint32_t    signature;              /* "zero" or "desc" in ASCII */
 
180
    union  {
 
181
        uint32_t    reserved;           /* zero desc */
 
182
        uint32_t    trailing_bytes;     /* data desc: bytes 4092-4096 of the
 
183
                                           data sector */
 
184
    };
 
185
    union {
 
186
        uint64_t    zero_length;        /* zero desc: length of the section to
 
187
                                           zero */
 
188
        uint64_t    leading_bytes;      /* data desc: bytes 0-7 of the data
 
189
                                           sector */
 
190
    };
 
191
    uint64_t    file_offset;            /* file offset to write zeros - multiple
 
192
                                           of 4kB */
 
193
    uint64_t    sequence_number;        /* must match same field in
 
194
                                           vhdx_log_entry_header */
 
195
} VHDXLogDescriptor;
 
196
 
 
197
typedef struct QEMU_PACKED VHDXLogDataSector {
 
198
    uint32_t    data_signature;         /* "data" in ASCII */
 
199
    uint32_t    sequence_high;          /* 4 MSB of 8 byte sequence_number */
 
200
    uint8_t     data[4084];             /* raw data, bytes 8-4091 (inclusive).
 
201
                                           see the data descriptor field for the
 
202
                                           other mising bytes */
 
203
    uint32_t    sequence_low;           /* 4 LSB of 8 byte sequence_number */
 
204
} VHDXLogDataSector;
 
205
 
 
206
 
 
207
 
 
208
/* block states - different state values depending on whether it is a
 
209
 * payload block, or a sector block. */
 
210
 
 
211
#define PAYLOAD_BLOCK_NOT_PRESENT       0
 
212
#define PAYLOAD_BLOCK_UNDEFINED         1
 
213
#define PAYLOAD_BLOCK_ZERO              2
 
214
#define PAYLOAD_BLOCK_UNMAPPED          5
 
215
#define PAYLOAD_BLOCK_FULL_PRESENT      6
 
216
#define PAYLOAD_BLOCK_PARTIALLY_PRESENT 7
 
217
 
 
218
#define SB_BLOCK_NOT_PRESENT    0
 
219
#define SB_BLOCK_PRESENT        6
 
220
 
 
221
/* per the spec */
 
222
#define VHDX_MAX_SECTORS_PER_BLOCK  (1<<23)
 
223
 
 
224
/* upper 44 bits are the file offset in 1MB units lower 3 bits are the state
 
225
   other bits are reserved */
 
226
#define VHDX_BAT_STATE_BIT_MASK 0x07
 
227
#define VHDX_BAT_FILE_OFF_BITS (64-44)
 
228
typedef uint64_t VHDXBatEntry;
 
229
 
 
230
/* ---- METADATA REGION STRUCTURES ---- */
 
231
 
 
232
#define VHDX_METADATA_ENTRY_SIZE 32
 
233
#define VHDX_METADATA_MAX_ENTRIES 2047  /* not including the header */
 
234
#define VHDX_METADATA_TABLE_MAX_SIZE \
 
235
    (VHDX_METADATA_ENTRY_SIZE * (VHDX_METADATA_MAX_ENTRIES+1))
 
236
typedef struct QEMU_PACKED VHDXMetadataTableHeader {
 
237
    uint64_t    signature;              /* "metadata" in ASCII */
 
238
    uint16_t    reserved;
 
239
    uint16_t    entry_count;            /* number table entries. <= 2047 */
 
240
    uint32_t    reserved2[5];
 
241
} VHDXMetadataTableHeader;
 
242
 
 
243
#define VHDX_META_FLAGS_IS_USER         0x01    /* max 1024 entries */
 
244
#define VHDX_META_FLAGS_IS_VIRTUAL_DISK 0x02    /* virtual disk metadata if set,
 
245
                                                   otherwise file metdata */
 
246
#define VHDX_META_FLAGS_IS_REQUIRED     0x04    /* parse must understand this
 
247
                                                   entry to open the file */
 
248
typedef struct QEMU_PACKED VHDXMetadataTableEntry {
 
249
    MSGUID      item_id;                /* 128-bit identifier for metadata */
 
250
    uint32_t    offset;                 /* byte offset of the metadata.  At
 
251
                                           least 64kB.  Relative to start of
 
252
                                           metadata region */
 
253
                                        /* note: if length = 0, so is offset */
 
254
    uint32_t    length;                 /* length of metadata. <= 1MB. */
 
255
    uint32_t    data_bits;      /* least-significant 3 bits are flags, the
 
256
                                   rest are reserved (see above) */
 
257
    uint32_t    reserved2;
 
258
} VHDXMetadataTableEntry;
 
259
 
 
260
#define VHDX_PARAMS_LEAVE_BLOCKS_ALLOCED 0x01   /* Do not change any blocks to
 
261
                                                   be BLOCK_NOT_PRESENT.
 
262
                                                   If set indicates a fixed
 
263
                                                   size VHDX file */
 
264
#define VHDX_PARAMS_HAS_PARENT           0x02    /* has parent / backing file */
 
265
typedef struct QEMU_PACKED VHDXFileParameters {
 
266
    uint32_t    block_size;             /* size of each payload block, always
 
267
                                           power of 2, <= 256MB and >= 1MB. */
 
268
    uint32_t data_bits;     /* least-significant 2 bits are flags, the rest
 
269
                               are reserved (see above) */
 
270
} VHDXFileParameters;
 
271
 
 
272
typedef struct QEMU_PACKED VHDXVirtualDiskSize {
 
273
    uint64_t    virtual_disk_size;      /* Size of the virtual disk, in bytes.
 
274
                                           Must be multiple of the sector size,
 
275
                                           max of 64TB */
 
276
} VHDXVirtualDiskSize;
 
277
 
 
278
typedef struct QEMU_PACKED VHDXPage83Data {
 
279
    MSGUID      page_83_data[16];       /* unique id for scsi devices that
 
280
                                           support page 0x83 */
 
281
} VHDXPage83Data;
 
282
 
 
283
typedef struct QEMU_PACKED VHDXVirtualDiskLogicalSectorSize {
 
284
    uint32_t    logical_sector_size;    /* virtual disk sector size (in bytes).
 
285
                                           Can only be 512 or 4096 bytes */
 
286
} VHDXVirtualDiskLogicalSectorSize;
 
287
 
 
288
typedef struct QEMU_PACKED VHDXVirtualDiskPhysicalSectorSize {
 
289
    uint32_t    physical_sector_size;   /* physical sector size (in bytes).
 
290
                                           Can only be 512 or 4096 bytes */
 
291
} VHDXVirtualDiskPhysicalSectorSize;
 
292
 
 
293
typedef struct QEMU_PACKED VHDXParentLocatorHeader {
 
294
    MSGUID      locator_type[16];       /* type of the parent virtual disk. */
 
295
    uint16_t    reserved;
 
296
    uint16_t    key_value_count;        /* number of key/value pairs for this
 
297
                                           locator */
 
298
} VHDXParentLocatorHeader;
 
299
 
 
300
/* key and value strings are UNICODE strings, UTF-16 LE encoding, no NULs */
 
301
typedef struct QEMU_PACKED VHDXParentLocatorEntry {
 
302
    uint32_t    key_offset;             /* offset in metadata for key, > 0 */
 
303
    uint32_t    value_offset;           /* offset in metadata for value, >0 */
 
304
    uint16_t    key_length;             /* length of entry key, > 0 */
 
305
    uint16_t    value_length;           /* length of entry value, > 0 */
 
306
} VHDXParentLocatorEntry;
 
307
 
 
308
 
 
309
/* ----- END VHDX SPECIFICATION STRUCTURES ---- */
 
310
 
 
311
 
 
312
uint32_t vhdx_checksum_calc(uint32_t crc, uint8_t *buf, size_t size,
 
313
                            int crc_offset);
 
314
 
 
315
bool vhdx_checksum_is_valid(uint8_t *buf, size_t size, int crc_offset);
 
316
 
 
317
 
 
318
static void leguid_to_cpus(MSGUID *guid)
 
319
{
 
320
    le32_to_cpus(&guid->data1);
 
321
    le16_to_cpus(&guid->data2);
 
322
    le16_to_cpus(&guid->data3);
 
323
}
 
324
 
 
325
#endif