Statistics
| Branch: | Revision:

root / block / vpc.c @ d5124c00

History | View | Annotate | Download (23.8 kB)

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
#include "qemu-common.h"
26
#include "block/block_int.h"
27
#include "qemu/module.h"
28
#include "migration/migration.h"
29
#if defined(CONFIG_UUID)
30
#include <uuid/uuid.h>
31
#endif
32

    
33
/**************************************************************/
34

    
35
#define HEADER_SIZE 512
36

    
37
//#define CACHE
38

    
39
enum vhd_type {
40
    VHD_FIXED           = 2,
41
    VHD_DYNAMIC         = 3,
42
    VHD_DIFFERENCING    = 4,
43
};
44

    
45
// Seconds since Jan 1, 2000 0:00:00 (UTC)
46
#define VHD_TIMESTAMP_BASE 946684800
47

    
48
// always big-endian
49
struct vhd_footer {
50
    char        creator[8]; // "conectix"
51
    uint32_t    features;
52
    uint32_t    version;
53

    
54
    // Offset of next header structure, 0xFFFFFFFF if none
55
    uint64_t    data_offset;
56

    
57
    // Seconds since Jan 1, 2000 0:00:00 (UTC)
58
    uint32_t    timestamp;
59

    
60
    char        creator_app[4]; // "vpc "
61
    uint16_t    major;
62
    uint16_t    minor;
63
    char        creator_os[4]; // "Wi2k"
64

    
65
    uint64_t    orig_size;
66
    uint64_t    size;
67

    
68
    uint16_t    cyls;
69
    uint8_t     heads;
70
    uint8_t     secs_per_cyl;
71

    
72
    uint32_t    type;
73

    
74
    // Checksum of the Hard Disk Footer ("one's complement of the sum of all
75
    // the bytes in the footer without the checksum field")
76
    uint32_t    checksum;
77

    
78
    // UUID used to identify a parent hard disk (backing file)
79
    uint8_t     uuid[16];
80

    
81
    uint8_t     in_saved_state;
82
};
83

    
84
struct vhd_dyndisk_header {
85
    char        magic[8]; // "cxsparse"
86

    
87
    // Offset of next header structure, 0xFFFFFFFF if none
88
    uint64_t    data_offset;
89

    
90
    // Offset of the Block Allocation Table (BAT)
91
    uint64_t    table_offset;
92

    
93
    uint32_t    version;
94
    uint32_t    max_table_entries; // 32bit/entry
95

    
96
    // 2 MB by default, must be a power of two
97
    uint32_t    block_size;
98

    
99
    uint32_t    checksum;
100
    uint8_t     parent_uuid[16];
101
    uint32_t    parent_timestamp;
102
    uint32_t    reserved;
103

    
104
    // Backing file name (in UTF-16)
105
    uint8_t     parent_name[512];
106

    
107
    struct {
108
        uint32_t    platform;
109
        uint32_t    data_space;
110
        uint32_t    data_length;
111
        uint32_t    reserved;
112
        uint64_t    data_offset;
113
    } parent_locator[8];
114
};
115

    
116
typedef struct BDRVVPCState {
117
    CoMutex lock;
118
    uint8_t footer_buf[HEADER_SIZE];
119
    uint64_t free_data_block_offset;
120
    int max_table_entries;
121
    uint32_t *pagetable;
122
    uint64_t bat_offset;
123
    uint64_t last_bitmap_offset;
124

    
125
    uint32_t block_size;
126
    uint32_t bitmap_size;
127

    
128
#ifdef CACHE
129
    uint8_t *pageentry_u8;
130
    uint32_t *pageentry_u32;
131
    uint16_t *pageentry_u16;
132

    
133
    uint64_t last_bitmap;
134
#endif
135

    
136
    Error *migration_blocker;
137
} BDRVVPCState;
138

    
139
static uint32_t vpc_checksum(uint8_t* buf, size_t size)
140
{
141
    uint32_t res = 0;
142
    int i;
143

    
144
    for (i = 0; i < size; i++)
145
        res += buf[i];
146

    
147
    return ~res;
148
}
149

    
150

    
151
static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
152
{
153
    if (buf_size >= 8 && !strncmp((char *)buf, "conectix", 8))
154
        return 100;
155
    return 0;
156
}
157

    
158
static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
159
                    Error **errp)
