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