Statistics
| Branch: | Revision:

root / block / vmdk.c @ 4a1d5e1f

History | View | Annotate | Download (38.4 kB)

1
/*
2
 * Block driver for the VMDK format
3
 *
4
 * Copyright (c) 2004 Fabrice Bellard
5
 * Copyright (c) 2005 Filip Navara
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-common.h"
27
#include "block_int.h"
28
#include "module.h"
29

    
30
#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
31
#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
32

    
33
typedef struct {
34
    uint32_t version;
35
    uint32_t flags;
36
    uint32_t disk_sectors;
37
    uint32_t granularity;
38
    uint32_t l1dir_offset;
39
    uint32_t l1dir_size;
40
    uint32_t file_sectors;
41
    uint32_t cylinders;
42
    uint32_t heads;
43
    uint32_t sectors_per_track;
44
} VMDK3Header;
45

    
46
typedef struct {
47
    uint32_t version;
48
    uint32_t flags;
49
    int64_t capacity;
50
    int64_t granularity;
51
    int64_t desc_offset;
52
    int64_t desc_size;
53
    int32_t num_gtes_per_gte;
54
    int64_t rgd_offset;
55
    int64_t gd_offset;
56
    int64_t grain_offset;
57
    char filler[1];
58
    char check_bytes[4];
59
} __attribute__((packed)) VMDK4Header;
60

    
61
#define L2_CACHE_SIZE 16
62

    
63
typedef struct VmdkExtent {
64
    BlockDriverState *file;
65
    bool flat;
66
    int64_t sectors;
67
    int64_t end_sector;
68
    int64_t flat_start_offset;
69
    int64_t l1_table_offset;
70
    int64_t l1_backup_table_offset;
71
    uint32_t *l1_table;
72
    uint32_t *l1_backup_table;
73
    unsigned int l1_size;
74
    uint32_t l1_entry_sectors;
75

    
76
    unsigned int l2_size;
77
    uint32_t *l2_cache;
78
    uint32_t l2_cache_offsets[L2_CACHE_SIZE];
79
    uint32_t l2_cache_counts[L2_CACHE_SIZE];
80

    
81
    unsigned int cluster_sectors;
82
} VmdkExtent;
83

    
84
typedef struct BDRVVmdkState {
85
    int desc_offset;
86
    bool cid_updated;
87
    uint32_t parent_cid;
88
    int num_extents;
89
    /* Extent array with num_extents entries, ascend ordered by address */
90
    VmdkExtent *extents;
91
} BDRVVmdkState;
92

    
93
typedef struct VmdkMetaData {
94
    uint32_t offset;
95
    unsigned int l1_index;
96
    unsigned int l2_index;
97
    unsigned int l2_offset;
98
    int valid;
99
} VmdkMetaData;
100

    
101
static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
102
{
103
    uint32_t magic;
104

    
105
    if (buf_size < 4) {
106
        return 0;
107
    }
108
    magic = be32_to_cpu(*(uint32_t *)buf);
109
    if (magic == VMDK3_MAGIC ||
110
        magic == VMDK4_MAGIC) {
111
        return 100;
112
    } else {
113
        const char *p = (const char *)buf;
114
        const char *end = p + buf_size;
115
        while (p < end) {
116
            if (*p == '#') {
117
                /* skip comment line */
118
                while (p < end && *p != '\n') {
119
                    p++;
120
                }
121
                p++;
122
                continue;
123
            }
124
            if (*p == ' ') {
125
                while (p < end && *p == ' ') {
126
                    p++;
127
                }
128
                /* skip '\r' if windows line endings used. */
129
                if (p < end && *p == '\r') {
130
                    p++;
131
                }
132
                /* only accept blank lines before 'version=' line */
133
                if (p == end || *p != '\n') {
134
                    return 0;
135
                }
136
                p++;
137
                continue;
138
            }
139
            if (end - p >= strlen("version=X\n")) {
140
                if (strncmp("version=1\n", p, strlen("version=1\n")) == 0 ||
141
                    strncmp("version=2\n", p, strlen("version=2\n")) == 0) {
142
                    return 100;
143
                }
144
            }
145
            if (end - p >= strlen("version=X\r\n")) {
146
                if (strncmp("version=1\r\n", p, strlen("version=1\r\n")) == 0 ||
147
                    strncmp("version=2\r\n", p, strlen("version=2\r\n")) == 0) {
148
                    return 100;
149
                }
150
            }
151
            return 0;
152
        }
153
        return 0;
154
    }
155
}
156

    
157
#define CHECK_CID 1
158

    
159
#define SECTOR_SIZE 512
160
#define DESC_SIZE (20 * SECTOR_SIZE)    /* 20 sectors of 512 bytes each */
161
#define BUF_SIZE 4096
162
#define HEADER_SIZE 512                 /* first sector of 512 bytes */
163

    
164
static void vmdk_free_extents(BlockDriverState *bs)
165
{
166
    int i;
167
    BDRVVmdkState *s = bs->opaque;
168

    
169
    for (i = 0; i < s->num_extents; i++) {
170
        qemu_free(s->extents[i].l1_table);
171
        qemu_free(s->extents[i].l2_cache);
172
        qemu_free(s->extents[i].l1_backup_table);
173
    }
174
    qemu_free(s->extents);
175
}
176

    
177
static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
178
{
179
    char desc[DESC_SIZE];
180
    uint32_t cid;
181
    const char *p_name, *cid_str;
182
    size_t cid_str_size;
183
    BDRVVmdkState *s = bs->opaque;
184

    
185
    if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
186
        return 0;
187
    }
188

    
189
    if (parent) {
190
        cid_str = "parentCID";
191
        cid_str_size = sizeof("parentCID");
192
    } else {
193
        cid_str = "CID";
194
        cid_str_size = sizeof("CID");
195
    }