160
{
161
    BDRVVPCState *s = bs->opaque;
162
    int i;
163
    struct vhd_footer* footer;
164
    struct vhd_dyndisk_header* dyndisk_header;
165
    uint8_t buf[HEADER_SIZE];
166
    uint32_t checksum;
167
    int disk_type = VHD_DYNAMIC;
168
    int ret;
169

    
170
    ret = bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE);
171
    if (ret < 0) {
172
        goto fail;
173
    }
174

    
175
    footer = (struct vhd_footer*) s->footer_buf;
176
    if (strncmp(footer->creator, "conectix", 8)) {
177
        int64_t offset = bdrv_getlength(bs->file);
178
        if (offset < 0) {
179
            ret = offset;
180
            goto fail;
181
        } else if (offset < HEADER_SIZE) {
182
            ret = -EINVAL;
183
            goto fail;
184
        }
185

    
186
        /* If a fixed disk, the footer is found only at the end of the file */
187
        ret = bdrv_pread(bs->file, offset-HEADER_SIZE, s->footer_buf,
188
                         HEADER_SIZE);
189
        if (ret < 0) {
190
            goto fail;
191
        }
192
        if (strncmp(footer->creator, "conectix", 8)) {
193
            ret = -EMEDIUMTYPE;
194
            goto fail;
195
        }
196
        disk_type = VHD_FIXED;
197
    }
198

    
199
    checksum = be32_to_cpu(footer->checksum);
200
    footer->checksum = 0;
201
    if (vpc_checksum(s->footer_buf, HEADER_SIZE) != checksum)
202
        fprintf(stderr, "block-vpc: The header checksum of '%s' is "
203
            "incorrect.\n", bs->filename);
204

    
205
    /* Write 'checksum' back to footer, or else will leave it with zero. */
206
    footer->checksum = be32_to_cpu(checksum);
207

    
208
    // The visible size of a image in Virtual PC depends on the geometry
209
    // rather than on the size stored in the footer (the size in the footer
210
    // is too large usually)
211
    bs->total_sectors = (int64_t)
212
        be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
213

    
214
    /* Allow a maximum disk size of approximately 2 TB */
215
    if (bs->total_sectors >= 65535LL * 255 * 255) {
216
        ret = -EFBIG;
217
        goto fail;
218
    }
219

    
220
    if (disk_type == VHD_DYNAMIC) {
221
        ret = bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf,
222
                         HEADER_SIZE);
223
        if (ret < 0) {
224
            goto fail;
225
        }
226

    
227
        dyndisk_header = (struct vhd_dyndisk_header *) buf;
228

    
229
        if (strncmp(dyndisk_header->magic, "cxsparse", 8)) {
230
            ret = -EINVAL;
231
            goto fail;
232
        }
233

    
234
        s->block_size = be32_to_cpu(dyndisk_header->block_size);
235
        s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;
236

    
237
        s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);
238
        s->pagetable = g_malloc(s->max_table_entries * 4);
239

    
240
        s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
241

    
242
        ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable,
243
                         s->max_table_entries * 4);
244
        if (ret < 0) {
245
            goto fail;
246
        }
247

    
248
        s->free_data_block_offset =
249
            (s->bat_offset + (s->max_table_entries * 4) + 511) & ~511;
250

    
251
        for (i = 0; i < s->max_table_entries; i++) {
252
            be32_to_cpus(&s->pagetable[i]);
253
            if (s->pagetable[i] != 0xFFFFFFFF) {
254
                int64_t next = (512 * (int64_t) s->pagetable[i]) +
255
                    s->bitmap_size + s->block_size;
256

    
257
                if (next > s->free_data_block_offset) {
258
                    s->free_data_block_offset = next;
259
                }
260
            }
261
        }
262

    
263
        s->last_bitmap_offset = (int64_t) -1;
264

    
265
#ifdef CACHE
266
        s->pageentry_u8 = g_malloc(512);
267
        s->pageentry_u32 = s->pageentry_u8;
268
        s->pageentry_u16 = s->pageentry_u8;
269
        s->last_pagetable = -1;
270
#endif
271
    }
272

    
273
    qemu_co_mutex_init(&s->lock);
274

    
275
    /* Disable migration when VHD images are used */
