xref: /openbmc/qemu/block/vpc.c (revision a4b740db)
1 /*
2  * Block driver for Connectix / Microsoft Virtual PC images
3  *
4  * Copyright (c) 2005 Alex Beregszaszi
5  * Copyright (c) 2009 Kevin Wolf <kwolf@suse.de>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 
26 #include "qemu/osdep.h"
27 #include "qapi/error.h"
28 #include "block/block_int.h"
29 #include "block/qdict.h"
30 #include "sysemu/block-backend.h"
31 #include "qemu/module.h"
32 #include "qemu/option.h"
33 #include "migration/blocker.h"
34 #include "qemu/bswap.h"
35 #include "qemu/uuid.h"
36 #include "qemu/memalign.h"
37 #include "qapi/qmp/qdict.h"
38 #include "qapi/qobject-input-visitor.h"
39 #include "qapi/qapi-visit-block-core.h"
40 
41 /**************************************************************/
42 
43 //#define CACHE
44 
45 enum vhd_type {
46     VHD_FIXED           = 2,
47     VHD_DYNAMIC         = 3,
48     VHD_DIFFERENCING    = 4,
49 };
50 
51 /* Seconds since Jan 1, 2000 0:00:00 (UTC) */
52 #define VHD_TIMESTAMP_BASE 946684800
53 
54 #define VHD_CHS_MAX_C   65535LL
55 #define VHD_CHS_MAX_H   16
56 #define VHD_CHS_MAX_S   255
57 
58 #define VHD_MAX_SECTORS       0xff000000    /* 2040 GiB max image size */
59 #define VHD_MAX_GEOMETRY      (VHD_CHS_MAX_C * VHD_CHS_MAX_H * VHD_CHS_MAX_S)
60 
61 #define VPC_OPT_FORCE_SIZE "force_size"
62 
63 /* always big-endian */
64 typedef struct vhd_footer {
65     char        creator[8]; /* "conectix" */
66     uint32_t    features;
67     uint32_t    version;
68 
69     /* Offset of next header structure, 0xFFFFFFFF if none */
70     uint64_t    data_offset;
71 
72     /* Seconds since Jan 1, 2000 0:00:00 (UTC) */
73     uint32_t    timestamp;
74 
75     char        creator_app[4]; /*  e.g., "vpc " */
76     uint16_t    major;
77     uint16_t    minor;
78     char        creator_os[4]; /* "Wi2k" */
79 
80     uint64_t    orig_size;
81     uint64_t    current_size;
82 
83     uint16_t    cyls;
84     uint8_t     heads;
85     uint8_t     secs_per_cyl;
86 
87     uint32_t    type;
88 
89     /* Checksum of the Hard Disk Footer ("one's complement of the sum of all
90        the bytes in the footer without the checksum field") */
91     uint32_t    checksum;
92 
93     /* UUID used to identify a parent hard disk (backing file) */
94     QemuUUID    uuid;
95 
96     uint8_t     in_saved_state;
97     uint8_t     reserved[427];
98 } QEMU_PACKED VHDFooter;
99 
100 QEMU_BUILD_BUG_ON(sizeof(VHDFooter) != 512);
101 
102 typedef struct vhd_dyndisk_header {
103     char        magic[8]; /* "cxsparse" */
104 
105     /* Offset of next header structure, 0xFFFFFFFF if none */
106     uint64_t    data_offset;
107 
108     /* Offset of the Block Allocation Table (BAT) */
109     uint64_t    table_offset;
110 
111     uint32_t    version;
112     uint32_t    max_table_entries; /* 32bit/entry */
113 
114     /* 2 MB by default, must be a power of two */
115     uint32_t    block_size;
116 
117     uint32_t    checksum;
118     uint8_t     parent_uuid[16];
119     uint32_t    parent_timestamp;
120     uint32_t    reserved;
121 
122     /* Backing file name (in UTF-16) */
123     uint8_t     parent_name[512];
124 
125     struct {
126         uint32_t    platform;
127         uint32_t    data_space;
128         uint32_t    data_length;
129         uint32_t    reserved;
130         uint64_t    data_offset;
131     } parent_locator[8];
132     uint8_t     reserved2[256];
133 } QEMU_PACKED VHDDynDiskHeader;
134 
135 QEMU_BUILD_BUG_ON(sizeof(VHDDynDiskHeader) != 1024);
136 
137 typedef struct BDRVVPCState {
138     CoMutex lock;
139     VHDFooter footer;
140     uint64_t free_data_block_offset;
141     int max_table_entries;
142     uint32_t *pagetable;
143     uint64_t bat_offset;
144     uint64_t last_bitmap_offset;
145 
146     uint32_t block_size;
147     uint32_t bitmap_size;
148     bool force_use_chs;
149     bool force_use_sz;
150 
151 #ifdef CACHE
152     uint8_t *pageentry_u8;
153     uint32_t *pageentry_u32;
154     uint16_t *pageentry_u16;
155 
156     uint64_t last_bitmap;
157 #endif
158 
159     Error *migration_blocker;
160 } BDRVVPCState;
161 
162 #define VPC_OPT_SIZE_CALC "force_size_calc"
163 static QemuOptsList vpc_runtime_opts = {
164     .name = "vpc-runtime-opts",
165     .head = QTAILQ_HEAD_INITIALIZER(vpc_runtime_opts.head),
166     .desc = {
167         {
168             .name = VPC_OPT_SIZE_CALC,
169             .type = QEMU_OPT_STRING,
170             .help = "Force disk size calculation to use either CHS geometry, "
171                     "or use the disk current_size specified in the VHD footer. "
172                     "{chs, current_size}"
173         },
174         { /* end of list */ }
175     }
176 };
177 
178 static QemuOptsList vpc_create_opts;
179 
vpc_checksum(void * p,size_t size)180 static uint32_t vpc_checksum(void *p, size_t size)
181 {
182     uint8_t *buf = p;
183     uint32_t res = 0;
184     int i;
185 
186     for (i = 0; i < size; i++)
187         res += buf[i];
188 
189     return ~res;
190 }
191 
192 
vpc_probe(const uint8_t * buf,int buf_size,const char * filename)193 static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
194 {
195     if (buf_size >= 8 && !strncmp((char *)buf, "conectix", 8))
196         return 100;
197     return 0;
198 }
199 
vpc_parse_options(BlockDriverState * bs,QemuOpts * opts,Error ** errp)200 static void vpc_parse_options(BlockDriverState *bs, QemuOpts *opts,
201                               Error **errp)
202 {
203     BDRVVPCState *s = bs->opaque;
204     const char *size_calc;
205 
206     size_calc = qemu_opt_get(opts, VPC_OPT_SIZE_CALC);
207 
208     if (!size_calc) {
209        /* no override, use autodetect only */
210     } else if (!strcmp(size_calc, "current_size")) {
211         s->force_use_sz = true;
212     } else if (!strcmp(size_calc, "chs")) {
213         s->force_use_chs = true;
214     } else {
215         error_setg(errp, "Invalid size calculation mode: '%s'", size_calc);
216     }
217 }
218 
vpc_open(BlockDriverState * bs,QDict * options,int flags,Error ** errp)219 static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
220                     Error **errp)
221 {
222     BDRVVPCState *s = bs->opaque;
223     int i;
224     VHDFooter *footer;
225     QemuOpts *opts = NULL;
226     Error *local_err = NULL;
227     bool use_chs;
228     VHDDynDiskHeader dyndisk_header;
229     uint32_t checksum;
230     uint64_t computed_size;
231     uint64_t pagetable_size;
232     int disk_type = VHD_DYNAMIC;
233     int ret;
234     int64_t bs_size;
235 
236     ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
237     if (ret < 0) {
238         return ret;
239     }
240 
241     GRAPH_RDLOCK_GUARD_MAINLOOP();
242 
243     opts = qemu_opts_create(&vpc_runtime_opts, NULL, 0, &error_abort);
244     if (!qemu_opts_absorb_qdict(opts, options, errp)) {
245         ret = -EINVAL;
246         goto fail;
247     }
248 
249     vpc_parse_options(bs, opts, &local_err);
250     if (local_err) {
251         error_propagate(errp, local_err);
252         ret = -EINVAL;
253         goto fail;
254     }
255 
256     ret = bdrv_pread(bs->file, 0, sizeof(s->footer), &s->footer, 0);
257     if (ret < 0) {
258         error_setg(errp, "Unable to read VHD header");
259         goto fail;
260     }
261 
262     footer = &s->footer;
263     if (strncmp(footer->creator, "conectix", 8)) {
264         int64_t offset = bdrv_getlength(bs->file->bs);
265         if (offset < 0) {
266             ret = offset;
267             error_setg(errp, "Invalid file size");
268             goto fail;
269         } else if (offset < sizeof(*footer)) {
270             ret = -EINVAL;
271             error_setg(errp, "File too small for a VHD header");
272             goto fail;
273         }
274 
275         /* If a fixed disk, the footer is found only at the end of the file */
276         ret = bdrv_pread(bs->file, offset - sizeof(*footer), sizeof(*footer),
277                          footer, 0);
278         if (ret < 0) {
279             goto fail;
280         }
281         if (strncmp(footer->creator, "conectix", 8) ||
282             be32_to_cpu(footer->type) != VHD_FIXED) {
283             error_setg(errp, "invalid VPC image");
284             ret = -EINVAL;
285             goto fail;
286         }
287         disk_type = VHD_FIXED;
288     }
289 
290     checksum = be32_to_cpu(footer->checksum);
291     footer->checksum = 0;
292     if (vpc_checksum(footer, sizeof(*footer)) != checksum) {
293         error_setg(errp, "Incorrect header checksum");
294         ret = -EINVAL;
295         goto fail;
296     }
297 
298     /* Write 'checksum' back to footer, or else will leave it with zero. */
299     footer->checksum = cpu_to_be32(checksum);
300 
301     /* The visible size of a image in Virtual PC depends on the geometry
302        rather than on the size stored in the footer (the size in the footer
303        is too large usually) */
304     bs->total_sectors = (int64_t)
305         be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
306 
307     /* Microsoft Virtual PC and Microsoft Hyper-V produce and read
308      * VHD image sizes differently.  VPC will rely on CHS geometry,
309      * while Hyper-V and disk2vhd use the size specified in the footer.
310      *
311      * We use a couple of approaches to try and determine the correct method:
312      * look at the Creator App field, and look for images that have CHS
313      * geometry that is the maximum value.
314      *
315      * If the CHS geometry is the maximum CHS geometry, then we assume that
316      * the size is the footer->current_size to avoid truncation.  Otherwise,
317      * we follow the table based on footer->creator_app:
318      *
319      *  Known creator apps:
320      *      'vpc '  :  CHS              Virtual PC (uses disk geometry)
321      *      'qemu'  :  CHS              QEMU (uses disk geometry)
322      *      'qem2'  :  current_size     QEMU (uses current_size)
323      *      'win '  :  current_size     Hyper-V
324      *      'd2v '  :  current_size     Disk2vhd
325      *      'tap\0' :  current_size     XenServer
326      *      'CTXS'  :  current_size     XenConverter
327      *
328      *  The user can override the table values via drive options, however
329      *  even with an override we will still use current_size for images
330      *  that have CHS geometry of the maximum size.
331      */
332     use_chs = (!!strncmp(footer->creator_app, "win ", 4) &&
333                !!strncmp(footer->creator_app, "qem2", 4) &&
334                !!strncmp(footer->creator_app, "d2v ", 4) &&
335                !!strncmp(footer->creator_app, "CTXS", 4) &&
336                !!memcmp(footer->creator_app, "tap", 4)) || s->force_use_chs;
337 
338     if (!use_chs || bs->total_sectors == VHD_MAX_GEOMETRY || s->force_use_sz) {
339         bs->total_sectors = be64_to_cpu(footer->current_size) /
340                                         BDRV_SECTOR_SIZE;
341     }
342 
343     /* Allow a maximum disk size of 2040 GiB */
344     if (bs->total_sectors > VHD_MAX_SECTORS) {
345         ret = -EFBIG;
346         goto fail;
347     }
348 
349     if (disk_type == VHD_DYNAMIC) {
350         ret = bdrv_pread(bs->file, be64_to_cpu(footer->data_offset),
351                          sizeof(dyndisk_header), &dyndisk_header, 0);
352         if (ret < 0) {
353             error_setg(errp, "Error reading dynamic VHD header");
354             goto fail;
355         }
356 
357         if (strncmp(dyndisk_header.magic, "cxsparse", 8)) {
358             error_setg(errp, "Invalid header magic");
359             ret = -EINVAL;
360             goto fail;
361         }
362 
363         s->block_size = be32_to_cpu(dyndisk_header.block_size);
364         if (!is_power_of_2(s->block_size) || s->block_size < BDRV_SECTOR_SIZE) {
365             error_setg(errp, "Invalid block size %" PRIu32, s->block_size);
366             ret = -EINVAL;
367             goto fail;
368         }
369         s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;
370 
371         s->max_table_entries = be32_to_cpu(dyndisk_header.max_table_entries);
372 
373         if ((bs->total_sectors * 512) / s->block_size > 0xffffffffU) {
374             error_setg(errp, "Too many blocks");
375             ret = -EINVAL;
376             goto fail;
377         }
378 
379         computed_size = (uint64_t) s->max_table_entries * s->block_size;
380         if (computed_size < bs->total_sectors * 512) {
381             error_setg(errp, "Page table too small");
382             ret = -EINVAL;
383             goto fail;
384         }
385 
386         if (s->max_table_entries > SIZE_MAX / 4 ||
387             s->max_table_entries > (int) INT_MAX / 4) {
388             error_setg(errp, "Max Table Entries too large (%" PRId32 ")",
389                         s->max_table_entries);
390             ret = -EINVAL;
391             goto fail;
392         }
393 
394         pagetable_size = (uint64_t) s->max_table_entries * 4;
395 
396         s->pagetable = qemu_try_blockalign(bs->file->bs, pagetable_size);
397         if (s->pagetable == NULL) {
398             error_setg(errp, "Unable to allocate memory for page table");
399             ret = -ENOMEM;
400             goto fail;
401         }
402 
403         s->bat_offset = be64_to_cpu(dyndisk_header.table_offset);
404 
405         ret = bdrv_pread(bs->file, s->bat_offset, pagetable_size,
406                          s->pagetable, 0);
407         if (ret < 0) {
408             error_setg(errp, "Error reading pagetable");
409             goto fail;
410         }
411 
412         s->free_data_block_offset =
413             ROUND_UP(s->bat_offset + pagetable_size, 512);
414 
415         for (i = 0; i < s->max_table_entries; i++) {
416             be32_to_cpus(&s->pagetable[i]);
417             if (s->pagetable[i] != 0xFFFFFFFF) {
418                 int64_t next = (512 * (int64_t) s->pagetable[i]) +
419                     s->bitmap_size + s->block_size;
420 
421                 if (next > s->free_data_block_offset) {
422                     s->free_data_block_offset = next;
423                 }
424             }
425         }
426 
427         bs_size = bdrv_getlength(bs->file->bs);
428         if (bs_size < 0) {
429             error_setg_errno(errp, -bs_size, "Unable to learn image size");
430             ret = bs_size;
431             goto fail;
432         }
433         if (s->free_data_block_offset > bs_size) {
434             error_setg(errp, "block-vpc: free_data_block_offset points after "
435                              "the end of file. The image has been truncated.");
436             ret = -EINVAL;
437             goto fail;
438         }
439 
440         s->last_bitmap_offset = (int64_t) -1;
441 
442 #ifdef CACHE
443         s->pageentry_u8 = g_malloc(512);
444         s->pageentry_u32 = s->pageentry_u8;
445         s->pageentry_u16 = s->pageentry_u8;
446         s->last_pagetable = -1;
447 #endif
448     }
449 
450     /* Disable migration when VHD images are used */
451     error_setg(&s->migration_blocker, "The vpc format used by node '%s' "
452                "does not support live migration",
453                bdrv_get_device_or_node_name(bs));
454 
455     ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
456     if (ret < 0) {
457         goto fail;
458     }
459 
460     qemu_co_mutex_init(&s->lock);
461     qemu_opts_del(opts);
462 
463     return 0;
464 
465 fail:
466     qemu_opts_del(opts);
467     qemu_vfree(s->pagetable);
468 #ifdef CACHE
469     g_free(s->pageentry_u8);
470 #endif
471     return ret;
472 }
473 
vpc_reopen_prepare(BDRVReopenState * state,BlockReopenQueue * queue,Error ** errp)474 static int vpc_reopen_prepare(BDRVReopenState *state,
475                               BlockReopenQueue *queue, Error **errp)
476 {
477     return 0;
478 }
479 
480 /*
481  * Returns the absolute byte offset of the given sector in the image file.
482  * If the sector is not allocated, -1 is returned instead.
483  * If an error occurred trying to write an updated block bitmap back to
484  * the file, -2 is returned, and the error value is written to *err.
485  * This can only happen for a write operation.
486  *
487  * The parameter write must be 1 if the offset will be used for a write
488  * operation (the block bitmaps is updated then), 0 otherwise.
489  * If write is true then err must not be NULL.
490  */
491 static int64_t coroutine_fn GRAPH_RDLOCK
get_image_offset(BlockDriverState * bs,uint64_t offset,bool write,int * err)492 get_image_offset(BlockDriverState *bs, uint64_t offset, bool write, int *err)
493 {
494     BDRVVPCState *s = bs->opaque;
495     uint64_t bitmap_offset, block_offset;
496     uint32_t pagetable_index, offset_in_block;
497 
498     assert(!(write && err == NULL));
499 
500     pagetable_index = offset / s->block_size;
501     offset_in_block = offset % s->block_size;
502 
503     if (pagetable_index >= s->max_table_entries || s->pagetable[pagetable_index] == 0xffffffff)
504         return -1; /* not allocated */
505 
506     bitmap_offset = 512 * (uint64_t) s->pagetable[pagetable_index];
507     block_offset = bitmap_offset + s->bitmap_size + offset_in_block;
508 
509     /* We must ensure that we don't write to any sectors which are marked as
510        unused in the bitmap. We get away with setting all bits in the block
511        bitmap each time we write to a new block. This might cause Virtual PC to
512        miss sparse read optimization, but it's not a problem in terms of
513        correctness. */
514     if (write && (s->last_bitmap_offset != bitmap_offset)) {
515         g_autofree uint8_t *bitmap = g_malloc(s->bitmap_size);
516         int r;
517 
518         s->last_bitmap_offset = bitmap_offset;
519         memset(bitmap, 0xff, s->bitmap_size);
520         r = bdrv_co_pwrite_sync(bs->file, bitmap_offset, s->bitmap_size, bitmap, 0);
521         if (r < 0) {
522             *err = r;
523             return -2;
524         }
525     }
526 
527     return block_offset;
528 }
529 
530 /*
531  * Writes the footer to the end of the image file. This is needed when the
532  * file grows as it overwrites the old footer
533  *
534  * Returns 0 on success and < 0 on error
535  */
rewrite_footer(BlockDriverState * bs)536 static int coroutine_fn GRAPH_RDLOCK rewrite_footer(BlockDriverState *bs)
537 {
538     int ret;
539     BDRVVPCState *s = bs->opaque;
540     int64_t offset = s->free_data_block_offset;
541 
542     ret = bdrv_co_pwrite_sync(bs->file, offset, sizeof(s->footer), &s->footer, 0);
543     if (ret < 0)
544         return ret;
545 
546     return 0;
547 }
548 
549 /*
550  * Allocates a new block. This involves writing a new footer and updating
551  * the Block Allocation Table to use the space at the old end of the image
552  * file (overwriting the old footer)
553  *
554  * Returns the sectors' offset in the image file on success and < 0 on error
555  */
556 static int64_t coroutine_fn GRAPH_RDLOCK
alloc_block(BlockDriverState * bs,int64_t offset)557 alloc_block(BlockDriverState *bs, int64_t offset)
558 {
559     BDRVVPCState *s = bs->opaque;
560     int64_t bat_offset;
561     uint32_t index, bat_value;
562     int ret;
563     g_autofree uint8_t *bitmap = g_malloc(s->bitmap_size);
564 
565     /* Check if sector_num is valid */
566     if ((offset < 0) || (offset > bs->total_sectors * BDRV_SECTOR_SIZE)) {
567         return -EINVAL;
568     }
569 
570     /* Write entry into in-memory BAT */
571     index = offset / s->block_size;
572     assert(s->pagetable[index] == 0xFFFFFFFF);
573     s->pagetable[index] = s->free_data_block_offset / 512;
574 
575     /* Initialize the block's bitmap */
576     memset(bitmap, 0xff, s->bitmap_size);
577     ret = bdrv_co_pwrite_sync(bs->file, s->free_data_block_offset,
578                               s->bitmap_size, bitmap, 0);
579     if (ret < 0) {
580         return ret;
581     }
582 
583     /* Write new footer (the old one will be overwritten) */
584     s->free_data_block_offset += s->block_size + s->bitmap_size;
585     ret = rewrite_footer(bs);
586     if (ret < 0)
587         goto fail;
588 
589     /* Write BAT entry to disk */
590     bat_offset = s->bat_offset + (4 * index);
591     bat_value = cpu_to_be32(s->pagetable[index]);
592     ret = bdrv_co_pwrite_sync(bs->file, bat_offset, 4, &bat_value, 0);
593     if (ret < 0)
594         goto fail;
595 
596     return get_image_offset(bs, offset, false, NULL);
597 
598 fail:
599     s->free_data_block_offset -= (s->block_size + s->bitmap_size);
600     return ret;
601 }
602 
603 static int coroutine_fn
vpc_co_get_info(BlockDriverState * bs,BlockDriverInfo * bdi)604 vpc_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
605 {
606     BDRVVPCState *s = (BDRVVPCState *)bs->opaque;
607 
608     if (be32_to_cpu(s->footer.type) != VHD_FIXED) {
609         bdi->cluster_size = s->block_size;
610     }
611 
612     return 0;
613 }
614 
615 static int coroutine_fn GRAPH_RDLOCK
vpc_co_preadv(BlockDriverState * bs,int64_t offset,int64_t bytes,QEMUIOVector * qiov,BdrvRequestFlags flags)616 vpc_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
617               QEMUIOVector *qiov, BdrvRequestFlags flags)
618 {
619     BDRVVPCState *s = bs->opaque;
620     int ret;
621     int64_t image_offset;
622     int64_t n_bytes;
623     int64_t bytes_done = 0;
624     QEMUIOVector local_qiov;
625 
626     if (be32_to_cpu(s->footer.type) == VHD_FIXED) {
627         return bdrv_co_preadv(bs->file, offset, bytes, qiov, 0);
628     }
629 
630     qemu_co_mutex_lock(&s->lock);
631     qemu_iovec_init(&local_qiov, qiov->niov);
632 
633     while (bytes > 0) {
634         image_offset = get_image_offset(bs, offset, false, NULL);
635         n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
636 
637         if (image_offset == -1) {
638             qemu_iovec_memset(qiov, bytes_done, 0, n_bytes);
639         } else {
640             qemu_iovec_reset(&local_qiov);
641             qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
642 
643             qemu_co_mutex_unlock(&s->lock);
644             ret = bdrv_co_preadv(bs->file, image_offset, n_bytes,
645                                  &local_qiov, 0);
646             qemu_co_mutex_lock(&s->lock);
647             if (ret < 0) {
648                 goto fail;
649             }
650         }
651 
652         bytes -= n_bytes;
653         offset += n_bytes;
654         bytes_done += n_bytes;
655     }
656 
657     ret = 0;
658 fail:
659     qemu_iovec_destroy(&local_qiov);
660     qemu_co_mutex_unlock(&s->lock);
661 
662     return ret;
663 }
664 
665 static int coroutine_fn GRAPH_RDLOCK
vpc_co_pwritev(BlockDriverState * bs,int64_t offset,int64_t bytes,QEMUIOVector * qiov,BdrvRequestFlags flags)666 vpc_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
667                QEMUIOVector *qiov, BdrvRequestFlags flags)
668 {
669     BDRVVPCState *s = bs->opaque;
670     int64_t image_offset;
671     int64_t n_bytes;
672     int64_t bytes_done = 0;
673     int ret = 0;
674     QEMUIOVector local_qiov;
675 
676     if (be32_to_cpu(s->footer.type) == VHD_FIXED) {
677         return bdrv_co_pwritev(bs->file, offset, bytes, qiov, 0);
678     }
679 
680     qemu_co_mutex_lock(&s->lock);
681     qemu_iovec_init(&local_qiov, qiov->niov);
682 
683     while (bytes > 0) {
684         image_offset = get_image_offset(bs, offset, true, &ret);
685         if (image_offset == -2) {
686             /* Failed to write block bitmap: can't proceed with write */
687             goto fail;
688         }
689         n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
690 
691         if (image_offset == -1) {
692             image_offset = alloc_block(bs, offset);
693             if (image_offset < 0) {
694                 ret = image_offset;
695                 goto fail;
696             }
697         }
698 
699         qemu_iovec_reset(&local_qiov);
700         qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
701 
702         qemu_co_mutex_unlock(&s->lock);
703         ret = bdrv_co_pwritev(bs->file, image_offset, n_bytes,
704                               &local_qiov, 0);
705         qemu_co_mutex_lock(&s->lock);
706         if (ret < 0) {
707             goto fail;
708         }
709 
710         bytes -= n_bytes;
711         offset += n_bytes;
712         bytes_done += n_bytes;
713     }
714 
715     ret = 0;
716 fail:
717     qemu_iovec_destroy(&local_qiov);
718     qemu_co_mutex_unlock(&s->lock);
719 
720     return ret;
721 }
722 
723 static int coroutine_fn GRAPH_RDLOCK
vpc_co_block_status(BlockDriverState * bs,bool want_zero,int64_t offset,int64_t bytes,int64_t * pnum,int64_t * map,BlockDriverState ** file)724 vpc_co_block_status(BlockDriverState *bs, bool want_zero,
725                     int64_t offset, int64_t bytes,
726                     int64_t *pnum, int64_t *map,
727                     BlockDriverState **file)
728 {
729     BDRVVPCState *s = bs->opaque;
730     int64_t image_offset;
731     bool allocated;
732     int ret;
733     int64_t n;
734 
735     if (be32_to_cpu(s->footer.type) == VHD_FIXED) {
736         *pnum = bytes;
737         *map = offset;
738         *file = bs->file->bs;
739         return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_RECURSE;
740     }
741 
742     qemu_co_mutex_lock(&s->lock);
743 
744     image_offset = get_image_offset(bs, offset, false, NULL);
745     allocated = (image_offset != -1);
746     *pnum = 0;
747     ret = BDRV_BLOCK_ZERO;
748 
749     do {
750         /* All sectors in a block are contiguous (without using the bitmap) */
751         n = ROUND_UP(offset + 1, s->block_size) - offset;
752         n = MIN(n, bytes);
753 
754         *pnum += n;
755         offset += n;
756         bytes -= n;
757         /* *pnum can't be greater than one block for allocated
758          * sectors since there is always a bitmap in between. */
759         if (allocated) {
760             *file = bs->file->bs;
761             *map = image_offset;
762             ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
763             break;
764         }
765         if (bytes == 0) {
766             break;
767         }
768         image_offset = get_image_offset(bs, offset, false, NULL);
769     } while (image_offset == -1);
770 
771     qemu_co_mutex_unlock(&s->lock);
772     return ret;
773 }
774 
775 /*
776  * Calculates the number of cylinders, heads and sectors per cylinder
777  * based on a given number of sectors. This is the algorithm described
778  * in the VHD specification.
779  *
780  * Note that the geometry doesn't always exactly match total_sectors but
781  * may round it down.
782  *
783  * Returns 0 on success, -EFBIG if the size is larger than 2040 GiB. Override
784  * the hardware EIDE and ATA-2 limit of 16 heads (max disk size of 127 GB)
785  * and instead allow up to 255 heads.
786  */
calculate_geometry(int64_t total_sectors,uint16_t * cyls,uint8_t * heads,uint8_t * secs_per_cyl)787 static int calculate_geometry(int64_t total_sectors, uint16_t *cyls,
788     uint8_t *heads, uint8_t *secs_per_cyl)
789 {
790     uint32_t cyls_times_heads;
791 
792     total_sectors = MIN(total_sectors, VHD_MAX_GEOMETRY);
793 
794     if (total_sectors >= 65535LL * 16 * 63) {
795         *secs_per_cyl = 255;
796         *heads = 16;
797         cyls_times_heads = total_sectors / *secs_per_cyl;
798     } else {
799         *secs_per_cyl = 17;
800         cyls_times_heads = total_sectors / *secs_per_cyl;
801         *heads = DIV_ROUND_UP(cyls_times_heads, 1024);
802 
803         if (*heads < 4) {
804             *heads = 4;
805         }
806 
807         if (cyls_times_heads >= (*heads * 1024) || *heads > 16) {
808             *secs_per_cyl = 31;
809             *heads = 16;
810             cyls_times_heads = total_sectors / *secs_per_cyl;
811         }
812 
813         if (cyls_times_heads >= (*heads * 1024)) {
814             *secs_per_cyl = 63;
815             *heads = 16;
816             cyls_times_heads = total_sectors / *secs_per_cyl;
817         }
818     }
819 
820     *cyls = cyls_times_heads / *heads;
821 
822     return 0;
823 }
824 
create_dynamic_disk(BlockBackend * blk,VHDFooter * footer,int64_t total_sectors)825 static int coroutine_fn create_dynamic_disk(BlockBackend *blk, VHDFooter *footer,
826                                             int64_t total_sectors)
827 {
828     VHDDynDiskHeader dyndisk_header;
829     uint8_t bat_sector[512];
830     size_t block_size, num_bat_entries;
831     int i;
832     int ret;
833     int64_t offset = 0;
834 
835     /* Write the footer (twice: at the beginning and at the end) */
836     block_size = 0x200000;
837     num_bat_entries = DIV_ROUND_UP(total_sectors, block_size / 512);
838 
839     ret = blk_co_pwrite(blk, offset, sizeof(*footer), footer, 0);
840     if (ret < 0) {
841         goto fail;
842     }
843 
844     offset = 1536 + ((num_bat_entries * 4 + 511) & ~511);
845     ret = blk_co_pwrite(blk, offset, sizeof(*footer), footer, 0);
846     if (ret < 0) {
847         goto fail;
848     }
849 
850     /* Write the initial BAT */
851     offset = 3 * 512;
852 
853     memset(bat_sector, 0xFF, 512);
854     for (i = 0; i < DIV_ROUND_UP(num_bat_entries * 4, 512); i++) {
855         ret = blk_co_pwrite(blk, offset, 512, bat_sector, 0);
856         if (ret < 0) {
857             goto fail;
858         }
859         offset += 512;
860     }
861 
862     /* Prepare the Dynamic Disk Header */
863     memset(&dyndisk_header, 0, sizeof(dyndisk_header));
864 
865     memcpy(dyndisk_header.magic, "cxsparse", 8);
866 
867     /*
868      * Note: The spec is actually wrong here for data_offset, it says
869      * 0xFFFFFFFF, but MS tools expect all 64 bits to be set.
870      */
871     dyndisk_header.data_offset = cpu_to_be64(0xFFFFFFFFFFFFFFFFULL);
872     dyndisk_header.table_offset = cpu_to_be64(3 * 512);
873     dyndisk_header.version = cpu_to_be32(0x00010000);
874     dyndisk_header.block_size = cpu_to_be32(block_size);
875     dyndisk_header.max_table_entries = cpu_to_be32(num_bat_entries);
876 
877     dyndisk_header.checksum = cpu_to_be32(
878         vpc_checksum(&dyndisk_header, sizeof(dyndisk_header)));
879 
880     /* Write the header */
881     offset = 512;
882 
883     ret = blk_co_pwrite(blk, offset, sizeof(dyndisk_header), &dyndisk_header, 0);
884     if (ret < 0) {
885         goto fail;
886     }
887 
888     ret = 0;
889  fail:
890     return ret;
891 }
892 
create_fixed_disk(BlockBackend * blk,VHDFooter * footer,int64_t total_size,Error ** errp)893 static int coroutine_fn create_fixed_disk(BlockBackend *blk, VHDFooter *footer,
894                                           int64_t total_size, Error **errp)
895 {
896     int ret;
897 
898     /* Add footer to total size */
899     total_size += sizeof(*footer);
900 
901     ret = blk_co_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
902     if (ret < 0) {
903         return ret;
904     }
905 
906     ret = blk_co_pwrite(blk, total_size - sizeof(*footer), sizeof(*footer),
907                         footer, 0);
908     if (ret < 0) {
909         error_setg_errno(errp, -ret, "Unable to write VHD header");
910         return ret;
911     }
912 
913     return 0;
914 }
915 
calculate_rounded_image_size(BlockdevCreateOptionsVpc * vpc_opts,uint16_t * out_cyls,uint8_t * out_heads,uint8_t * out_secs_per_cyl,int64_t * out_total_sectors,Error ** errp)916 static int calculate_rounded_image_size(BlockdevCreateOptionsVpc *vpc_opts,
917                                         uint16_t *out_cyls,
918                                         uint8_t *out_heads,
919                                         uint8_t *out_secs_per_cyl,
920                                         int64_t *out_total_sectors,
921                                         Error **errp)
922 {
923     int64_t total_size = vpc_opts->size;
924     uint16_t cyls = 0;
925     uint8_t heads = 0;
926     uint8_t secs_per_cyl = 0;
927     int64_t total_sectors;
928     int i;
929 
930     /*
931      * Calculate matching total_size and geometry. Increase the number of
932      * sectors requested until we get enough (or fail). This ensures that
933      * qemu-img convert doesn't truncate images, but rather rounds up.
934      *
935      * If the image size can't be represented by a spec conformant CHS geometry,
936      * we set the geometry to 65535 x 16 x 255 (CxHxS) sectors and use
937      * the image size from the VHD footer to calculate total_sectors.
938      */
939     if (vpc_opts->force_size) {
940         /* This will force the use of total_size for sector count, below */
941         cyls         = VHD_CHS_MAX_C;
942         heads        = VHD_CHS_MAX_H;
943         secs_per_cyl = VHD_CHS_MAX_S;
944     } else {
945         total_sectors = MIN(VHD_MAX_GEOMETRY, total_size / BDRV_SECTOR_SIZE);
946         for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {
947             calculate_geometry(total_sectors + i, &cyls, &heads, &secs_per_cyl);
948         }
949     }
950 
951     if ((int64_t)cyls * heads * secs_per_cyl == VHD_MAX_GEOMETRY) {
952         total_sectors = total_size / BDRV_SECTOR_SIZE;
953         /* Allow a maximum disk size of 2040 GiB */
954         if (total_sectors > VHD_MAX_SECTORS) {
955             error_setg(errp, "Disk size is too large, max size is 2040 GiB");
956             return -EFBIG;
957         }
958     } else {
959         total_sectors = (int64_t) cyls * heads * secs_per_cyl;
960     }
961 
962     *out_total_sectors = total_sectors;
963     if (out_cyls) {
964         *out_cyls = cyls;
965         *out_heads = heads;
966         *out_secs_per_cyl = secs_per_cyl;
967     }
968 
969     return 0;
970 }
971 
972 static int coroutine_fn GRAPH_UNLOCKED
vpc_co_create(BlockdevCreateOptions * opts,Error ** errp)973 vpc_co_create(BlockdevCreateOptions *opts, Error **errp)
974 {
975     BlockdevCreateOptionsVpc *vpc_opts;
976     BlockBackend *blk = NULL;
977     BlockDriverState *bs = NULL;
978 
979     VHDFooter footer;
980     uint16_t cyls = 0;
981     uint8_t heads = 0;
982     uint8_t secs_per_cyl = 0;
983     int64_t total_sectors;
984     int64_t total_size;
985     int disk_type;
986     int ret = -EIO;
987     QemuUUID uuid;
988 
989     assert(opts->driver == BLOCKDEV_DRIVER_VPC);
990     vpc_opts = &opts->u.vpc;
991 
992     /* Validate options and set default values */
993     total_size = vpc_opts->size;
994 
995     if (!vpc_opts->has_subformat) {
996         vpc_opts->subformat = BLOCKDEV_VPC_SUBFORMAT_DYNAMIC;
997     }
998     switch (vpc_opts->subformat) {
999     case BLOCKDEV_VPC_SUBFORMAT_DYNAMIC:
1000         disk_type = VHD_DYNAMIC;
1001         break;
1002     case BLOCKDEV_VPC_SUBFORMAT_FIXED:
1003         disk_type = VHD_FIXED;
1004         break;
1005     default:
1006         g_assert_not_reached();
1007     }
1008 
1009     /* Create BlockBackend to write to the image */
1010     bs = bdrv_co_open_blockdev_ref(vpc_opts->file, errp);
1011     if (bs == NULL) {
1012         return -EIO;
1013     }
1014 
1015     blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
1016                              errp);
1017     if (!blk) {
1018         ret = -EPERM;
1019         goto out;
1020     }
1021     blk_set_allow_write_beyond_eof(blk, true);
1022 
1023     /* Get geometry and check that it matches the image size*/
1024     ret = calculate_rounded_image_size(vpc_opts, &cyls, &heads, &secs_per_cyl,
1025                                        &total_sectors, errp);
1026     if (ret < 0) {
1027         goto out;
1028     }
1029 
1030     if (total_size != total_sectors * BDRV_SECTOR_SIZE) {
1031         error_setg(errp, "The requested image size cannot be represented in "
1032                          "CHS geometry");
1033         error_append_hint(errp, "Try size=%llu or force-size=on (the "
1034                                 "latter makes the image incompatible with "
1035                                 "Virtual PC)",
1036                           total_sectors * BDRV_SECTOR_SIZE);
1037         ret = -EINVAL;
1038         goto out;
1039     }
1040 
1041     /* Prepare the Hard Disk Footer */
1042     memset(&footer, 0, sizeof(footer));
1043 
1044     memcpy(footer.creator, "conectix", 8);
1045     if (vpc_opts->force_size) {
1046         memcpy(footer.creator_app, "qem2", 4);
1047     } else {
1048         memcpy(footer.creator_app, "qemu", 4);
1049     }
1050     memcpy(footer.creator_os, "Wi2k", 4);
1051 
1052     footer.features = cpu_to_be32(0x02);
1053     footer.version = cpu_to_be32(0x00010000);
1054     if (disk_type == VHD_DYNAMIC) {
1055         footer.data_offset = cpu_to_be64(sizeof(footer));
1056     } else {
1057         footer.data_offset = cpu_to_be64(0xFFFFFFFFFFFFFFFFULL);
1058     }
1059     footer.timestamp = cpu_to_be32(time(NULL) - VHD_TIMESTAMP_BASE);
1060 
1061     /* Version of Virtual PC 2007 */
1062     footer.major = cpu_to_be16(0x0005);
1063     footer.minor = cpu_to_be16(0x0003);
1064     footer.orig_size = cpu_to_be64(total_size);
1065     footer.current_size = cpu_to_be64(total_size);
1066     footer.cyls = cpu_to_be16(cyls);
1067     footer.heads = heads;
1068     footer.secs_per_cyl = secs_per_cyl;
1069 
1070     footer.type = cpu_to_be32(disk_type);
1071 
1072     qemu_uuid_generate(&uuid);
1073     footer.uuid = uuid;
1074 
1075     footer.checksum = cpu_to_be32(vpc_checksum(&footer, sizeof(footer)));
1076 
1077     if (disk_type == VHD_DYNAMIC) {
1078         ret = create_dynamic_disk(blk, &footer, total_sectors);
1079         if (ret < 0) {
1080             error_setg(errp, "Unable to create or write VHD header");
1081         }
1082     } else {
1083         ret = create_fixed_disk(blk, &footer, total_size, errp);
1084     }
1085 
1086 out:
1087     blk_co_unref(blk);
1088     bdrv_co_unref(bs);
1089     return ret;
1090 }
1091 
1092 static int coroutine_fn GRAPH_UNLOCKED
vpc_co_create_opts(BlockDriver * drv,const char * filename,QemuOpts * opts,Error ** errp)1093 vpc_co_create_opts(BlockDriver *drv, const char *filename,
1094                    QemuOpts *opts, Error **errp)
1095 {
1096     BlockdevCreateOptions *create_options = NULL;
1097     QDict *qdict;
1098     Visitor *v;
1099     BlockDriverState *bs = NULL;
1100     int ret;
1101 
1102     static const QDictRenames opt_renames[] = {
1103         { VPC_OPT_FORCE_SIZE,           "force-size" },
1104         { NULL, NULL },
1105     };
1106 
1107     /* Parse options and convert legacy syntax */
1108     qdict = qemu_opts_to_qdict_filtered(opts, NULL, &vpc_create_opts, true);
1109 
1110     if (!qdict_rename_keys(qdict, opt_renames, errp)) {
1111         ret = -EINVAL;
1112         goto fail;
1113     }
1114 
1115     /* Create and open the file (protocol layer) */
1116     ret = bdrv_co_create_file(filename, opts, errp);
1117     if (ret < 0) {
1118         goto fail;
1119     }
1120 
1121     bs = bdrv_co_open(filename, NULL, NULL,
1122                       BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
1123     if (bs == NULL) {
1124         ret = -EIO;
1125         goto fail;
1126     }
1127 
1128     /* Now get the QAPI type BlockdevCreateOptions */
1129     qdict_put_str(qdict, "driver", "vpc");
1130     qdict_put_str(qdict, "file", bs->node_name);
1131 
1132     v = qobject_input_visitor_new_flat_confused(qdict, errp);
1133     if (!v) {
1134         ret = -EINVAL;
1135         goto fail;
1136     }
1137 
1138     visit_type_BlockdevCreateOptions(v, NULL, &create_options, errp);
1139     visit_free(v);
1140     if (!create_options) {
1141         ret = -EINVAL;
1142         goto fail;
1143     }
1144 
1145     /* Silently round up size */
1146     assert(create_options->driver == BLOCKDEV_DRIVER_VPC);
1147     create_options->u.vpc.size =
1148         ROUND_UP(create_options->u.vpc.size, BDRV_SECTOR_SIZE);
1149 
1150     if (!create_options->u.vpc.force_size) {
1151         int64_t total_sectors;
1152         ret = calculate_rounded_image_size(&create_options->u.vpc, NULL, NULL,
1153                                            NULL, &total_sectors, errp);
1154         if (ret < 0) {
1155             goto fail;
1156         }
1157 
1158         create_options->u.vpc.size = total_sectors * BDRV_SECTOR_SIZE;
1159     }
1160 
1161 
1162     /* Create the vpc image (format layer) */
1163     ret = vpc_co_create(create_options, errp);
1164 
1165 fail:
1166     qobject_unref(qdict);
1167     bdrv_co_unref(bs);
1168     qapi_free_BlockdevCreateOptions(create_options);
1169     return ret;
1170 }
1171 
1172 
vpc_has_zero_init(BlockDriverState * bs)1173 static int GRAPH_RDLOCK vpc_has_zero_init(BlockDriverState *bs)
1174 {
1175     BDRVVPCState *s = bs->opaque;
1176 
1177     if (be32_to_cpu(s->footer.type) == VHD_FIXED) {
1178         return bdrv_has_zero_init(bs->file->bs);
1179     } else {
1180         return 1;
1181     }
1182 }
1183 
vpc_close(BlockDriverState * bs)1184 static void vpc_close(BlockDriverState *bs)
1185 {
1186     BDRVVPCState *s = bs->opaque;
1187     qemu_vfree(s->pagetable);
1188 #ifdef CACHE
1189     g_free(s->pageentry_u8);
1190 #endif
1191 
1192     migrate_del_blocker(&s->migration_blocker);
1193 }
1194 
1195 static QemuOptsList vpc_create_opts = {
1196     .name = "vpc-create-opts",
1197     .head = QTAILQ_HEAD_INITIALIZER(vpc_create_opts.head),
1198     .desc = {
1199         {
1200             .name = BLOCK_OPT_SIZE,
1201             .type = QEMU_OPT_SIZE,
1202             .help = "Virtual disk size"
1203         },
1204         {
1205             .name = BLOCK_OPT_SUBFMT,
1206             .type = QEMU_OPT_STRING,
1207             .help =
1208                 "Type of virtual hard disk format. Supported formats are "
1209                 "{dynamic (default) | fixed} "
1210         },
1211         {
1212             .name = VPC_OPT_FORCE_SIZE,
1213             .type = QEMU_OPT_BOOL,
1214             .help = "Force disk size calculation to use the actual size "
1215                     "specified, rather than using the nearest CHS-based "
1216                     "calculation"
1217         },
1218         { /* end of list */ }
1219     }
1220 };
1221 
1222 static const char *const vpc_strong_runtime_opts[] = {
1223     VPC_OPT_SIZE_CALC,
1224 
1225     NULL
1226 };
1227 
1228 static BlockDriver bdrv_vpc = {
1229     .format_name    = "vpc",
1230     .instance_size  = sizeof(BDRVVPCState),
1231 
1232     .bdrv_probe             = vpc_probe,
1233     .bdrv_open              = vpc_open,
1234     .bdrv_close             = vpc_close,
1235     .bdrv_reopen_prepare    = vpc_reopen_prepare,
1236     .bdrv_child_perm        = bdrv_default_perms,
1237     .bdrv_co_create         = vpc_co_create,
1238     .bdrv_co_create_opts    = vpc_co_create_opts,
1239 
1240     .bdrv_co_preadv             = vpc_co_preadv,
1241     .bdrv_co_pwritev            = vpc_co_pwritev,
1242     .bdrv_co_block_status       = vpc_co_block_status,
1243 
1244     .bdrv_co_get_info       = vpc_co_get_info,
1245 
1246     .is_format              = true,
1247     .create_opts            = &vpc_create_opts,
1248     .bdrv_has_zero_init     = vpc_has_zero_init,
1249     .strong_runtime_opts    = vpc_strong_runtime_opts,
1250 };
1251 
bdrv_vpc_init(void)1252 static void bdrv_vpc_init(void)
1253 {
1254     bdrv_register(&bdrv_vpc);
1255 }
1256 
1257 block_init(bdrv_vpc_init);
1258