196

    
197
    p_name = strstr(desc, cid_str);
198
    if (p_name != NULL) {
199
        p_name += cid_str_size;
200
        sscanf(p_name, "%x", &cid);
201
    }
202

    
203
    return cid;
204
}
205

    
206
static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
207
{
208
    char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
209
    char *p_name, *tmp_str;
210
    BDRVVmdkState *s = bs->opaque;
211

    
212
    memset(desc, 0, sizeof(desc));
213
    if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
214
        return -EIO;
215
    }
216

    
217
    tmp_str = strstr(desc, "parentCID");
218
    pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
219
    p_name = strstr(desc, "CID");
220
    if (p_name != NULL) {
221
        p_name += sizeof("CID");
222
        snprintf(p_name, sizeof(desc) - (p_name - desc), "%x\n", cid);
223
        pstrcat(desc, sizeof(desc), tmp_desc);
224
    }
225

    
226
    if (bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE) < 0) {
227
        return -EIO;
228
    }
229
    return 0;
230
}
231

    
232
static int vmdk_is_cid_valid(BlockDriverState *bs)
233
{
234
#ifdef CHECK_CID
235
    BDRVVmdkState *s = bs->opaque;
236
    BlockDriverState *p_bs = bs->backing_hd;
237
    uint32_t cur_pcid;
238

    
239
    if (p_bs) {
240
        cur_pcid = vmdk_read_cid(p_bs, 0);
241
        if (s->parent_cid != cur_pcid) {
242
            /* CID not valid */
243
            return 0;
244
        }
245
    }
246
#endif
247
    /* CID valid */
248
    return 1;
249
}
250

    
251
static int vmdk_parent_open(BlockDriverState *bs)
252
{
253
    char *p_name;
254
    char desc[DESC_SIZE + 1];
255
    BDRVVmdkState *s = bs->opaque;
256

    
257
    desc[DESC_SIZE] = '\0';
258
    if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
259
        return -1;
260
    }
261

    
262
    p_name = strstr(desc, "parentFileNameHint");
263
    if (p_name != NULL) {
264
        char *end_name;
265

    
266
        p_name += sizeof("parentFileNameHint") + 1;
267
        end_name = strchr(p_name, '\"');
268
        if (end_name == NULL) {
269
            return -1;
270
        }
271
        if ((end_name - p_name) > sizeof(bs->backing_file) - 1) {
272
            return -1;
273
        }
274

    
275
        pstrcpy(bs->backing_file, end_name - p_name + 1, p_name);
276
    }
277

    
278
    return 0;
279
}
280

    
281
/* Create and append extent to the extent array. Return the added VmdkExtent
282
 * address. return NULL if allocation failed. */
283
static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
284
                           BlockDriverState *file, bool flat, int64_t sectors,
285
                           int64_t l1_offset, int64_t l1_backup_offset,
286
                           uint32_t l1_size,
287
                           int l2_size, unsigned int cluster_sectors)
288
{
289
    VmdkExtent *extent;
290
    BDRVVmdkState *s = bs->opaque;
291

    
292
    s->extents = qemu_realloc(s->extents,
293
                              (s->num_extents + 1) * sizeof(VmdkExtent));
294
    extent = &s->extents[s->num_extents];
295
    s->num_extents++;
296

    
297
    memset(extent, 0, sizeof(VmdkExtent));
298
    extent->file = file;
299
    extent->flat = flat;
300
    extent->sectors = sectors;
301
    extent->l1_table_offset = l1_offset;
302
    extent->l1_backup_table_offset = l1_backup_offset;
303
    extent->l1_size = l1_size;
304
    extent->l1_entry_sectors = l2_size * cluster_sectors;
305
    extent->l2_size = l2_size;
306
    extent->cluster_sectors = cluster_sectors;
307

    
308
    if (s->num_extents > 1) {
309
        extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
310
    } else {
311
        extent->end_sector = extent->sectors;
312
    }
313
    bs->total_sectors = extent->end_sector;
314
    return extent;
315
}
316

    
317
static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
318
{
319
    int ret;
320
    int l1_size, i;
321

    
322
    /* read the L1 table */
323
    l1_size = extent->l1_size * sizeof(uint32_t);
324
    extent->l1_table = qemu_malloc(l1_size);
325
    ret = bdrv_pread(extent->file,
326
                    extent->l1_table_offset,
327
                    extent->l1_table,
328
                    l1_size);
329
    if (ret < 0) {
330
        goto fail_l1;
331
    }
332
    for (i = 0; i < extent->l1_size; i++) {
333
        le32_to_cpus(&extent->l1_table[i]);
334
    }
335

    
336
    if (extent->l1_backup_table_offset) {
337
        extent->l1_backup_table = qemu_malloc(l1_size);
338
        ret = bdrv_pread(extent->file,
339
                        extent->l1_backup_table_offset,
340
                        extent->l1_backup_table,
341
                        l1_size);
342
        if (ret < 0) {
343
            goto fail_l1b;
344
        }
345
        for (i = 0; i < extent->l1_size; i++) {
346
            le32_to_cpus(&extent->l1_backup_table[i]);
347
        }
348
    }
349

    
350
    extent->l2_cache =
351
        qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
352
    return 0;
353
 fail_l1b:
354
    qemu_free(extent->l1_backup_table);
355
 fail_l1:
356
    qemu_free(extent->l1_table);
357
    return ret;
358
}
359

    
360
static int vmdk_open_vmdk3(BlockDriverState *bs, int flags)
361
{
362
    int ret;
363
    uint32_t magic;
364
    VMDK3Header header;
365
    BDRVVmdkState *s = bs->opaque;
366
    VmdkExtent *extent;
367

    
368
    s->desc_offset = 0x200;
369
    ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
370
    if (ret < 0) {
371
        goto fail;
372
    }
373
    extent = vmdk_add_extent(bs,
374
                             bs->file, false,
375
                             le32_to_cpu(header.disk_sectors),
376
                             le32_to_cpu(header.l1dir_offset) << 9,
377
                             0, 1 << 6, 1 << 9,
378
                             le32_to_cpu(header.granularity));
379
    ret = vmdk_init_tables(bs, extent);
380
    if (ret) {
381
        /* vmdk_init_tables cleans up on fail, so only free allocation of
382
         * vmdk_add_extent here. */
383
        goto fail;
384
    }
385
    return 0;
386
 fail:
387
    vmdk_free_extents(bs);
388
    return ret;
389
}
390

    
391
static int vmdk_open_vmdk4(BlockDriverState *bs, int flags)
392
{
393
    int ret;
394
    uint32_t magic;
395
    uint32_t l1_size, l1_entry_sectors;
396
    VMDK4Header header;
397
    BDRVVmdkState *s = bs->opaque;
398
    VmdkExtent *extent;
399

    
400
    s->desc_offset = 0x200;
401
    ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
402
    if (ret < 0) {
403
        goto fail;
404
    }
405
    l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
406
                        * le64_to_cpu(header.granularity);
407
    l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
408
                / l1_entry_sectors;
409
    extent = vmdk_add_extent(bs, bs->file, false,
410
                          le64_to_cpu(header.capacity),
411
                          le64_to_cpu(header.gd_offset) << 9,
412
                          le64_to_cpu(header.rgd_offset) << 9,
413
                          l1_size,
414
                          le32_to_cpu(header.num_gtes_per_gte),
415
                          le64_to_cpu(header.granularity));
416
    if (extent->l1_entry_sectors <= 0) {
417
        ret = -EINVAL;
418
        goto fail;
419
    }
420
    /* try to open parent images, if exist */
421
    ret = vmdk_parent_open(bs);
422
    if (ret) {
423
        goto fail;
424
    }
425
    s->parent_cid = vmdk_read_cid(bs, 1);
426
    ret = vmdk_init_tables(bs, extent);
427
    if (ret) {
428
        goto fail;
429
    }
430
    return 0;
431
 fail:
432
    vmdk_free_extents(bs);
433
    return ret;
434
}
435

    
436
/* find an option value out of descriptor file */
437
static int vmdk_parse_description(const char *desc, const char *opt_name,
438
        char *buf, int buf_size)