276
    error_set(&s->migration_blocker,
277
              QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
278
              "vpc", bs->device_name, "live migration");
279
    migrate_add_blocker(s->migration_blocker);
280

    
281
    return 0;
282

    
283
fail:
284
    g_free(s->pagetable);
285
#ifdef CACHE
286
    g_free(s->pageentry_u8);
287
#endif
288
    return ret;
289
}
290

    
291
static int vpc_reopen_prepare(BDRVReopenState *state,
292
                              BlockReopenQueue *queue, Error **errp)
293
{
294
    return 0;
295
}
296

    
297
/*
298
 * Returns the absolute byte offset of the given sector in the image file.
299
 * If the sector is not allocated, -1 is returned instead.
300
 *
301
 * The parameter write must be 1 if the offset will be used for a write
302
 * operation (the block bitmaps is updated then), 0 otherwise.
303
 */
304
static inline int64_t get_sector_offset(BlockDriverState *bs,
305
    int64_t sector_num, int write)
306
{
307
    BDRVVPCState *s = bs->opaque;
308
    uint64_t offset = sector_num * 512;
309
    uint64_t bitmap_offset, block_offset;
310
    uint32_t pagetable_index, pageentry_index;
311

    
312
    pagetable_index = offset / s->block_size;
313
    pageentry_index = (offset % s->block_size) / 512;
314

    
315
    if (pagetable_index >= s->max_table_entries || s->pagetable[pagetable_index] == 0xffffffff)
316
        return -1; // not allocated
317

    
318
    bitmap_offset = 512 * (uint64_t) s->pagetable[pagetable_index];
319
    block_offset = bitmap_offset + s->bitmap_size + (512 * pageentry_index);
320

    
321
    // We must ensure that we don't write to any sectors which are marked as
322
    // unused in the bitmap. We get away with setting all bits in the block
323
    // bitmap each time we write to a new block. This might cause Virtual PC to
324
    // miss sparse read optimization, but it's not a problem in terms of
325
    // correctness.
326
    if (write && (s->last_bitmap_offset != bitmap_offset)) {
327
        uint8_t bitmap[s->bitmap_size];
328

    
329
        s->last_bitmap_offset = bitmap_offset;
330
        memset(bitmap, 0xff, s->bitmap_size);
331
        bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size);
332
    }
333

    
334
//    printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n",
335
//        sector_num, pagetable_index, pageentry_index,
336
//        bitmap_offset, block_offset);
337

    
338
// disabled by reason
339
#if 0
340
#ifdef CACHE
341
    if (bitmap_offset != s->last_bitmap)
342
    {
343
        lseek(s->fd, bitmap_offset, SEEK_SET);
344

345
        s->last_bitmap = bitmap_offset;
346

347
        // Scary! Bitmap is stored as big endian 32bit entries,
348
        // while we used to look it up byte by byte
349
        read(s->fd, s->pageentry_u8, 512);
350
        for (i = 0; i < 128; i++)
351
            be32_to_cpus(&s->pageentry_u32[i]);
352
    }
353

354
    if ((s->pageentry_u8[pageentry_index / 8] >> (pageentry_index % 8)) & 1)
355
        return -1;
356
#else
357
    lseek(s->fd, bitmap_offset + (pageentry_index / 8), SEEK_SET);
358

    
359
    read(s->fd, &bitmap_entry, 1);
360

    
361
    if ((bitmap_entry >> (pageentry_index % 8)) & 1)
362
        return -1; // not allocated
363
#endif
364
#endif
365

    
366
    return block_offset;
367
}
368

    
369
/*
370
 * Writes the footer to the end of the image file. This is needed when the
371
 * file grows as it overwrites the old footer
372
 *
373
 * Returns 0 on success and < 0 on error
374
 */
375
static int rewrite_footer(BlockDriverState* bs)
376
{
377
    int ret;
378
    BDRVVPCState *s = bs->opaque;
379
    int64_t offset = s->free_data_block_offset;
380

    
381
    ret = bdrv_pwrite_sync(bs->file, offset, s->footer_buf, HEADER_SIZE);
382
    if (ret < 0)
383
        return ret;
384

    
385
    return 0;
386
}
387

    
388
/*
389
 * Allocates a new block. This involves writing a new footer and updating
390
 * the Block Allocation Table to use the space at the old end of the image
391
 * file (overwriting the old footer)
392
 *
393
 * Returns the sectors' offset in the image file on success and < 0 on error
394
 */
