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