439
{
440
    char *opt_pos, *opt_end;
441
    const char *end = desc + strlen(desc);
442

    
443
    opt_pos = strstr(desc, opt_name);
444
    if (!opt_pos) {
445
        return -1;
446
    }
447
    /* Skip "=\"" following opt_name */
448
    opt_pos += strlen(opt_name) + 2;
449
    if (opt_pos >= end) {
450
        return -1;
451
    }
452
    opt_end = opt_pos;
453
    while (opt_end < end && *opt_end != '"') {
454
        opt_end++;
455
    }
456
    if (opt_end == end || buf_size < opt_end - opt_pos + 1) {
457
        return -1;
458
    }
459
    pstrcpy(buf, opt_end - opt_pos + 1, opt_pos);
460
    return 0;
461
}
462

    
463
static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
464
        const char *desc_file_path)
465
{
466
    int ret;
467
    char access[11];
468
    char type[11];
469
    char fname[512];
470
    const char *p = desc;
471
    int64_t sectors = 0;
472
    int64_t flat_offset;
473

    
474
    while (*p) {
475
        /* parse extent line:
476
         * RW [size in sectors] FLAT "file-name.vmdk" OFFSET
477
         * or
478
         * RW [size in sectors] SPARSE "file-name.vmdk"
479
         */
480
        flat_offset = -1;
481
        ret = sscanf(p, "%10s %" SCNd64 " %10s %511s %" SCNd64,
482
                access, &sectors, type, fname, &flat_offset);
483
        if (ret < 4 || strcmp(access, "RW")) {
484
            goto next_line;
485
        } else if (!strcmp(type, "FLAT")) {
486
            if (ret != 5 || flat_offset < 0) {
487
                return -EINVAL;
488
            }
489
        } else if (ret != 4) {
490
            return -EINVAL;
491
        }
492

    
493
        /* trim the quotation marks around */
494
        if (fname[0] == '"') {
495
            memmove(fname, fname + 1, strlen(fname));
496
            if (strlen(fname) <= 1 || fname[strlen(fname) - 1] != '"') {
497
                return -EINVAL;
498
            }
499
            fname[strlen(fname) - 1] = '\0';
500
        }
501
        if (sectors <= 0 ||
502
            (strcmp(type, "FLAT") && strcmp(type, "SPARSE")) ||
503
            (strcmp(access, "RW"))) {
504
            goto next_line;
505
        }
506

    
507
        /* save to extents array */
508
        if (!strcmp(type, "FLAT")) {
509
            /* FLAT extent */
510
            char extent_path[PATH_MAX];
511
            BlockDriverState *extent_file;
512
            VmdkExtent *extent;
513

    
514
            path_combine(extent_path, sizeof(extent_path),
515
                    desc_file_path, fname);
516
            ret = bdrv_file_open(&extent_file, extent_path, bs->open_flags);
517
            if (ret) {
518
                return ret;
519
            }
520
            extent = vmdk_add_extent(bs, extent_file, true, sectors,
521
                            0, 0, 0, 0, sectors);
522
            extent->flat_start_offset = flat_offset;
523
        } else {
524
            /* SPARSE extent, not supported for now */
525
            fprintf(stderr,
526
                "VMDK: Not supported extent type \"%s\""".\n", type);
527
            return -ENOTSUP;
528
        }
529
next_line:
530
        /* move to next line */
531
        while (*p && *p != '\n') {
532
            p++;
533
        }
534
        p++;
535
    }
536
    return 0;
537
}
538

    
539
static int vmdk_open_desc_file(BlockDriverState *bs, int flags)
540
{
541
    int ret;
542
    char buf[2048];
543
    char ct[128];
544
    BDRVVmdkState *s = bs->opaque;
545

    
546
    ret = bdrv_pread(bs->file, 0, buf, sizeof(buf));
547
    if (ret < 0) {
548
        return ret;
549
    }
550
    buf[2047] = '\0';
551
    if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
552
        return -EINVAL;
553
    }
