]> Git Repo - qemu.git/blob - block/vhdx.c
block: vhdx - update log guid in header, and first write tracker
[qemu.git] / block / vhdx.c
1 /*
2  * Block driver for Hyper-V VHDX Images
3  *
4  * Copyright (c) 2013 Red Hat, Inc.,
5  *
6  * Authors:
7  *  Jeff Cody <[email protected]>
8  *
9  *  This is based on the "VHDX Format Specification v1.00", published 8/25/2012
10  *  by Microsoft:
11  *      https://www.microsoft.com/en-us/download/details.aspx?id=34750
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 #include "qemu-common.h"
19 #include "block/block_int.h"
20 #include "qemu/module.h"
21 #include "qemu/crc32c.h"
22 #include "block/vhdx.h"
23 #include "migration/migration.h"
24
25 #include <uuid/uuid.h>
26
27 /* Several metadata and region table data entries are identified by
28  * guids in  a MS-specific GUID format. */
29
30
31 /* ------- Known Region Table GUIDs ---------------------- */
32 static const MSGUID bat_guid =      { .data1 = 0x2dc27766,
33                                       .data2 = 0xf623,
34                                       .data3 = 0x4200,
35                                       .data4 = { 0x9d, 0x64, 0x11, 0x5e,
36                                                  0x9b, 0xfd, 0x4a, 0x08} };
37
38 static const MSGUID metadata_guid = { .data1 = 0x8b7ca206,
39                                       .data2 = 0x4790,
40                                       .data3 = 0x4b9a,
41                                       .data4 = { 0xb8, 0xfe, 0x57, 0x5f,
42                                                  0x05, 0x0f, 0x88, 0x6e} };
43
44
45
46 /* ------- Known Metadata Entry GUIDs ---------------------- */
47 static const MSGUID file_param_guid =   { .data1 = 0xcaa16737,
48                                           .data2 = 0xfa36,
49                                           .data3 = 0x4d43,
50                                           .data4 = { 0xb3, 0xb6, 0x33, 0xf0,
51                                                      0xaa, 0x44, 0xe7, 0x6b} };
52
53 static const MSGUID virtual_size_guid = { .data1 = 0x2FA54224,
54                                           .data2 = 0xcd1b,
55                                           .data3 = 0x4876,
56                                           .data4 = { 0xb2, 0x11, 0x5d, 0xbe,
57                                                      0xd8, 0x3b, 0xf4, 0xb8} };
58
59 static const MSGUID page83_guid =       { .data1 = 0xbeca12ab,
60                                           .data2 = 0xb2e6,
61                                           .data3 = 0x4523,
62                                           .data4 = { 0x93, 0xef, 0xc3, 0x09,
63                                                      0xe0, 0x00, 0xc7, 0x46} };
64
65
66 static const MSGUID phys_sector_guid =  { .data1 = 0xcda348c7,
67                                           .data2 = 0x445d,
68                                           .data3 = 0x4471,
69                                           .data4 = { 0x9c, 0xc9, 0xe9, 0x88,
70                                                      0x52, 0x51, 0xc5, 0x56} };
71
72 static const MSGUID parent_locator_guid = { .data1 = 0xa8d35f2d,
73                                             .data2 = 0xb30b,
74                                             .data3 = 0x454d,
75                                             .data4 = { 0xab, 0xf7, 0xd3,
76                                                        0xd8, 0x48, 0x34,
77                                                        0xab, 0x0c} };
78
79 static const MSGUID logical_sector_guid = { .data1 = 0x8141bf1d,
80                                             .data2 = 0xa96f,
81                                             .data3 = 0x4709,
82                                             .data4 = { 0xba, 0x47, 0xf2,
83                                                        0x33, 0xa8, 0xfa,
84                                                        0xab, 0x5f} };
85
86 /* Each parent type must have a valid GUID; this is for parent images
87  * of type 'VHDX'.  If we were to allow e.g. a QCOW2 parent, we would
88  * need to make up our own QCOW2 GUID type */
89 static const MSGUID parent_vhdx_guid = { .data1 = 0xb04aefb7,
90                                          .data2 = 0xd19e,
91                                          .data3 = 0x4a81,
92                                          .data4 = { 0xb7, 0x89, 0x25, 0xb8,
93                                                     0xe9, 0x44, 0x59, 0x13} };
94
95
96 #define META_FILE_PARAMETER_PRESENT      0x01
97 #define META_VIRTUAL_DISK_SIZE_PRESENT   0x02
98 #define META_PAGE_83_PRESENT             0x04
99 #define META_LOGICAL_SECTOR_SIZE_PRESENT 0x08
100 #define META_PHYS_SECTOR_SIZE_PRESENT    0x10
101 #define META_PARENT_LOCATOR_PRESENT      0x20
102
103 #define META_ALL_PRESENT    \
104     (META_FILE_PARAMETER_PRESENT | META_VIRTUAL_DISK_SIZE_PRESENT | \
105      META_PAGE_83_PRESENT | META_LOGICAL_SECTOR_SIZE_PRESENT | \
106      META_PHYS_SECTOR_SIZE_PRESENT)
107
108
109 typedef struct VHDXSectorInfo {
110     uint32_t bat_idx;       /* BAT entry index */
111     uint32_t sectors_avail; /* sectors available in payload block */
112     uint32_t bytes_left;    /* bytes left in the block after data to r/w */
113     uint32_t bytes_avail;   /* bytes available in payload block */
114     uint64_t file_offset;   /* absolute offset in bytes, in file */
115     uint64_t block_offset;  /* block offset, in bytes */
116 } VHDXSectorInfo;
117
118 /* Calculates new checksum.
119  *
120  * Zero is substituted during crc calculation for the original crc field
121  * crc_offset: byte offset in buf of the buffer crc
122  * buf: buffer pointer
123  * size: size of buffer (must be > crc_offset+4)
124  *
125  * Note: The resulting checksum is in the CPU endianness, not necessarily
126  *       in the file format endianness (LE).  Any header export to disk should
127  *       make sure that vhdx_header_le_export() is used to convert to the
128  *       correct endianness
129  */
130 uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset)
131 {
132     uint32_t crc;
133
134     assert(buf != NULL);
135     assert(size > (crc_offset + sizeof(crc)));
136
137     memset(buf + crc_offset, 0, sizeof(crc));
138     crc =  crc32c(0xffffffff, buf, size);
139     memcpy(buf + crc_offset, &crc, sizeof(crc));
140
141     return crc;
142 }
143
144 uint32_t vhdx_checksum_calc(uint32_t crc, uint8_t *buf, size_t size,
145                             int crc_offset)
146 {
147     uint32_t crc_new;
148     uint32_t crc_orig;
149     assert(buf != NULL);
150
151     if (crc_offset > 0) {
152         memcpy(&crc_orig, buf + crc_offset, sizeof(crc_orig));
153         memset(buf + crc_offset, 0, sizeof(crc_orig));
154     }
155
156     crc_new = crc32c(crc, buf, size);
157     if (crc_offset > 0) {
158         memcpy(buf + crc_offset, &crc_orig, sizeof(crc_orig));
159     }
160
161     return crc_new;
162 }
163
164 /* Validates the checksum of the buffer, with an in-place CRC.
165  *
166  * Zero is substituted during crc calculation for the original crc field,
167  * and the crc field is restored afterwards.  But the buffer will be modifed
168  * during the calculation, so this may not be not suitable for multi-threaded
169  * use.
170  *
171  * crc_offset: byte offset in buf of the buffer crc
172  * buf: buffer pointer
173  * size: size of buffer (must be > crc_offset+4)
174  *
175  * returns true if checksum is valid, false otherwise
176  */
177 bool vhdx_checksum_is_valid(uint8_t *buf, size_t size, int crc_offset)
178 {
179     uint32_t crc_orig;
180     uint32_t crc;
181
182     assert(buf != NULL);
183     assert(size > (crc_offset + 4));
184
185     memcpy(&crc_orig, buf + crc_offset, sizeof(crc_orig));
186     crc_orig = le32_to_cpu(crc_orig);
187
188     crc = vhdx_checksum_calc(0xffffffff, buf, size, crc_offset);
189
190     return crc == crc_orig;
191 }
192
193
194 /*
195  * This generates a UUID that is compliant with the MS GUIDs used
196  * in the VHDX spec (and elsewhere).
197  */
198 void vhdx_guid_generate(MSGUID *guid)
199 {
200     uuid_t uuid;
201     assert(guid != NULL);
202
203     uuid_generate(uuid);
204     memcpy(guid, uuid, sizeof(MSGUID));
205 }
206
207 /*
208  * Per the MS VHDX Specification, for every VHDX file:
209  *      - The header section is fixed size - 1 MB
210  *      - The header section is always the first "object"
211  *      - The first 64KB of the header is the File Identifier
212  *      - The first uint64 (8 bytes) is the VHDX Signature ("vhdxfile")
213  *      - The following 512 bytes constitute a UTF-16 string identifiying the
214  *        software that created the file, and is optional and diagnostic only.
215  *
216  *  Therefore, we probe by looking for the vhdxfile signature "vhdxfile"
217  */
218 static int vhdx_probe(const uint8_t *buf, int buf_size, const char *filename)
219 {
220     if (buf_size >= 8 && !memcmp(buf, "vhdxfile", 8)) {
221         return 100;
222     }
223     return 0;
224 }
225
226 /* Update the VHDX headers
227  *
228  * This follows the VHDX spec procedures for header updates.
229  *
230  *  - non-current header is updated with largest sequence number
231  */
232 static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s,
233                               bool generate_data_write_guid, MSGUID *log_guid)
234 {
235     int ret = 0;
236     int hdr_idx = 0;
237     uint64_t header_offset = VHDX_HEADER1_OFFSET;
238
239     VHDXHeader *active_header;
240     VHDXHeader *inactive_header;
241     VHDXHeader header_le;
242     uint8_t *buffer;
243
244     /* operate on the non-current header */
245     if (s->curr_header == 0) {
246         hdr_idx = 1;
247         header_offset = VHDX_HEADER2_OFFSET;
248     }
249
250     active_header   = s->headers[s->curr_header];
251     inactive_header = s->headers[hdr_idx];
252
253     inactive_header->sequence_number = active_header->sequence_number + 1;
254
255     /* a new file guid must be generated before any file write, including
256      * headers */
257     inactive_header->file_write_guid = s->session_guid;
258
259     /* a new data guid only needs to be generated before any guest-visible
260      * writes (i.e. something observable via virtual disk read) */
261     if (generate_data_write_guid) {
262         vhdx_guid_generate(&inactive_header->data_write_guid);
263     }
264
265     /* update the log guid if present */
266     if (log_guid) {
267         inactive_header->log_guid = *log_guid;
268     }
269
270     /* the header checksum is not over just the packed size of VHDXHeader,
271      * but rather over the entire 'reserved' range for the header, which is
272      * 4KB (VHDX_HEADER_SIZE). */
273
274     buffer = qemu_blockalign(bs, VHDX_HEADER_SIZE);
275     /* we can't assume the extra reserved bytes are 0 */
276     ret = bdrv_pread(bs->file, header_offset, buffer, VHDX_HEADER_SIZE);
277     if (ret < 0) {
278         goto exit;
279     }
280     /* overwrite the actual VHDXHeader portion */
281     memcpy(buffer, inactive_header, sizeof(VHDXHeader));
282     inactive_header->checksum =
283                         vhdx_update_checksum(buffer, VHDX_HEADER_SIZE,
284                                              offsetof(VHDXHeader, checksum));
285     vhdx_header_le_export(inactive_header, &header_le);
286     ret = bdrv_pwrite_sync(bs->file, header_offset, &header_le,
287                            sizeof(VHDXHeader));
288     if (ret < 0) {
289         goto exit;
290     }
291     s->curr_header = hdr_idx;
292
293 exit:
294     qemu_vfree(buffer);
295     return ret;
296 }
297
298 /*
299  * The VHDX spec calls for header updates to be performed twice, so that both
300  * the current and non-current header have valid info
301  */
302 int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s,
303                         bool generate_data_write_guid, MSGUID *log_guid)
304 {
305     int ret;
306
307     ret = vhdx_update_header(bs, s, generate_data_write_guid, log_guid);
308     if (ret < 0) {
309         return ret;
310     }
311     ret = vhdx_update_header(bs, s, generate_data_write_guid, log_guid);
312     return ret;
313 }
314
315 /* opens the specified header block from the VHDX file header section */
316 static int vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s)
317 {
318     int ret = 0;
319     VHDXHeader *header1;
320     VHDXHeader *header2;
321     bool h1_valid = false;
322     bool h2_valid = false;
323     uint64_t h1_seq = 0;
324     uint64_t h2_seq = 0;
325     uint8_t *buffer;
326
327     /* header1 & header2 are freed in vhdx_close() */
328     header1 = qemu_blockalign(bs, sizeof(VHDXHeader));
329     header2 = qemu_blockalign(bs, sizeof(VHDXHeader));
330
331     buffer = qemu_blockalign(bs, VHDX_HEADER_SIZE);
332
333     s->headers[0] = header1;
334     s->headers[1] = header2;
335
336     /* We have to read the whole VHDX_HEADER_SIZE instead of
337      * sizeof(VHDXHeader), because the checksum is over the whole
338      * region */
339     ret = bdrv_pread(bs->file, VHDX_HEADER1_OFFSET, buffer, VHDX_HEADER_SIZE);
340     if (ret < 0) {
341         goto fail;
342     }
343     /* copy over just the relevant portion that we need */
344     memcpy(header1, buffer, sizeof(VHDXHeader));
345     vhdx_header_le_import(header1);
346
347     if (vhdx_checksum_is_valid(buffer, VHDX_HEADER_SIZE, 4) &&
348         !memcmp(&header1->signature, "head", 4)             &&
349         header1->version == 1) {
350         h1_seq = header1->sequence_number;
351         h1_valid = true;
352     }
353
354     ret = bdrv_pread(bs->file, VHDX_HEADER2_OFFSET, buffer, VHDX_HEADER_SIZE);
355     if (ret < 0) {
356         goto fail;
357     }
358     /* copy over just the relevant portion that we need */
359     memcpy(header2, buffer, sizeof(VHDXHeader));
360     vhdx_header_le_import(header2);
361
362     if (vhdx_checksum_is_valid(buffer, VHDX_HEADER_SIZE, 4) &&
363         !memcmp(&header2->signature, "head", 4)             &&
364         header2->version == 1) {
365         h2_seq = header2->sequence_number;
366         h2_valid = true;
367     }
368
369     /* If there is only 1 valid header (or no valid headers), we
370      * don't care what the sequence numbers are */
371     if (h1_valid && !h2_valid) {
372         s->curr_header = 0;
373     } else if (!h1_valid && h2_valid) {
374         s->curr_header = 1;
375     } else if (!h1_valid && !h2_valid) {
376         ret = -EINVAL;
377         goto fail;
378     } else {
379         /* If both headers are valid, then we choose the active one by the
380          * highest sequence number.  If the sequence numbers are equal, that is
381          * invalid */
382         if (h1_seq > h2_seq) {
383             s->curr_header = 0;
384         } else if (h2_seq > h1_seq) {
385             s->curr_header = 1;
386         } else {
387             ret = -EINVAL;
388             goto fail;
389         }
390     }
391
392     ret = 0;
393
394     goto exit;
395
396 fail:
397     qerror_report(ERROR_CLASS_GENERIC_ERROR, "No valid VHDX header found");
398     qemu_vfree(header1);
399     qemu_vfree(header2);
400     s->headers[0] = NULL;
401     s->headers[1] = NULL;
402 exit:
403     qemu_vfree(buffer);
404     return ret;
405 }
406
407
408 static int vhdx_open_region_tables(BlockDriverState *bs, BDRVVHDXState *s)
409 {
410     int ret = 0;
411     uint8_t *buffer;
412     int offset = 0;
413     VHDXRegionTableEntry rt_entry;
414     uint32_t i;
415     bool bat_rt_found = false;
416     bool metadata_rt_found = false;
417
418     /* We have to read the whole 64KB block, because the crc32 is over the
419      * whole block */
420     buffer = qemu_blockalign(bs, VHDX_HEADER_BLOCK_SIZE);
421
422     ret = bdrv_pread(bs->file, VHDX_REGION_TABLE_OFFSET, buffer,
423                      VHDX_HEADER_BLOCK_SIZE);
424     if (ret < 0) {
425         goto fail;
426     }
427     memcpy(&s->rt, buffer, sizeof(s->rt));
428     le32_to_cpus(&s->rt.signature);
429     le32_to_cpus(&s->rt.checksum);
430     le32_to_cpus(&s->rt.entry_count);
431     le32_to_cpus(&s->rt.reserved);
432     offset += sizeof(s->rt);
433
434     if (!vhdx_checksum_is_valid(buffer, VHDX_HEADER_BLOCK_SIZE, 4) ||
435         memcmp(&s->rt.signature, "regi", 4)) {
436         ret = -EINVAL;
437         goto fail;
438     }
439
440     /* Per spec, maximum region table entry count is 2047 */
441     if (s->rt.entry_count > 2047) {
442         ret = -EINVAL;
443         goto fail;
444     }
445
446     for (i = 0; i < s->rt.entry_count; i++) {
447         memcpy(&rt_entry, buffer + offset, sizeof(rt_entry));
448         offset += sizeof(rt_entry);
449
450         leguid_to_cpus(&rt_entry.guid);
451         le64_to_cpus(&rt_entry.file_offset);
452         le32_to_cpus(&rt_entry.length);
453         le32_to_cpus(&rt_entry.data_bits);
454
455         /* see if we recognize the entry */
456         if (guid_eq(rt_entry.guid, bat_guid)) {
457             /* must be unique; if we have already found it this is invalid */
458             if (bat_rt_found) {
459                 ret = -EINVAL;
460                 goto fail;
461             }
462             bat_rt_found = true;
463             s->bat_rt = rt_entry;
464             continue;
465         }
466
467         if (guid_eq(rt_entry.guid, metadata_guid)) {
468             /* must be unique; if we have already found it this is invalid */
469             if (metadata_rt_found) {
470                 ret = -EINVAL;
471                 goto fail;
472             }
473             metadata_rt_found = true;
474             s->metadata_rt = rt_entry;
475             continue;
476         }
477
478         if (rt_entry.data_bits & VHDX_REGION_ENTRY_REQUIRED) {
479             /* cannot read vhdx file - required region table entry that
480              * we do not understand.  per spec, we must fail to open */
481             ret = -ENOTSUP;
482             goto fail;
483         }
484     }
485     ret = 0;
486
487 fail:
488     qemu_vfree(buffer);
489     return ret;
490 }
491
492
493
494 /* Metadata initial parser
495  *
496  * This loads all the metadata entry fields.  This may cause additional
497  * fields to be processed (e.g. parent locator, etc..).
498  *
499  * There are 5 Metadata items that are always required:
500  *      - File Parameters (block size, has a parent)
501  *      - Virtual Disk Size (size, in bytes, of the virtual drive)
502  *      - Page 83 Data (scsi page 83 guid)
503  *      - Logical Sector Size (logical sector size in bytes, either 512 or
504  *                             4096.  We only support 512 currently)
505  *      - Physical Sector Size (512 or 4096)
506  *
507  * Also, if the File Parameters indicate this is a differencing file,
508  * we must also look for the Parent Locator metadata item.
509  */
510 static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
511 {
512     int ret = 0;
513     uint8_t *buffer;
514     int offset = 0;
515     uint32_t i = 0;
516     VHDXMetadataTableEntry md_entry;
517
518     buffer = qemu_blockalign(bs, VHDX_METADATA_TABLE_MAX_SIZE);
519
520     ret = bdrv_pread(bs->file, s->metadata_rt.file_offset, buffer,
521                      VHDX_METADATA_TABLE_MAX_SIZE);
522     if (ret < 0) {
523         goto exit;
524     }
525     memcpy(&s->metadata_hdr, buffer, sizeof(s->metadata_hdr));
526     offset += sizeof(s->metadata_hdr);
527
528     le64_to_cpus(&s->metadata_hdr.signature);
529     le16_to_cpus(&s->metadata_hdr.reserved);
530     le16_to_cpus(&s->metadata_hdr.entry_count);
531
532     if (memcmp(&s->metadata_hdr.signature, "metadata", 8)) {
533         ret = -EINVAL;
534         goto exit;
535     }
536
537     s->metadata_entries.present = 0;
538
539     if ((s->metadata_hdr.entry_count * sizeof(md_entry)) >
540         (VHDX_METADATA_TABLE_MAX_SIZE - offset)) {
541         ret = -EINVAL;
542         goto exit;
543     }
544
545     for (i = 0; i < s->metadata_hdr.entry_count; i++) {
546         memcpy(&md_entry, buffer + offset, sizeof(md_entry));
547         offset += sizeof(md_entry);
548
549         leguid_to_cpus(&md_entry.item_id);
550         le32_to_cpus(&md_entry.offset);
551         le32_to_cpus(&md_entry.length);
552         le32_to_cpus(&md_entry.data_bits);
553         le32_to_cpus(&md_entry.reserved2);
554
555         if (guid_eq(md_entry.item_id, file_param_guid)) {
556             if (s->metadata_entries.present & META_FILE_PARAMETER_PRESENT) {
557                 ret = -EINVAL;
558                 goto exit;
559             }
560             s->metadata_entries.file_parameters_entry = md_entry;
561             s->metadata_entries.present |= META_FILE_PARAMETER_PRESENT;
562             continue;
563         }
564
565         if (guid_eq(md_entry.item_id, virtual_size_guid)) {
566             if (s->metadata_entries.present & META_VIRTUAL_DISK_SIZE_PRESENT) {
567                 ret = -EINVAL;
568                 goto exit;
569             }
570             s->metadata_entries.virtual_disk_size_entry = md_entry;
571             s->metadata_entries.present |= META_VIRTUAL_DISK_SIZE_PRESENT;
572             continue;
573         }
574
575         if (guid_eq(md_entry.item_id, page83_guid)) {
576             if (s->metadata_entries.present & META_PAGE_83_PRESENT) {
577                 ret = -EINVAL;
578                 goto exit;
579             }
580             s->metadata_entries.page83_data_entry = md_entry;
581             s->metadata_entries.present |= META_PAGE_83_PRESENT;
582             continue;
583         }
584
585         if (guid_eq(md_entry.item_id, logical_sector_guid)) {
586             if (s->metadata_entries.present &
587                 META_LOGICAL_SECTOR_SIZE_PRESENT) {
588                 ret = -EINVAL;
589                 goto exit;
590             }
591             s->metadata_entries.logical_sector_size_entry = md_entry;
592             s->metadata_entries.present |= META_LOGICAL_SECTOR_SIZE_PRESENT;
593             continue;
594         }
595
596         if (guid_eq(md_entry.item_id, phys_sector_guid)) {
597             if (s->metadata_entries.present & META_PHYS_SECTOR_SIZE_PRESENT) {
598                 ret = -EINVAL;
599                 goto exit;
600             }
601             s->metadata_entries.phys_sector_size_entry = md_entry;
602             s->metadata_entries.present |= META_PHYS_SECTOR_SIZE_PRESENT;
603             continue;
604         }
605
606         if (guid_eq(md_entry.item_id, parent_locator_guid)) {
607             if (s->metadata_entries.present & META_PARENT_LOCATOR_PRESENT) {
608                 ret = -EINVAL;
609                 goto exit;
610             }
611             s->metadata_entries.parent_locator_entry = md_entry;
612             s->metadata_entries.present |= META_PARENT_LOCATOR_PRESENT;
613             continue;
614         }
615
616         if (md_entry.data_bits & VHDX_META_FLAGS_IS_REQUIRED) {
617             /* cannot read vhdx file - required region table entry that
618              * we do not understand.  per spec, we must fail to open */
619             ret = -ENOTSUP;
620             goto exit;
621         }
622     }
623
624     if (s->metadata_entries.present != META_ALL_PRESENT) {
625         ret = -ENOTSUP;
626         goto exit;
627     }
628
629     ret = bdrv_pread(bs->file,
630                      s->metadata_entries.file_parameters_entry.offset
631                                          + s->metadata_rt.file_offset,
632                      &s->params,
633                      sizeof(s->params));
634
635     if (ret < 0) {
636         goto exit;
637     }
638
639     le32_to_cpus(&s->params.block_size);
640     le32_to_cpus(&s->params.data_bits);
641
642
643     /* We now have the file parameters, so we can tell if this is a
644      * differencing file (i.e.. has_parent), is dynamic or fixed
645      * sized (leave_blocks_allocated), and the block size */
646
647     /* The parent locator required iff the file parameters has_parent set */
648     if (s->params.data_bits & VHDX_PARAMS_HAS_PARENT) {
649         if (s->metadata_entries.present & META_PARENT_LOCATOR_PRESENT) {
650             /* TODO: parse  parent locator fields */
651             ret = -ENOTSUP; /* temp, until differencing files are supported */
652             goto exit;
653         } else {
654             /* if has_parent is set, but there is not parent locator present,
655              * then that is an invalid combination */
656             ret = -EINVAL;
657             goto exit;
658         }
659     }
660
661     /* determine virtual disk size, logical sector size,
662      * and phys sector size */
663
664     ret = bdrv_pread(bs->file,
665                      s->metadata_entries.virtual_disk_size_entry.offset
666                                            + s->metadata_rt.file_offset,
667                      &s->virtual_disk_size,
668                      sizeof(uint64_t));
669     if (ret < 0) {
670         goto exit;
671     }
672     ret = bdrv_pread(bs->file,
673                      s->metadata_entries.logical_sector_size_entry.offset
674                                              + s->metadata_rt.file_offset,
675                      &s->logical_sector_size,
676                      sizeof(uint32_t));
677     if (ret < 0) {
678         goto exit;
679     }
680     ret = bdrv_pread(bs->file,
681                      s->metadata_entries.phys_sector_size_entry.offset
682                                           + s->metadata_rt.file_offset,
683                      &s->physical_sector_size,
684                      sizeof(uint32_t));
685     if (ret < 0) {
686         goto exit;
687     }
688
689     le64_to_cpus(&s->virtual_disk_size);
690     le32_to_cpus(&s->logical_sector_size);
691     le32_to_cpus(&s->physical_sector_size);
692
693     if (s->logical_sector_size == 0 || s->params.block_size == 0) {
694         ret = -EINVAL;
695         goto exit;
696     }
697
698     /* both block_size and sector_size are guaranteed powers of 2 */
699     s->sectors_per_block = s->params.block_size / s->logical_sector_size;
700     s->chunk_ratio = (VHDX_MAX_SECTORS_PER_BLOCK) *
701                      (uint64_t)s->logical_sector_size /
702                      (uint64_t)s->params.block_size;
703
704     /* These values are ones we will want to use for division / multiplication
705      * later on, and they are all guaranteed (per the spec) to be powers of 2,
706      * so we can take advantage of that for shift operations during
707      * reads/writes */
708     if (s->logical_sector_size & (s->logical_sector_size - 1)) {
709         ret = -EINVAL;
710         goto exit;
711     }
712     if (s->sectors_per_block & (s->sectors_per_block - 1)) {
713         ret = -EINVAL;
714         goto exit;
715     }
716     if (s->chunk_ratio & (s->chunk_ratio - 1)) {
717         ret = -EINVAL;
718         goto exit;
719     }
720     s->block_size = s->params.block_size;
721     if (s->block_size & (s->block_size - 1)) {
722         ret = -EINVAL;
723         goto exit;
724     }
725
726     s->logical_sector_size_bits = 31 - clz32(s->logical_sector_size);
727     s->sectors_per_block_bits =   31 - clz32(s->sectors_per_block);
728     s->chunk_ratio_bits =         63 - clz64(s->chunk_ratio);
729     s->block_size_bits =          31 - clz32(s->block_size);
730
731     ret = 0;
732
733 exit:
734     qemu_vfree(buffer);
735     return ret;
736 }
737
738 /* Parse the replay log.  Per the VHDX spec, if the log is present
739  * it must be replayed prior to opening the file, even read-only.
740  *
741  * If read-only, we must replay the log in RAM (or refuse to open
742  * a dirty VHDX file read-only */
743 static int vhdx_parse_log(BlockDriverState *bs, BDRVVHDXState *s)
744 {
745     int ret = 0;
746     int i;
747     VHDXHeader *hdr;
748
749     hdr = s->headers[s->curr_header];
750
751     /* either the log guid, or log length is zero,
752      * then a replay log is present */
753     for (i = 0; i < sizeof(hdr->log_guid.data4); i++) {
754         ret |= hdr->log_guid.data4[i];
755     }
756     if (hdr->log_guid.data1 == 0 &&
757         hdr->log_guid.data2 == 0 &&
758         hdr->log_guid.data3 == 0 &&
759         ret == 0) {
760         goto exit;
761     }
762
763     /* per spec, only log version of 0 is supported */
764     if (hdr->log_version != 0) {
765         ret = -EINVAL;
766         goto exit;
767     }
768
769     if (hdr->log_length == 0) {
770         goto exit;
771     }
772
773     /* We currently do not support images with logs to replay */
774     ret = -ENOTSUP;
775
776 exit:
777     return ret;
778 }
779
780
781 static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
782                      Error **errp)
783 {
784     BDRVVHDXState *s = bs->opaque;
785     int ret = 0;
786     uint32_t i;
787     uint64_t signature;
788     uint32_t data_blocks_cnt, bitmap_blocks_cnt;
789
790
791     s->bat = NULL;
792     s->first_visible_write = true;
793
794     qemu_co_mutex_init(&s->lock);
795
796     /* validate the file signature */
797     ret = bdrv_pread(bs->file, 0, &signature, sizeof(uint64_t));
798     if (ret < 0) {
799         goto fail;
800     }
801     if (memcmp(&signature, "vhdxfile", 8)) {
802         ret = -EINVAL;
803         goto fail;
804     }
805
806     /* This is used for any header updates, for the file_write_guid.
807      * The spec dictates that a new value should be used for the first
808      * header update */
809     vhdx_guid_generate(&s->session_guid);
810
811     ret = vhdx_parse_header(bs, s);
812     if (ret) {
813         goto fail;
814     }
815
816     ret = vhdx_parse_log(bs, s);
817     if (ret) {
818         goto fail;
819     }
820
821     ret = vhdx_open_region_tables(bs, s);
822     if (ret) {
823         goto fail;
824     }
825
826     ret = vhdx_parse_metadata(bs, s);
827     if (ret) {
828         goto fail;
829     }
830     s->block_size = s->params.block_size;
831
832     /* the VHDX spec dictates that virtual_disk_size is always a multiple of
833      * logical_sector_size */
834     bs->total_sectors = s->virtual_disk_size >> s->logical_sector_size_bits;
835
836     data_blocks_cnt = s->virtual_disk_size >> s->block_size_bits;
837     if (s->virtual_disk_size - (data_blocks_cnt << s->block_size_bits)) {
838         data_blocks_cnt++;
839     }
840     bitmap_blocks_cnt = data_blocks_cnt >> s->chunk_ratio_bits;
841     if (data_blocks_cnt - (bitmap_blocks_cnt << s->chunk_ratio_bits)) {
842         bitmap_blocks_cnt++;
843     }
844
845     if (s->parent_entries) {
846         s->bat_entries = bitmap_blocks_cnt * (s->chunk_ratio + 1);
847     } else {
848         s->bat_entries = data_blocks_cnt +
849                          ((data_blocks_cnt - 1) >> s->chunk_ratio_bits);
850     }
851
852     s->bat_offset = s->bat_rt.file_offset;
853
854     if (s->bat_entries > s->bat_rt.length / sizeof(VHDXBatEntry)) {
855         /* BAT allocation is not large enough for all entries */
856         ret = -EINVAL;
857         goto fail;
858     }
859
860     /* s->bat is freed in vhdx_close() */
861     s->bat = qemu_blockalign(bs, s->bat_rt.length);
862
863     ret = bdrv_pread(bs->file, s->bat_offset, s->bat, s->bat_rt.length);
864     if (ret < 0) {
865         goto fail;
866     }
867
868     for (i = 0; i < s->bat_entries; i++) {
869         le64_to_cpus(&s->bat[i]);
870     }
871
872     if (flags & BDRV_O_RDWR) {
873         ret = vhdx_update_headers(bs, s, false, NULL);
874         if (ret < 0) {
875             goto fail;
876         }
877     }
878
879     /* TODO: differencing files, write */
880
881     /* Disable migration when VHDX images are used */
882     error_set(&s->migration_blocker,
883             QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
884             "vhdx", bs->device_name, "live migration");
885     migrate_add_blocker(s->migration_blocker);
886
887     return 0;
888 fail:
889     qemu_vfree(s->headers[0]);
890     qemu_vfree(s->headers[1]);
891     qemu_vfree(s->bat);
892     qemu_vfree(s->parent_entries);
893     return ret;
894 }
895
896 static int vhdx_reopen_prepare(BDRVReopenState *state,
897                                BlockReopenQueue *queue, Error **errp)
898 {
899     return 0;
900 }
901
902
903 /*
904  * Perform sector to block offset translations, to get various
905  * sector and file offsets into the image.  See VHDXSectorInfo
906  */
907 static void vhdx_block_translate(BDRVVHDXState *s, int64_t sector_num,
908                                  int nb_sectors, VHDXSectorInfo *sinfo)
909 {
910     uint32_t block_offset;
911
912     sinfo->bat_idx = sector_num >> s->sectors_per_block_bits;
913     /* effectively a modulo - this gives us the offset into the block
914      * (in sector sizes) for our sector number */
915     block_offset = sector_num - (sinfo->bat_idx << s->sectors_per_block_bits);
916     /* the chunk ratio gives us the interleaving of the sector
917      * bitmaps, so we need to advance our page block index by the
918      * sector bitmaps entry number */
919     sinfo->bat_idx += sinfo->bat_idx >> s->chunk_ratio_bits;
920
921     /* the number of sectors we can read/write in this cycle */
922     sinfo->sectors_avail = s->sectors_per_block - block_offset;
923
924     sinfo->bytes_left = sinfo->sectors_avail << s->logical_sector_size_bits;
925
926     if (sinfo->sectors_avail > nb_sectors) {
927         sinfo->sectors_avail = nb_sectors;
928     }
929
930     sinfo->bytes_avail = sinfo->sectors_avail << s->logical_sector_size_bits;
931
932     sinfo->file_offset = s->bat[sinfo->bat_idx] >> VHDX_BAT_FILE_OFF_BITS;
933
934     sinfo->block_offset = block_offset << s->logical_sector_size_bits;
935
936     /* The file offset must be past the header section, so must be > 0 */
937     if (sinfo->file_offset == 0) {
938         return;
939     }
940
941     /* block offset is the offset in vhdx logical sectors, in
942      * the payload data block. Convert that to a byte offset
943      * in the block, and add in the payload data block offset
944      * in the file, in bytes, to get the final read address */
945
946     sinfo->file_offset <<= 20;  /* now in bytes, rather than 1MB units */
947     sinfo->file_offset += sinfo->block_offset;
948 }
949
950
951
952 static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
953                                       int nb_sectors, QEMUIOVector *qiov)
954 {
955     BDRVVHDXState *s = bs->opaque;
956     int ret = 0;
957     VHDXSectorInfo sinfo;
958     uint64_t bytes_done = 0;
959     QEMUIOVector hd_qiov;
960
961     qemu_iovec_init(&hd_qiov, qiov->niov);
962
963     qemu_co_mutex_lock(&s->lock);
964
965     while (nb_sectors > 0) {
966         /* We are a differencing file, so we need to inspect the sector bitmap
967          * to see if we have the data or not */
968         if (s->params.data_bits & VHDX_PARAMS_HAS_PARENT) {
969             /* not supported yet */
970             ret = -ENOTSUP;
971             goto exit;
972         } else {
973             vhdx_block_translate(s, sector_num, nb_sectors, &sinfo);
974
975             qemu_iovec_reset(&hd_qiov);
976             qemu_iovec_concat(&hd_qiov, qiov,  bytes_done, sinfo.bytes_avail);
977
978             /* check the payload block state */
979             switch (s->bat[sinfo.bat_idx] & VHDX_BAT_STATE_BIT_MASK) {
980             case PAYLOAD_BLOCK_NOT_PRESENT: /* fall through */
981             case PAYLOAD_BLOCK_UNDEFINED:   /* fall through */
982             case PAYLOAD_BLOCK_UNMAPPED:    /* fall through */
983             case PAYLOAD_BLOCK_ZERO:
984                 /* return zero */
985                 qemu_iovec_memset(&hd_qiov, 0, 0, sinfo.bytes_avail);
986                 break;
987             case PAYLOAD_BLOCK_FULL_PRESENT:
988                 qemu_co_mutex_unlock(&s->lock);
989                 ret = bdrv_co_readv(bs->file,
990                                     sinfo.file_offset >> BDRV_SECTOR_BITS,
991                                     sinfo.sectors_avail, &hd_qiov);
992                 qemu_co_mutex_lock(&s->lock);
993                 if (ret < 0) {
994                     goto exit;
995                 }
996                 break;
997             case PAYLOAD_BLOCK_PARTIALLY_PRESENT:
998                 /* we don't yet support difference files, fall through
999                  * to error */
1000             default:
1001                 ret = -EIO;
1002                 goto exit;
1003                 break;
1004             }
1005             nb_sectors -= sinfo.sectors_avail;
1006             sector_num += sinfo.sectors_avail;
1007             bytes_done += sinfo.bytes_avail;
1008         }
1009     }
1010     ret = 0;
1011 exit:
1012     qemu_co_mutex_unlock(&s->lock);
1013     qemu_iovec_destroy(&hd_qiov);
1014     return ret;
1015 }
1016
1017
1018
1019 /* Per the spec, on the first write of guest-visible data to the file the
1020  * data write guid must be updated in the header */
1021 int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s)
1022 {
1023     int ret = 0;
1024     if (s->first_visible_write) {
1025         s->first_visible_write = false;
1026         ret = vhdx_update_headers(bs, s, true, NULL);
1027     }
1028     return ret;
1029 }
1030
1031 static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
1032                                       int nb_sectors, QEMUIOVector *qiov)
1033 {
1034     return -ENOTSUP;
1035 }
1036
1037
1038 static void vhdx_close(BlockDriverState *bs)
1039 {
1040     BDRVVHDXState *s = bs->opaque;
1041     qemu_vfree(s->headers[0]);
1042     qemu_vfree(s->headers[1]);
1043     qemu_vfree(s->bat);
1044     qemu_vfree(s->parent_entries);
1045     migrate_del_blocker(s->migration_blocker);
1046     error_free(s->migration_blocker);
1047 }
1048
1049 static BlockDriver bdrv_vhdx = {
1050     .format_name            = "vhdx",
1051     .instance_size          = sizeof(BDRVVHDXState),
1052     .bdrv_probe             = vhdx_probe,
1053     .bdrv_open              = vhdx_open,
1054     .bdrv_close             = vhdx_close,
1055     .bdrv_reopen_prepare    = vhdx_reopen_prepare,
1056     .bdrv_co_readv          = vhdx_co_readv,
1057     .bdrv_co_writev         = vhdx_co_writev,
1058 };
1059
1060 static void bdrv_vhdx_init(void)
1061 {
1062     bdrv_register(&bdrv_vhdx);
1063 }
1064
1065 block_init(bdrv_vhdx_init);
This page took 0.08523 seconds and 4 git commands to generate.