395
static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
396
{
397
    BDRVVPCState *s = bs->opaque;
398
    int64_t bat_offset;
399
    uint32_t index, bat_value;
400
    int ret;
401
    uint8_t bitmap[s->bitmap_size];
402

    
403
    // Check if sector_num is valid
404
    if ((sector_num < 0) || (sector_num > bs->total_sectors))
405
        return -1;
406

    
407
    // Write entry into in-memory BAT
408
    index = (sector_num * 512) / s->block_size;
409
    if (s->pagetable[index] != 0xFFFFFFFF)
410
        return -1;
411

    
412
    s->pagetable[index] = s->free_data_block_offset / 512;
413

    
414
    // Initialize the block's bitmap
415
    memset(bitmap, 0xff, s->bitmap_size);
416
    ret = bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap,
417
        s->bitmap_size);
418
    if (ret < 0) {
419
        return ret;
420
    }
421

    
422
    // Write new footer (the old one will be overwritten)
423
    s->free_data_block_offset += s->block_size + s->bitmap_size;
424
    ret = rewrite_footer(bs);
425
    if (ret < 0)
426
        goto fail;
427

    
428
    // Write BAT entry to disk
429
    bat_offset = s->bat_offset + (4 * index);
430
    bat_value = be32_to_cpu(s->pagetable[index]);
431
    ret = bdrv_pwrite_sync(bs->file, bat_offset, &bat_value, 4);
432
    if (ret < 0)
433
        goto fail;
434

    
435
    return get_sector_offset(bs, sector_num, 0);
436

    
437
fail:
438
    s->free_data_block_offset -= (s->block_size + s->bitmap_size);
439
    return -1;
440
}
441

    
442
static int vpc_read(BlockDriverState *bs, int64_t sector_num,
443
                    uint8_t *buf, int nb_sectors)
444
{
445
    BDRVVPCState *s = bs->opaque;
446
    int ret;
447
    int64_t offset;
448
    int64_t sectors, sectors_per_block;
449
    struct vhd_footer *footer = (struct vhd_footer *) s->footer_buf;
450

    
451
    if (cpu_to_be32(footer->type) == VHD_FIXED) {
452
        return bdrv_read(bs->file, sector_num, buf, nb_sectors);
453
    }
454
    while (nb_sectors > 0) {
455
        offset = get_sector_offset(bs, sector_num, 0);
456

    
457
        sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
458
        sectors = sectors_per_block - (sector_num % sectors_per_block);
459
        if (sectors > nb_sectors) {
460
            sectors = nb_sectors;
461
        }
462

    
463
        if (offset == -1) {
464
            memset(buf, 0, sectors * BDRV_SECTOR_SIZE);
465
        } else {
466
            ret = bdrv_pread(bs->file, offset, buf,
467
                sectors * BDRV_SECTOR_SIZE);
468
            if (ret != sectors * BDRV_SECTOR_SIZE) {
469
                return -1;
470
            }
471
        }
472

    
473
        nb_sectors -= sectors;
474
        sector_num += sectors;
475
        buf += sectors * BDRV_SECTOR_SIZE;
476
    }
477
    return 0;
478
}
479

    
480
static coroutine_fn int vpc_co_read(BlockDriverState *bs, int64_t sector_num,
481
                                    uint8_t *buf, int nb_sectors)
482
{
483
    int ret;
484
    BDRVVPCState *s = bs->opaque;
485
    qemu_co_mutex_lock(&s->lock);
486
    ret = vpc_read(bs, sector_num, buf, nb_sectors);
487
    qemu_co_mutex_unlock(&s->lock);
488
    return ret;
489
}
490

    
491
static int vpc_write(BlockDriverState *bs, int64_t sector_num,
492
    const uint8_t *buf, int nb_sectors)