554
    if (strcmp(ct, "monolithicFlat")) {
555
        fprintf(stderr,
556
                "VMDK: Not supported image type \"%s\""".\n", ct);
557
        return -ENOTSUP;
558
    }
559
    s->desc_offset = 0;
560
    ret = vmdk_parse_extents(buf, bs, bs->file->filename);
561
    if (ret) {
562
        return ret;
563
    }
564

    
565
    /* try to open parent images, if exist */
566
    if (vmdk_parent_open(bs)) {
567
        qemu_free(s->extents);
568
        return -EINVAL;
569
    }
570
    s->parent_cid = vmdk_read_cid(bs, 1);
571
    return 0;
572
}
573

    
574
static int vmdk_open(BlockDriverState *bs, int flags)
575
{
576
    uint32_t magic;
577

    
578
    if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic)) {
579
        return -EIO;
580
    }
581

    
582
    magic = be32_to_cpu(magic);
583
    if (magic == VMDK3_MAGIC) {
584
        return vmdk_open_vmdk3(bs, flags);
585
    } else if (magic == VMDK4_MAGIC) {
586
        return vmdk_open_vmdk4(bs, flags);
587
    } else {
588
        return vmdk_open_desc_file(bs, flags);
589
    }
590
}
591

    
592
static int get_whole_cluster(BlockDriverState *bs,
593
                VmdkExtent *extent,
594
                uint64_t cluster_offset,
595
                uint64_t offset,
596
                bool allocate)
597
{
598
    /* 128 sectors * 512 bytes each = grain size 64KB */
599
    uint8_t  whole_grain[extent->cluster_sectors * 512];
600

    
601
    /* we will be here if it's first write on non-exist grain(cluster).
602
     * try to read from parent image, if exist */
603
    if (bs->backing_hd) {
604
        int ret;
605

    
606
        if (!vmdk_is_cid_valid(bs)) {
607
            return -1;
608
        }
609

    
610
        /* floor offset to cluster */
611
        offset -= offset % (extent->cluster_sectors * 512);
612
        ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
613
                extent->cluster_sectors);
614
        if (ret < 0) {
615
            return -1;
616
        }
617

    
618
        /* Write grain only into the active image */
619
        ret = bdrv_write(extent->file, cluster_offset, whole_grain,
620
                extent->cluster_sectors);
621
        if (ret < 0) {
622
            return -1;
623
        }
624
    }
625
    return 0;
626
}
627

    
628
static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
629
{
630
    /* update L2 table */
631
    if (bdrv_pwrite_sync(
632
                extent->file,
633
                ((int64_t)m_data->l2_offset * 512)
634
                    + (m_data->l2_index * sizeof(m_data->offset)),
635
                &(m_data->offset),
636
                sizeof(m_data->offset)
637
            ) < 0) {
638
        return -1;
639
    }
640
    /* update backup L2 table */
641
    if (extent->l1_backup_table_offset != 0) {
642
        m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
643
        if (bdrv_pwrite_sync(
644
                    extent->file,
645
                    ((int64_t)m_data->l2_offset * 512)
646
                        + (m_data->l2_index * sizeof(m_data->offset)),
647
                    &(m_data->offset), sizeof(m_data->offset)
648
                ) < 0) {
649
            return -1;
650
        }
651
    }
652

    
653
    return 0;
654
}
655

    
656
static int get_cluster_offset(BlockDriverState *bs,
657
                                    VmdkExtent *extent,
658
                                    VmdkMetaData *m_data,
659
                                    uint64_t offset,
660
                                    int allocate,
661
                                    uint64_t *cluster_offset)
662
{
663
    unsigned int l1_index, l2_offset, l2_index;
664
    int min_index, i, j;
665
    uint32_t min_count, *l2_table, tmp = 0;
666

    
667
    if (m_data) {
668
        m_data->valid = 0;
669
    }
670
    if (extent->flat) {
671
        *cluster_offset = extent->flat_start_offset;
672
        return 0;
673
    }
674

    
675
    l1_index = (offset >> 9) / extent->l1_entry_sectors;
676
    if (l1_index >= extent->l1_size) {
677
        return -1;
678
    }
679
    l2_offset = extent->l1_table[l1_index];
680
    if (!l2_offset) {
681
        return -1;
682
    }
683
    for (i = 0; i < L2_CACHE_SIZE; i++) {
684
        if (l2_offset == extent->l2_cache_offsets[i]) {
685
            /* increment the hit count */
686
            if (++extent->l2_cache_counts[i] == 0xffffffff) {
687
                for (j = 0; j < L2_CACHE_SIZE; j++) {
688
                    extent->l2_cache_counts[j] >>= 1;
689
                }
690
            }
691
            l2_table = extent->l2_cache + (i * extent->l2_size);
692
            goto found;
693
        }
694
    }
695
    /* not found: load a new entry in the least used one */
696
    min_index = 0;
697
    min_count = 0xffffffff;
698
    for (i = 0; i < L2_CACHE_SIZE; i++) {
699
        if (extent->l2_cache_counts[i] < min_count) {
700
            min_count = extent->l2_cache_counts[i];
701
            min_index = i;
702
        }
703
    }
704
    l2_table = extent->l2_cache + (min_index * extent->l2_size);
705
    if (bdrv_pread(
706
                extent->file,
707
                (int64_t)l2_offset * 512,
708
                l2_table,
709
                extent->l2_size * sizeof(uint32_t)
710
            ) != extent->l2_size * sizeof(uint32_t)) {
711
        return -1;
712
    }
713

    
714
    extent->l2_cache_offsets[min_index] = l2_offset;
715
    extent->l2_cache_counts[min_index] = 1;
716
 found:
717
    l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
718
    *cluster_offset = le32_to_cpu(l2_table[l2_index]);
719

    
720
    if (!*cluster_offset) {
721
        if (!allocate) {
722
            return -1;
723
        }
724

    
725
        /* Avoid the L2 tables update for the images that have snapshots. */
726
        *cluster_offset = bdrv_getlength(extent->file);
727
        bdrv_truncate(
728
            extent->file,
729
            *cluster_offset + (extent->cluster_sectors << 9)
730
        );
731

    
732
        *cluster_offset >>= 9;
733
        tmp = cpu_to_le32(*cluster_offset);
734
        l2_table[l2_index] = tmp;
735

    
736
        /* First of all we write grain itself, to avoid race condition
737
         * that may to corrupt the image.
738
         * This problem may occur because of insufficient space on host disk
739
         * or inappropriate VM shutdown.
740
         */
741
        if (get_whole_cluster(
742
                bs, extent, *cluster_offset, offset, allocate) == -1) {
743
            return -1;
744
        }
745

    
746
        if (m_data) {
747
            m_data->offset = tmp;
748
            m_data->l1_index = l1_index;
749
            m_data->l2_index = l2_index;
750
            m_data->l2_offset = l2_offset;
751
            m_data->valid = 1;
752
        }
753
    }
754
    *cluster_offset <<= 9;
755
    return 0;
756
}
757

    
758
static VmdkExtent *find_extent(BDRVVmdkState *s,
759
                                int64_t sector_num, VmdkExtent *start_hint)
760
{
761
    VmdkExtent *extent = start_hint;
762

    
763
    if (!extent) {
764
        extent = &s->extents[0];
765
    }
766
    while (extent < &s->extents[s->num_extents]) {
767
        if (sector_num < extent->end_sector) {
768
            return extent;
769
        }
770
        extent++;
771
    }
772
    return NULL;
773
}
774

    
775
static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
776
                             int nb_sectors, int *pnum)
777
{
778
    BDRVVmdkState *s = bs->opaque;
779
    int64_t index_in_cluster, n, ret;
780
    uint64_t offset;
781
    VmdkExtent *extent;
782

    
783
    extent = find_extent(s, sector_num, NULL);
784
    if (!extent) {
785
        return 0;
786
    }
787
    ret = get_cluster_offset(bs, extent, NULL,
788
                            sector_num * 512, 0, &offset);
789
    /* get_cluster_offset returning 0 means success */
790
    ret = !ret;
791

    
792
    index_in_cluster = sector_num % extent->cluster_sectors;
793
    n = extent->cluster_sectors - index_in_cluster;
794
    if (n > nb_sectors) {
795
        n = nb_sectors;
796
    }
797
    *pnum = n;
798
    return ret;
799
}
800

    
801
static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
802
                    uint8_t *buf, int nb_sectors)
803
{
804
    BDRVVmdkState *s = bs->opaque;
805
    int ret;
806
    uint64_t n, index_in_cluster;
807
    VmdkExtent *extent = NULL;
808
    uint64_t cluster_offset;
809

    
810
    while (nb_sectors > 0) {
811
        extent = find_extent(s, sector_num, extent);
812
        if (!extent) {
813
            return -EIO;
814
        }
815
        ret = get_cluster_offset(
816
                            bs, extent, NULL,
817
                            sector_num << 9, 0, &cluster_offset);
818
        index_in_cluster = sector_num % extent->cluster_sectors;
819
        n = extent->cluster_sectors - index_in_cluster;
820
        if (n > nb_sectors) {
821
            n = nb_sectors;
822
        }
823
        if (ret) {
824
            /* if not allocated, try to read from parent image, if exist */
825
            if (bs->backing_hd) {
826
                if (!vmdk_is_cid_valid(bs)) {
827
                    return -EINVAL;
828
                }
829
                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
830
                if (ret < 0) {
831
                    return ret;
832
                }
833
            } else {
834
                memset(buf, 0, 512 * n);
835
            }
836
        } else {
837
            ret = bdrv_pread(extent->file,
838
                            cluster_offset + index_in_cluster * 512,
839
                            buf, n * 512);
840
            if (ret < 0) {
841
                return ret;
842
            }
843
        }
844
        nb_sectors -= n;
845
        sector_num += n;
846
        buf += n * 512;
847
    }
848
    return 0;
849
}
850

    
851
static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
852
                     const uint8_t *buf, int nb_sectors)