493
{
494
    BDRVVPCState *s = bs->opaque;
495
    int64_t offset;
496
    int64_t sectors, sectors_per_block;
497
    int ret;
498
    struct vhd_footer *footer =  (struct vhd_footer *) s->footer_buf;
499

    
500
    if (cpu_to_be32(footer->type) == VHD_FIXED) {
501
        return bdrv_write(bs->file, sector_num, buf, nb_sectors);
502
    }
503
    while (nb_sectors > 0) {
504
        offset = get_sector_offset(bs, sector_num, 1);
505

    
506
        sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
507
        sectors = sectors_per_block - (sector_num % sectors_per_block);
508
        if (sectors > nb_sectors) {
509
            sectors = nb_sectors;
510
        }
511

    
512
        if (offset == -1) {
513
            offset = alloc_block(bs, sector_num);
514
            if (offset < 0)
515
                return -1;
516
        }
517

    
518
        ret = bdrv_pwrite(bs->file, offset, buf, sectors * BDRV_SECTOR_SIZE);
519
        if (ret != sectors * BDRV_SECTOR_SIZE) {
520
            return -1;
521
        }
522

    
523
        nb_sectors -= sectors;
524
        sector_num += sectors;
525
        buf += sectors * BDRV_SECTOR_SIZE;
526
    }
527

    
528
    return 0;
529
}
530

    
531
static coroutine_fn int vpc_co_write(BlockDriverState *bs, int64_t sector_num,
532
                                     const uint8_t *buf, int nb_sectors)
533
{
534
    int ret;
535
    BDRVVPCState *s = bs->opaque;
536
    qemu_co_mutex_lock(&s->lock);
537
    ret = vpc_write(bs, sector_num, buf, nb_sectors);
538
    qemu_co_mutex_unlock(&s->lock);
539
    return ret;
540
}
541

    
542
/*
543
 * Calculates the number of cylinders, heads and sectors per cylinder
544
 * based on a given number of sectors. This is the algorithm described
545
 * in the VHD specification.
546
 *
547
 * Note that the geometry doesn't always exactly match total_sectors but
548
 * may round it down.
549
 *
550
 * Returns 0 on success, -EFBIG if the size is larger than ~2 TB. Override
551
 * the hardware EIDE and ATA-2 limit of 16 heads (max disk size of 127 GB)
552
 * and instead allow up to 255 heads.
553
 */
554
static int calculate_geometry(int64_t total_sectors, uint16_t* cyls,
555
    uint8_t* heads, uint8_t* secs_per_cyl)
556
{
557
    uint32_t cyls_times_heads;
558

    
559
    /* Allow a maximum disk size of approximately 2 TB */
560
    if (total_sectors > 65535LL * 255 * 255) {
561
        return -EFBIG;
562
    }
563

    
564
    if (total_sectors > 65535 * 16 * 63) {
565
        *secs_per_cyl = 255;
566
        if (total_sectors > 65535 * 16 * 255) {
567
            *heads = 255;
568
        } else {
569
            *heads = 16;
570
        }
571
        cyls_times_heads = total_sectors / *secs_per_cyl;
572
    } else {
573
        *secs_per_cyl = 17;
574
        cyls_times_heads = total_sectors / *secs_per_cyl;
575
        *heads = (cyls_times_heads + 1023) / 1024;
576

    
577
        if (*heads < 4)
578
            *heads = 4;
579

    
580
        if (cyls_times_heads >= (*heads * 1024) || *heads > 16) {
581
            *secs_per_cyl = 31;
582
            *heads = 16;
583
            cyls_times_heads = total_sectors / *secs_per_cyl;
584
        }
585

    
586
        if (cyls_times_heads >= (*heads * 1024)) {
587
            *secs_per_cyl = 63;
588
            *heads = 16;
589
            cyls_times_heads = total_sectors / *secs_per_cyl;
590
        }
591
    }
592

    
593
    *cyls = cyls_times_heads / *heads;
594

    
595
    return 0;
596
}
597

    
598
static int create_dynamic_disk(int fd, uint8_t *buf, int64_t total_sectors)
599
{
600
    struct vhd_dyndisk_header* dyndisk_header =
601
        (struct vhd_dyndisk_header*) buf;
602
    size_t block_size, num_bat_entries;
603
    int i;
604
    int ret = -EIO;
605

    
606
    // Write the footer (twice: at the beginning and at the end)
607
    block_size = 0x200000;
608
    num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);
609

    
610
    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE) {
611
        goto fail;
612
    }