853
{
854
    BDRVVmdkState *s = bs->opaque;
855
    VmdkExtent *extent = NULL;
856
    int n, ret;
857
    int64_t index_in_cluster;
858
    uint64_t cluster_offset;
859
    VmdkMetaData m_data;
860

    
861
    if (sector_num > bs->total_sectors) {
862
        fprintf(stderr,
863
                "(VMDK) Wrong offset: sector_num=0x%" PRIx64
864
                " total_sectors=0x%" PRIx64 "\n",
865
                sector_num, bs->total_sectors);
866
        return -EIO;
867
    }
868

    
869
    while (nb_sectors > 0) {
870
        extent = find_extent(s, sector_num, extent);
871
        if (!extent) {
872
            return -EIO;
873
        }
874
        ret = get_cluster_offset(
875
                                bs,
876
                                extent,
877
                                &m_data,
878
                                sector_num << 9, 1,
879
                                &cluster_offset);
880
        if (ret) {
881
            return -EINVAL;
882
        }
883
        index_in_cluster = sector_num % extent->cluster_sectors;
884
        n = extent->cluster_sectors - index_in_cluster;
885
        if (n > nb_sectors) {
886
            n = nb_sectors;
887
        }
888

    
889
        ret = bdrv_pwrite(extent->file,
890
                        cluster_offset + index_in_cluster * 512,
891
                        buf,
892
                        n * 512);
893
        if (ret < 0) {
894
            return ret;
895
        }
896
        if (m_data.valid) {
897
            /* update L2 tables */
898
            if (vmdk_L2update(extent, &m_data) == -1) {
899
                return -EIO;
900
            }
901
        }
902
        nb_sectors -= n;
903
        sector_num += n;
904
        buf += n * 512;
905

    
906
        /* update CID on the first write every time the virtual disk is
907
         * opened */
908
        if (!s->cid_updated) {
909
            vmdk_write_cid(bs, time(NULL));
910
            s->cid_updated = true;
911
        }
912
    }
913
    return 0;
914
}
915

    
916

    
917
static int vmdk_create_extent(const char *filename, int64_t filesize, bool flat)
918
{
919
    int ret, i;
920
    int fd = 0;
921
    VMDK4Header header;
922
    uint32_t tmp, magic, grains, gd_size, gt_size, gt_count;
923

    
924
    fd = open(
925
        filename,
926
        O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
927
        0644);
928
    if (fd < 0) {
929
        return -errno;
930
    }
931
    if (flat) {
932
        ret = ftruncate(fd, filesize);
933
        if (ret < 0) {
934
            ret = -errno;
935
        }
936
        goto exit;
937
    }
938
    magic = cpu_to_be32(VMDK4_MAGIC);
939
    memset(&header, 0, sizeof(header));
940
    header.version = 1;
941
    header.flags = 3; /* ?? */
942
    header.capacity = filesize / 512;
943
    header.granularity = 128;
944
    header.num_gtes_per_gte = 512;
945

    
946
    grains = (filesize / 512 + header.granularity - 1) / header.granularity;
947
    gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
948
    gt_count =
949
        (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
950
    gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
951

    
952
    header.desc_offset = 1;
953
    header.desc_size = 20;
954
    header.rgd_offset = header.desc_offset + header.desc_size;
955
    header.gd_offset = header.rgd_offset + gd_size + (gt_size * gt_count);
956
    header.grain_offset =
957
       ((header.gd_offset + gd_size + (gt_size * gt_count) +
958
         header.granularity - 1) / header.granularity) *
959
        header.granularity;
960
    /* swap endianness for all header fields */
961
    header.version = cpu_to_le32(header.version);
962
    header.flags = cpu_to_le32(header.flags);
963
    header.capacity = cpu_to_le64(header.capacity);
964
    header.granularity = cpu_to_le64(header.granularity);
965
    header.num_gtes_per_gte = cpu_to_le32(header.num_gtes_per_gte);
966
    header.desc_offset = cpu_to_le64(header.desc_offset);
967
    header.desc_size = cpu_to_le64(header.desc_size);
968
    header.rgd_offset = cpu_to_le64(header.rgd_offset);
969
    header.gd_offset = cpu_to_le64(header.gd_offset);
970
    header.grain_offset = cpu_to_le64(header.grain_offset);
971

    
972
    header.check_bytes[0] = 0xa;
973
    header.check_bytes[1] = 0x20;
974
    header.check_bytes[2] = 0xd;
975
    header.check_bytes[3] = 0xa;
976

    
977
    /* write all the data */
978
    ret = qemu_write_full(fd, &magic, sizeof(magic));
979
    if (ret != sizeof(magic)) {
980
        ret = -errno;
981
        goto exit;
982
    }
983
    ret = qemu_write_full(fd, &header, sizeof(header));
984
    if (ret != sizeof(header)) {
985
        ret = -errno;
986
        goto exit;
987
    }
988

    
989
    ret = ftruncate(fd, le64_to_cpu(header.grain_offset) << 9);
990
    if (ret < 0) {
991
        ret = -errno;
992
        goto exit;
993
    }
994

    
995
    /* write grain directory */
996
    lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET);
997
    for (i = 0, tmp = le64_to_cpu(header.rgd_offset) + gd_size;
998
         i < gt_count; i++, tmp += gt_size) {
999
        ret = qemu_write_full(fd, &tmp, sizeof(tmp));
1000
        if (ret != sizeof(tmp)) {
1001
            ret = -errno;
1002
            goto exit;
1003
        }
1004
    }
1005

    
1006
    /* write backup grain directory */
1007
    lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET);
1008
    for (i = 0, tmp = le64_to_cpu(header.gd_offset) + gd_size;
1009
         i < gt_count; i++, tmp += gt_size) {
1010
        ret = qemu_write_full(fd, &tmp, sizeof(tmp));
1011
        if (ret != sizeof(tmp)) {
1012
            ret = -errno;
1013
            goto exit;
1014
        }
1015
    }
1016

    
1017
    ret = 0;
1018
 exit:
1019
    close(fd);
1020
    return ret;
1021
}
1022

    
1023
static int filename_decompose(const char *filename, char *path, char *prefix,
1024
        char *postfix, size_t buf_len)
1025
{
1026
    const char *p, *q;
1027

    
1028
    if (filename == NULL || !strlen(filename)) {
1029
        fprintf(stderr, "Vmdk: no filename provided.\n");
1030
        return -1;
1031
    }
1032
    p = strrchr(filename, '/');
1033
    if (p == NULL) {
1034
        p = strrchr(filename, '\\');
1035
    }
1036
    if (p == NULL) {
1037
        p = strrchr(filename, ':');
1038
    }
1039
    if (p != NULL) {
1040
        p++;
1041
        if (p - filename >= buf_len) {
1042
            return -1;
1043
        }
1044
        pstrcpy(path, p - filename + 1, filename);
1045
    } else {
1046
        p = filename;
1047
        path[0] = '\0';
1048
    }
1049
    q = strrchr(p, '.');
1050
    if (q == NULL) {
1051
        pstrcpy(prefix, buf_len, p);
1052
        postfix[0] = '\0';
1053
    } else {
1054
        if (q - p >= buf_len) {
1055
            return -1;
1056
        }
1057
        pstrcpy(prefix, q - p + 1, p);
1058
        pstrcpy(postfix, buf_len, q);
1059
    }
1060
    return 0;
1061
}
1062

    
1063
static int relative_path(char *dest, int dest_size,
1064
        const char *base, const char *target)
1065
{
1066
    int i = 0;
1067
    int n = 0;
1068
    const char *p, *q;
1069
#ifdef _WIN32
1070
    const char *sep = "\\";
1071
#else
1072
    const char *sep = "/";
1073
#endif
1074

    
1075
    if (!(dest && base && target)) {
1076
        return -1;
1077
    }
1078
    if (path_is_absolute(target)) {
1079
        dest[dest_size - 1] = '\0';
1080
        strncpy(dest, target, dest_size - 1);
1081
        return 0;
1082
    }
1083
    while (base[i] == target[i]) {
1084
        i++;
1085
    }
1086
    p = &base[i];
1087
    q = &target[i];
1088
    while (*p) {
1089
        if (*p == *sep) {
1090
            n++;
1091
        }
1092
        p++;
1093
    }
1094
    dest[0] = '\0';
1095
    for (; n; n--) {
1096
        pstrcat(dest, dest_size, "..");
1097
        pstrcat(dest, dest_size, sep);
1098
    }
1099
    pstrcat(dest, dest_size, q);
1100
    return 0;
1101
}
1102

    
1103
static int vmdk_create(const char *filename, QEMUOptionParameter *options)
1104
{
1105
    int fd, idx = 0;
1106
    char desc[BUF_SIZE];
1107
    int64_t total_size = 0, filesize;
1108
    const char *backing_file = NULL;
1109
    const char *fmt = NULL;
1110
    int flags = 0;
1111
    int ret = 0;
1112
    bool flat, split;
1113
    char ext_desc_lines[BUF_SIZE] = "";
1114
    char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
1115
    const int64_t split_size = 0x80000000;  /* VMDK has constant split size */
1116
    const char *desc_extent_line;
1117
    char parent_desc_line[BUF_SIZE] = "";
1118
    uint32_t parent_cid = 0xffffffff;
1119
    const char desc_template[] =
1120
        "# Disk DescriptorFile\n"
1121
        "version=1\n"
1122
        "CID=%x\n"
1123
        "parentCID=%x\n"
1124
        "createType=\"%s\"\n"
1125
        "%s"
1126
        "\n"
1127
        "# Extent description\n"
1128
        "%s"
1129
        "\n"
1130
        "# The Disk Data Base\n"
1131
        "#DDB\n"
1132
        "\n"
1133
        "ddb.virtualHWVersion = \"%d\"\n"
1134
        "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
1135
        "ddb.geometry.heads = \"16\"\n"
1136
        "ddb.geometry.sectors = \"63\"\n"
1137
        "ddb.adapterType = \"ide\"\n";
1138

    
1139
    if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
1140
        return -EINVAL;
1141
    }
1142
    /* Read out options */
1143
    while (options && options->name) {
1144
        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
1145
            total_size = options->value.n;
1146
        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
1147
            backing_file = options->value.s;
1148
        } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
1149
            flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
1150
        } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
1151
            fmt = options->value.s;
1152
        }
1153
        options++;
1154
    }
1155
    if (!fmt) {
1156
        /* Default format to monolithicSparse */
1157
        fmt = "monolithicSparse";
1158
    } else if (strcmp(fmt, "monolithicFlat") &&
1159
               strcmp(fmt, "monolithicSparse") &&
1160
               strcmp(fmt, "twoGbMaxExtentSparse") &&
1161
               strcmp(fmt, "twoGbMaxExtentFlat")) {
1162
        fprintf(stderr, "VMDK: Unknown subformat: %s\n", fmt);
1163
        return -EINVAL;
1164
    }
1165
    split = !(strcmp(fmt, "twoGbMaxExtentFlat") &&
1166
              strcmp(fmt, "twoGbMaxExtentSparse"));
1167
    flat = !(strcmp(fmt, "monolithicFlat") &&
1168
             strcmp(fmt, "twoGbMaxExtentFlat"));
1169
    if (flat) {
1170
        desc_extent_line = "RW %lld FLAT \"%s\" 0\n";
1171
    } else {
1172
        desc_extent_line = "RW %lld SPARSE \"%s\"\n";
1173
    }
1174
    if (flat && backing_file) {
1175
        /* not supporting backing file for flat image */
1176
        return -ENOTSUP;
1177
    }
1178
    if (backing_file) {
1179
        char parent_filename[PATH_MAX];
1180
        BlockDriverState *bs = bdrv_new("");
1181
        ret = bdrv_open(bs, backing_file, 0, NULL);
1182
        if (ret != 0) {
1183
            bdrv_delete(bs);
1184
            return ret;
1185
        }
1186
        if (strcmp(bs->drv->format_name, "vmdk")) {
1187
            bdrv_delete(bs);
1188
            return -EINVAL;
1189
        }
1190
        filesize = bdrv_getlength(bs);
1191
        parent_cid = vmdk_read_cid(bs, 0);
1192
        bdrv_delete(bs);
1193
        relative_path(parent_filename, sizeof(parent_filename),
1194
                      filename, backing_file);
1195
        snprintf(parent_desc_line, sizeof(parent_desc_line),
1196
                "parentFileNameHint=\"%s\"", parent_filename);
1197
    }
1198

    
1199
    /* Create extents */
1200
    filesize = total_size;