613

    
614
    if (lseek(fd, 1536 + ((num_bat_entries * 4 + 511) & ~511), SEEK_SET) < 0) {
615
        goto fail;
616
    }
617
    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE) {
618
        goto fail;
619
    }
620

    
621
    // Write the initial BAT
622
    if (lseek(fd, 3 * 512, SEEK_SET) < 0) {
623
        goto fail;
624
    }
625

    
626
    memset(buf, 0xFF, 512);
627
    for (i = 0; i < (num_bat_entries * 4 + 511) / 512; i++) {
628
        if (write(fd, buf, 512) != 512) {
629
            goto fail;
630
        }
631
    }
632

    
633
    // Prepare the Dynamic Disk Header
634
    memset(buf, 0, 1024);
635

    
636
    memcpy(dyndisk_header->magic, "cxsparse", 8);
637

    
638
    /*
639
     * Note: The spec is actually wrong here for data_offset, it says
640
     * 0xFFFFFFFF, but MS tools expect all 64 bits to be set.
641
     */
642
    dyndisk_header->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL);
643
    dyndisk_header->table_offset = be64_to_cpu(3 * 512);
644
    dyndisk_header->version = be32_to_cpu(0x00010000);
645
    dyndisk_header->block_size = be32_to_cpu(block_size);
646
    dyndisk_header->max_table_entries = be32_to_cpu(num_bat_entries);
647

    
648
    dyndisk_header->checksum = be32_to_cpu(vpc_checksum(buf, 1024));
649

    
650
    // Write the header
651
    if (lseek(fd, 512, SEEK_SET) < 0) {
652
        goto fail;
653
    }
654

    
655
    if (write(fd, buf, 1024) != 1024) {
656
        goto fail;
657
    }
658
    ret = 0;
659

    
660
 fail:
661
    return ret;
662
}
663

    
664
static int create_fixed_disk(int fd, uint8_t *buf, int64_t total_size)
665
{
666
    int ret = -EIO;
667

    
668
    /* Add footer to total size */
669
    total_size += 512;
670
    if (ftruncate(fd, total_size) != 0) {
671
        ret = -errno;
672
        goto fail;
673
    }
674
    if (lseek(fd, -512, SEEK_END) < 0) {
675
        goto fail;
676
    }
677
    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE) {
678
        goto fail;
679
    }
680

    
681
    ret = 0;
682

    
683
 fail:
684
    return ret;
685
}
686

    
687
static int vpc_create(const char *filename, QEMUOptionParameter *options,
688
                      Error **errp)
689
{
690
    uint8_t buf[1024];
691
    struct vhd_footer *footer = (struct vhd_footer *) buf;
692
    QEMUOptionParameter *disk_type_param;
693
    int fd, i;
694
    uint16_t cyls = 0;
695
    uint8_t heads = 0;
696
    uint8_t secs_per_cyl = 0;
697
    int64_t total_sectors;
698
    int64_t total_size;
699
    int disk_type;
700
    int ret = -EIO;
701

    
702
    /* Read out options */
703
    total_size = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n;
704

    
705
    disk_type_param = get_option_parameter(options, BLOCK_OPT_SUBFMT);
706
    if (disk_type_param && disk_type_param->value.s) {
707
        if (!strcmp(disk_type_param->value.s, "dynamic")) {
708
            disk_type = VHD_DYNAMIC;
709
        } else if (!strcmp(disk_type_param->value.s, "fixed")) {
710
            disk_type = VHD_FIXED;
711
        } else {
712
            return -EINVAL;
713
        }
714
    } else {
715
        disk_type = VHD_DYNAMIC;
716
    }
717

    
718
    /* Create the file */
719
    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
720
    if (fd < 0) {
721
        return -EIO;
722
    }
723

    
724
    /*
725
     * Calculate matching total_size and geometry. Increase the number of
726
     * sectors requested until we get enough (or fail). This ensures that
727
     * qemu-img convert doesn't truncate images, but rather rounds up.
728
     */
729
    total_sectors = total_size / BDRV_SECTOR_SIZE;
730
    for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {
731
        if (calculate_geometry(total_sectors + i, &cyls, &heads,
732
                               &secs_per_cyl))
733
        {
734
            ret = -EFBIG;
735
            goto fail;
736
        }
737
    }
738

    
739
    total_sectors = (int64_t) cyls * heads * secs_per_cyl;
740

    
741
    /* Prepare the Hard Disk Footer */
742
    memset(buf, 0, 1024);
743

    
744
    memcpy(footer->creator, "conectix", 8);
745
    /* TODO Check if "qemu" creator_app is ok for VPC */
746
    memcpy(footer->creator_app, "qemu", 4);
747
    memcpy(footer->creator_os, "Wi2k", 4);
748

    
749
    footer->features = be32_to_cpu(0x02);
750
    footer->version = be32_to_cpu(0x00010000);
751
    if (disk_type == VHD_DYNAMIC) {
752
        footer->data_offset = be64_to_cpu(HEADER_SIZE);
753
    } else {
754
        footer->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL);
755
    }