1201
    while (filesize > 0) {
1202
        char desc_line[BUF_SIZE];
1203
        char ext_filename[PATH_MAX];
1204
        char desc_filename[PATH_MAX];
1205
        int64_t size = filesize;
1206

    
1207
        if (split && size > split_size) {
1208
            size = split_size;
1209
        }
1210
        if (split) {
1211
            snprintf(desc_filename, sizeof(desc_filename), "%s-%c%03d%s",
1212
                    prefix, flat ? 'f' : 's', ++idx, postfix);
1213
        } else if (flat) {
1214
            snprintf(desc_filename, sizeof(desc_filename), "%s-flat%s",
1215
                    prefix, postfix);
1216
        } else {
1217
            snprintf(desc_filename, sizeof(desc_filename), "%s%s",
1218
                    prefix, postfix);
1219
        }
1220
        snprintf(ext_filename, sizeof(ext_filename), "%s%s",
1221
                path, desc_filename);
1222

    
1223
        if (vmdk_create_extent(ext_filename, size, flat)) {
1224
            return -EINVAL;
1225
        }
1226
        filesize -= size;
1227

    
1228
        /* Format description line */
1229
        snprintf(desc_line, sizeof(desc_line),
1230
                    desc_extent_line, size / 512, desc_filename);
1231
        pstrcat(ext_desc_lines, sizeof(ext_desc_lines), desc_line);
1232
    }
1233
    /* generate descriptor file */
1234
    snprintf(desc, sizeof(desc), desc_template,
1235
            (unsigned int)time(NULL),
1236
            parent_cid,
1237
            fmt,
1238
            parent_desc_line,
1239
            ext_desc_lines,
1240
            (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
1241
            total_size / (int64_t)(63 * 16 * 512));
1242
    if (split || flat) {
1243
        fd = open(
1244
                filename,
1245
                O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
1246
                0644);
1247
    } else {
1248
        fd = open(
1249
                filename,
1250
                O_WRONLY | O_BINARY | O_LARGEFILE,
1251
                0644);
1252
    }
1253
    if (fd < 0) {
1254
        return -errno;
1255
    }
1256
    /* the descriptor offset = 0x200 */
1257
    if (!split && !flat && 0x200 != lseek(fd, 0x200, SEEK_SET)) {
1258
        ret = -errno;
1259
        goto exit;
1260
    }
1261
    ret = qemu_write_full(fd, desc, strlen(desc));
1262
    if (ret != strlen(desc)) {
1263
        ret = -errno;
1264
        goto exit;
1265
    }
1266
    ret = 0;
1267
exit:
1268
    close(fd);
1269
    return ret;
1270
}
1271

    
1272
static void vmdk_close(BlockDriverState *bs)
1273
{
1274
    vmdk_free_extents(bs);
1275
}
1276

    
1277
static int vmdk_flush(BlockDriverState *bs)
1278
{
1279
    int i, ret, err;
1280
    BDRVVmdkState *s = bs->opaque;
1281

    
1282
    ret = bdrv_flush(bs->file);
1283
    for (i = 0; i < s->num_extents; i++) {
1284
        err = bdrv_flush(s->extents[i].file);
1285
        if (err < 0) {
1286
            ret = err;
1287
        }
1288
    }
1289
    return ret;
1290
}
1291

    
1292
static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs)
1293
{
1294
    int i;
1295
    int64_t ret = 0;
1296
    int64_t r;
1297
    BDRVVmdkState *s = bs->opaque;
1298

    
1299
    ret = bdrv_get_allocated_file_size(bs->file);
1300
    if (ret < 0) {
1301
        return ret;
1302
    }
1303
    for (i = 0; i < s->num_extents; i++) {
1304
        if (s->extents[i].file == bs->file) {
1305
            continue;
1306
        }
1307
        r = bdrv_get_allocated_file_size(s->extents[i].file);
1308
        if (r < 0) {
1309
            return r;
1310
        }
1311
        ret += r;
1312
    }
1313
    return ret;
1314
}
1315

    
1316
static QEMUOptionParameter vmdk_create_options[] = {
1317
    {
1318
        .name = BLOCK_OPT_SIZE,
1319
        .type = OPT_SIZE,
1320
        .help = "Virtual disk size"
1321
    },
1322
    {
1323
        .name = BLOCK_OPT_BACKING_FILE,
1324
        .type = OPT_STRING,
1325
        .help = "File name of a base image"
1326
    },
1327
    {
1328
        .name = BLOCK_OPT_COMPAT6,
1329
        .type = OPT_FLAG,
1330
        .help = "VMDK version 6 image"
1331
    },
1332
    {
1333
        .name = BLOCK_OPT_SUBFMT,
1334
        .type = OPT_STRING,
1335
        .help =
1336
            "VMDK flat extent format, can be one of "
1337
            "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat} "
1338
    },
1339
    { NULL }
1340
};
1341

    
1342
static BlockDriver bdrv_vmdk = {
1343
    .format_name    = "vmdk",
1344
    .instance_size  = sizeof(BDRVVmdkState),
1345
    .bdrv_probe     = vmdk_probe,
1346
    .bdrv_open      = vmdk_open,
1347
    .bdrv_read      = vmdk_read,
1348
    .bdrv_write     = vmdk_write,
1349
    .bdrv_close     = vmdk_close,
1350
    .bdrv_create    = vmdk_create,
1351
    .bdrv_flush     = vmdk_flush,
1352
    .bdrv_is_allocated  = vmdk_is_allocated,
1353
    .bdrv_get_allocated_file_size  = vmdk_get_allocated_file_size,
1354

    
1355
    .create_options = vmdk_create_options,
1356
};
1357

    
1358
static void bdrv_vmdk_init(void)
1359
{
1360
    bdrv_register(&bdrv_vmdk);
1361
}
1362

    
1363
block_init(bdrv_vmdk_init);