756
    footer->timestamp = be32_to_cpu(time(NULL) - VHD_TIMESTAMP_BASE);
757

    
758
    /* Version of Virtual PC 2007 */
759
    footer->major = be16_to_cpu(0x0005);
760
    footer->minor = be16_to_cpu(0x0003);
761
    if (disk_type == VHD_DYNAMIC) {
762
        footer->orig_size = be64_to_cpu(total_sectors * 512);
763
        footer->size = be64_to_cpu(total_sectors * 512);
764
    } else {
765
        footer->orig_size = be64_to_cpu(total_size);
766
        footer->size = be64_to_cpu(total_size);
767
    }
768
    footer->cyls = be16_to_cpu(cyls);
769
    footer->heads = heads;
770
    footer->secs_per_cyl = secs_per_cyl;
771

    
772
    footer->type = be32_to_cpu(disk_type);
773

    
774
#if defined(CONFIG_UUID)
775
    uuid_generate(footer->uuid);
776
#endif
777

    
778
    footer->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE));
779

    
780
    if (disk_type == VHD_DYNAMIC) {
781
        ret = create_dynamic_disk(fd, buf, total_sectors);
782
    } else {
783
        ret = create_fixed_disk(fd, buf, total_size);
784
    }
785

    
786
 fail:
787
    qemu_close(fd);
788
    return ret;
789
}
790

    
791
static int vpc_has_zero_init(BlockDriverState *bs)
792
{
793
    BDRVVPCState *s = bs->opaque;
794
    struct vhd_footer *footer =  (struct vhd_footer *) s->footer_buf;
795

    
796
    if (cpu_to_be32(footer->type) == VHD_FIXED) {
797
        return bdrv_has_zero_init(bs->file);
798
    } else {
799
        return 1;
800
    }
801
}
802

    
803
static void vpc_close(BlockDriverState *bs)
804
{
805
    BDRVVPCState *s = bs->opaque;
806
    g_free(s->pagetable);
807
#ifdef CACHE
808
    g_free(s->pageentry_u8);
809
#endif
810

    
811
    migrate_del_blocker(s->migration_blocker);
812
    error_free(s->migration_blocker);
813
}
814

    
815
static QEMUOptionParameter vpc_create_options[] = {
816
    {
817
        .name = BLOCK_OPT_SIZE,
818
        .type = OPT_SIZE,
819
        .help = "Virtual disk size"
820
    },
821
    {
822
        .name = BLOCK_OPT_SUBFMT,
823
        .type = OPT_STRING,
824
        .help =
825
            "Type of virtual hard disk format. Supported formats are "
826
            "{dynamic (default) | fixed} "
827
    },
828
    { NULL }
829
};
830

    
831
static BlockDriver bdrv_vpc = {
832
    .format_name    = "vpc",
833
    .instance_size  = sizeof(BDRVVPCState),
834

    
835
    .bdrv_probe             = vpc_probe,
836
    .bdrv_open              = vpc_open,
837
    .bdrv_close             = vpc_close,
838
    .bdrv_reopen_prepare    = vpc_reopen_prepare,
839
    .bdrv_create            = vpc_create,
840

    
841
    .bdrv_read              = vpc_co_read,
842
    .bdrv_write             = vpc_co_write,
843

    
844
    .create_options         = vpc_create_options,
845
    .bdrv_has_zero_init     = vpc_has_zero_init,
846
};
847

    
848
static void bdrv_vpc_init(void)
849
{
850
    bdrv_register(&bdrv_vpc);
851
}
852

    
853
block_init(bdrv_vpc_init);