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 #include "zlib.h" 30 31 #define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D') 32 #define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V') 33 #define VMDK4_COMPRESSION_DEFLATE 1 34 #define VMDK4_FLAG_RGD (1 << 1) 35 #define VMDK4_FLAG_COMPRESS (1 << 16) 36 #define VMDK4_FLAG_MARKER (1 << 17) 37 38 typedef struct { 39 uint32_t version; 40 uint32_t flags; 41 uint32_t disk_sectors; 42 uint32_t granularity; 43 uint32_t l1dir_offset; 44 uint32_t l1dir_size; 45 uint32_t file_sectors; 46 uint32_t cylinders; 47 uint32_t heads; 48 uint32_t sectors_per_track; 49 } VMDK3Header; 50 51 typedef struct { 52 uint32_t version; 53 uint32_t flags; 54 int64_t capacity; 55 int64_t granularity; 56 int64_t desc_offset; 57 int64_t desc_size; 58 int32_t num_gtes_per_gte; 59 int64_t gd_offset; 60 int64_t rgd_offset; 61 int64_t grain_offset; 62 char filler[1]; 63 char check_bytes[4]; 64 uint16_t compressAlgorithm; 65 } QEMU_PACKED VMDK4Header; 66 67 #define L2_CACHE_SIZE 16 68 69 typedef struct VmdkExtent { 70 BlockDriverState *file; 71 bool flat; 72 bool compressed; 73 bool has_marker; 74 int64_t sectors; 75 int64_t end_sector; 76 int64_t flat_start_offset; 77 int64_t l1_table_offset; 78 int64_t l1_backup_table_offset; 79 uint32_t *l1_table; 80 uint32_t *l1_backup_table; 81 unsigned int l1_size; 82 uint32_t l1_entry_sectors; 83 84 unsigned int l2_size; 85 uint32_t *l2_cache; 86 uint32_t l2_cache_offsets[L2_CACHE_SIZE]; 87 uint32_t l2_cache_counts[L2_CACHE_SIZE]; 88 89 unsigned int cluster_sectors; 90 } VmdkExtent; 91 92 typedef struct BDRVVmdkState { 93 int desc_offset; 94 bool cid_updated; 95 uint32_t parent_cid; 96 int num_extents; 97 /* Extent array with num_extents entries, ascend ordered by address */ 98 VmdkExtent *extents; 99 } BDRVVmdkState; 100 101 typedef struct VmdkMetaData { 102 uint32_t offset; 103 unsigned int l1_index; 104 unsigned int l2_index; 105 unsigned int l2_offset; 106 int valid; 107 } VmdkMetaData; 108 109 typedef struct VmdkGrainMarker { 110 uint64_t lba; 111 uint32_t size; 112 uint8_t data[0]; 113 } VmdkGrainMarker; 114 115 static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename) 116 { 117 uint32_t magic; 118 119 if (buf_size < 4) { 120 return 0; 121 } 122 magic = be32_to_cpu(*(uint32_t *)buf); 123 if (magic == VMDK3_MAGIC || 124 magic == VMDK4_MAGIC) { 125 return 100; 126 } else { 127 const char *p = (const char *)buf; 128 const char *end = p + buf_size; 129 while (p < end) { 130 if (*p == '#') { 131 /* skip comment line */ 132 while (p < end && *p != '\n') { 133 p++; 134 } 135 p++; 136 continue; 137 } 138 if (*p == ' ') { 139 while (p < end && *p == ' ') { 140 p++; 141 } 142 /* skip '\r' if windows line endings used. */ 143 if (p < end && *p == '\r') { 144 p++; 145 } 146 /* only accept blank lines before 'version=' line */ 147 if (p == end || *p != '\n') { 148 return 0; 149 } 150 p++; 151 continue; 152 } 153 if (end - p >= strlen("version=X\n")) { 154 if (strncmp("version=1\n", p, strlen("version=1\n")) == 0 || 155 strncmp("version=2\n", p, strlen("version=2\n")) == 0) { 156 return 100; 157 } 158 } 159 if (end - p >= strlen("version=X\r\n")) { 160 if (strncmp("version=1\r\n", p, strlen("version=1\r\n")) == 0 || 161 strncmp("version=2\r\n", p, strlen("version=2\r\n")) == 0) { 162 return 100; 163 } 164 } 165 return 0; 166 } 167 return 0; 168 } 169 } 170 171 #define CHECK_CID 1 172 173 #define SECTOR_SIZE 512 174 #define DESC_SIZE (20 * SECTOR_SIZE) /* 20 sectors of 512 bytes each */ 175 #define BUF_SIZE 4096 176 #define HEADER_SIZE 512 /* first sector of 512 bytes */ 177 178 static void vmdk_free_extents(BlockDriverState *bs) 179 { 180 int i; 181 BDRVVmdkState *s = bs->opaque; 182 VmdkExtent *e; 183 184 for (i = 0; i < s->num_extents; i++) { 185 e = &s->extents[i]; 186 g_free(e->l1_table); 187 g_free(e->l2_cache); 188 g_free(e->l1_backup_table); 189 if (e->file != bs->file) { 190 bdrv_delete(e->file); 191 } 192 } 193 g_free(s->extents); 194 } 195 196 static void vmdk_free_last_extent(BlockDriverState *bs) 197 { 198 BDRVVmdkState *s = bs->opaque; 199 200 if (s->num_extents == 0) { 201 return; 202 } 203 s->num_extents--; 204 s->extents = g_realloc(s->extents, s->num_extents * sizeof(VmdkExtent)); 205 } 206 207 static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent) 208 { 209 char desc[DESC_SIZE]; 210 uint32_t cid; 211 const char *p_name, *cid_str; 212 size_t cid_str_size; 213 BDRVVmdkState *s = bs->opaque; 214 215 if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) { 216 return 0; 217 } 218 219 if (parent) { 220 cid_str = "parentCID"; 221 cid_str_size = sizeof("parentCID"); 222 } else { 223 cid_str = "CID"; 224 cid_str_size = sizeof("CID"); 225 } 226 227 p_name = strstr(desc, cid_str); 228 if (p_name != NULL) { 229 p_name += cid_str_size; 230 sscanf(p_name, "%x", &cid); 231 } 232 233 return cid; 234 } 235 236 static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid) 237 { 238 char desc[DESC_SIZE], tmp_desc[DESC_SIZE]; 239 char *p_name, *tmp_str; 240 BDRVVmdkState *s = bs->opaque; 241 242 memset(desc, 0, sizeof(desc)); 243 if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) { 244 return -EIO; 245 } 246 247 tmp_str = strstr(desc, "parentCID"); 248 pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str); 249 p_name = strstr(desc, "CID"); 250 if (p_name != NULL) { 251 p_name += sizeof("CID"); 252 snprintf(p_name, sizeof(desc) - (p_name - desc), "%x\n", cid); 253 pstrcat(desc, sizeof(desc), tmp_desc); 254 } 255 256 if (bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE) < 0) { 257 return -EIO; 258 } 259 return 0; 260 } 261 262 static int vmdk_is_cid_valid(BlockDriverState *bs) 263 { 264 #ifdef CHECK_CID 265 BDRVVmdkState *s = bs->opaque; 266 BlockDriverState *p_bs = bs->backing_hd; 267 uint32_t cur_pcid; 268 269 if (p_bs) { 270 cur_pcid = vmdk_read_cid(p_bs, 0); 271 if (s->parent_cid != cur_pcid) { 272 /* CID not valid */ 273 return 0; 274 } 275 } 276 #endif 277 /* CID valid */ 278 return 1; 279 } 280 281 static int vmdk_parent_open(BlockDriverState *bs) 282 { 283 char *p_name; 284 char desc[DESC_SIZE + 1]; 285 BDRVVmdkState *s = bs->opaque; 286 287 desc[DESC_SIZE] = '\0'; 288 if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) { 289 return -1; 290 } 291 292 p_name = strstr(desc, "parentFileNameHint"); 293 if (p_name != NULL) { 294 char *end_name; 295 296 p_name += sizeof("parentFileNameHint") + 1; 297 end_name = strchr(p_name, '\"'); 298 if (end_name == NULL) { 299 return -1; 300 } 301 if ((end_name - p_name) > sizeof(bs->backing_file) - 1) { 302 return -1; 303 } 304 305 pstrcpy(bs->backing_file, end_name - p_name + 1, p_name); 306 } 307 308 return 0; 309 } 310 311 /* Create and append extent to the extent array. Return the added VmdkExtent 312 * address. return NULL if allocation failed. */ 313 static VmdkExtent *vmdk_add_extent(BlockDriverState *bs, 314 BlockDriverState *file, bool flat, int64_t sectors, 315 int64_t l1_offset, int64_t l1_backup_offset, 316 uint32_t l1_size, 317 int l2_size, unsigned int cluster_sectors) 318 { 319 VmdkExtent *extent; 320 BDRVVmdkState *s = bs->opaque; 321 322 s->extents = g_realloc(s->extents, 323 (s->num_extents + 1) * sizeof(VmdkExtent)); 324 extent = &s->extents[s->num_extents]; 325 s->num_extents++; 326 327 memset(extent, 0, sizeof(VmdkExtent)); 328 extent->file = file; 329 extent->flat = flat; 330 extent->sectors = sectors; 331 extent->l1_table_offset = l1_offset; 332 extent->l1_backup_table_offset = l1_backup_offset; 333 extent->l1_size = l1_size; 334 extent->l1_entry_sectors = l2_size * cluster_sectors; 335 extent->l2_size = l2_size; 336 extent->cluster_sectors = cluster_sectors; 337 338 if (s->num_extents > 1) { 339 extent->end_sector = (*(extent - 1)).end_sector + extent->sectors; 340 } else { 341 extent->end_sector = extent->sectors; 342 } 343 bs->total_sectors = extent->end_sector; 344 return extent; 345 } 346 347 static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent) 348 { 349 int ret; 350 int l1_size, i; 351 352 /* read the L1 table */ 353 l1_size = extent->l1_size * sizeof(uint32_t); 354 extent->l1_table = g_malloc(l1_size); 355 ret = bdrv_pread(extent->file, 356 extent->l1_table_offset, 357 extent->l1_table, 358 l1_size); 359 if (ret < 0) { 360 goto fail_l1; 361 } 362 for (i = 0; i < extent->l1_size; i++) { 363 le32_to_cpus(&extent->l1_table[i]); 364 } 365 366 if (extent->l1_backup_table_offset) { 367 extent->l1_backup_table = g_malloc(l1_size); 368 ret = bdrv_pread(extent->file, 369 extent->l1_backup_table_offset, 370 extent->l1_backup_table, 371 l1_size); 372 if (ret < 0) { 373 goto fail_l1b; 374 } 375 for (i = 0; i < extent->l1_size; i++) { 376 le32_to_cpus(&extent->l1_backup_table[i]); 377 } 378 } 379 380 extent->l2_cache = 381 g_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t)); 382 return 0; 383 fail_l1b: 384 g_free(extent->l1_backup_table); 385 fail_l1: 386 g_free(extent->l1_table); 387 return ret; 388 } 389 390 static int vmdk_open_vmdk3(BlockDriverState *bs, 391 BlockDriverState *file, 392 int flags) 393 { 394 int ret; 395 uint32_t magic; 396 VMDK3Header header; 397 VmdkExtent *extent; 398 399 ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header)); 400 if (ret < 0) { 401 return ret; 402 } 403 extent = vmdk_add_extent(bs, 404 bs->file, false, 405 le32_to_cpu(header.disk_sectors), 406 le32_to_cpu(header.l1dir_offset) << 9, 407 0, 1 << 6, 1 << 9, 408 le32_to_cpu(header.granularity)); 409 ret = vmdk_init_tables(bs, extent); 410 if (ret) { 411 /* free extent allocated by vmdk_add_extent */ 412 vmdk_free_last_extent(bs); 413 } 414 return ret; 415 } 416 417 static int vmdk_open_desc_file(BlockDriverState *bs, int flags, 418 int64_t desc_offset); 419 420 static int vmdk_open_vmdk4(BlockDriverState *bs, 421 BlockDriverState *file, 422 int flags) 423 { 424 int ret; 425 uint32_t magic; 426 uint32_t l1_size, l1_entry_sectors; 427 VMDK4Header header; 428 VmdkExtent *extent; 429 int64_t l1_backup_offset = 0; 430 431 ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header)); 432 if (ret < 0) { 433 return ret; 434 } 435 if (header.capacity == 0 && header.desc_offset) { 436 return vmdk_open_desc_file(bs, flags, header.desc_offset << 9); 437 } 438 l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte) 439 * le64_to_cpu(header.granularity); 440 if (l1_entry_sectors <= 0) { 441 return -EINVAL; 442 } 443 l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1) 444 / l1_entry_sectors; 445 if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) { 446 l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9; 447 } 448 extent = vmdk_add_extent(bs, file, false, 449 le64_to_cpu(header.capacity), 450 le64_to_cpu(header.gd_offset) << 9, 451 l1_backup_offset, 452 l1_size, 453 le32_to_cpu(header.num_gtes_per_gte), 454 le64_to_cpu(header.granularity)); 455 extent->compressed = 456 le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE; 457 extent->has_marker = le32_to_cpu(header.flags) & VMDK4_FLAG_MARKER; 458 ret = vmdk_init_tables(bs, extent); 459 if (ret) { 460 /* free extent allocated by vmdk_add_extent */ 461 vmdk_free_last_extent(bs); 462 } 463 return ret; 464 } 465 466 /* find an option value out of descriptor file */ 467 static int vmdk_parse_description(const char *desc, const char *opt_name, 468 char *buf, int buf_size) 469 { 470 char *opt_pos, *opt_end; 471 const char *end = desc + strlen(desc); 472 473 opt_pos = strstr(desc, opt_name); 474 if (!opt_pos) { 475 return -1; 476 } 477 /* Skip "=\"" following opt_name */ 478 opt_pos += strlen(opt_name) + 2; 479 if (opt_pos >= end) { 480 return -1; 481 } 482 opt_end = opt_pos; 483 while (opt_end < end && *opt_end != '"') { 484 opt_end++; 485 } 486 if (opt_end == end || buf_size < opt_end - opt_pos + 1) { 487 return -1; 488 } 489 pstrcpy(buf, opt_end - opt_pos + 1, opt_pos); 490 return 0; 491 } 492 493 /* Open an extent file and append to bs array */ 494 static int vmdk_open_sparse(BlockDriverState *bs, 495 BlockDriverState *file, 496 int flags) 497 { 498 uint32_t magic; 499 500 if (bdrv_pread(file, 0, &magic, sizeof(magic)) != sizeof(magic)) { 501 return -EIO; 502 } 503 504 magic = be32_to_cpu(magic); 505 switch (magic) { 506 case VMDK3_MAGIC: 507 return vmdk_open_vmdk3(bs, file, flags); 508 break; 509 case VMDK4_MAGIC: 510 return vmdk_open_vmdk4(bs, file, flags); 511 break; 512 default: 513 return -EINVAL; 514 break; 515 } 516 } 517 518 static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, 519 const char *desc_file_path) 520 { 521 int ret; 522 char access[11]; 523 char type[11]; 524 char fname[512]; 525 const char *p = desc; 526 int64_t sectors = 0; 527 int64_t flat_offset; 528 char extent_path[PATH_MAX]; 529 BlockDriverState *extent_file; 530 531 while (*p) { 532 /* parse extent line: 533 * RW [size in sectors] FLAT "file-name.vmdk" OFFSET 534 * or 535 * RW [size in sectors] SPARSE "file-name.vmdk" 536 */ 537 flat_offset = -1; 538 ret = sscanf(p, "%10s %" SCNd64 " %10s %511s %" SCNd64, 539 access, §ors, type, fname, &flat_offset); 540 if (ret < 4 || strcmp(access, "RW")) { 541 goto next_line; 542 } else if (!strcmp(type, "FLAT")) { 543 if (ret != 5 || flat_offset < 0) { 544 return -EINVAL; 545 } 546 } else if (ret != 4) { 547 return -EINVAL; 548 } 549 550 /* trim the quotation marks around */ 551 if (fname[0] == '"') { 552 memmove(fname, fname + 1, strlen(fname)); 553 if (strlen(fname) <= 1 || fname[strlen(fname) - 1] != '"') { 554 return -EINVAL; 555 } 556 fname[strlen(fname) - 1] = '\0'; 557 } 558 if (sectors <= 0 || 559 (strcmp(type, "FLAT") && strcmp(type, "SPARSE")) || 560 (strcmp(access, "RW"))) { 561 goto next_line; 562 } 563 564 path_combine(extent_path, sizeof(extent_path), 565 desc_file_path, fname); 566 ret = bdrv_file_open(&extent_file, extent_path, bs->open_flags); 567 if (ret) { 568 return ret; 569 } 570 571 /* save to extents array */ 572 if (!strcmp(type, "FLAT")) { 573 /* FLAT extent */ 574 VmdkExtent *extent; 575 576 extent = vmdk_add_extent(bs, extent_file, true, sectors, 577 0, 0, 0, 0, sectors); 578 extent->flat_start_offset = flat_offset << 9; 579 } else if (!strcmp(type, "SPARSE")) { 580 /* SPARSE extent */ 581 ret = vmdk_open_sparse(bs, extent_file, bs->open_flags); 582 if (ret) { 583 bdrv_delete(extent_file); 584 return ret; 585 } 586 } else { 587 fprintf(stderr, 588 "VMDK: Not supported extent type \"%s\""".\n", type); 589 return -ENOTSUP; 590 } 591 next_line: 592 /* move to next line */ 593 while (*p && *p != '\n') { 594 p++; 595 } 596 p++; 597 } 598 return 0; 599 } 600 601 static int vmdk_open_desc_file(BlockDriverState *bs, int flags, 602 int64_t desc_offset) 603 { 604 int ret; 605 char buf[2048]; 606 char ct[128]; 607 BDRVVmdkState *s = bs->opaque; 608 609 ret = bdrv_pread(bs->file, desc_offset, buf, sizeof(buf)); 610 if (ret < 0) { 611 return ret; 612 } 613 buf[2047] = '\0'; 614 if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) { 615 return -EINVAL; 616 } 617 if (strcmp(ct, "monolithicFlat") && 618 strcmp(ct, "twoGbMaxExtentSparse") && 619 strcmp(ct, "twoGbMaxExtentFlat")) { 620 fprintf(stderr, 621 "VMDK: Not supported image type \"%s\""".\n", ct); 622 return -ENOTSUP; 623 } 624 s->desc_offset = 0; 625 ret = vmdk_parse_extents(buf, bs, bs->file->filename); 626 if (ret) { 627 vmdk_free_extents(bs); 628 return ret; 629 } 630 631 /* try to open parent images, if exist */ 632 if (vmdk_parent_open(bs)) { 633 vmdk_free_extents(bs); 634 return -EINVAL; 635 } 636 s->parent_cid = vmdk_read_cid(bs, 1); 637 return 0; 638 } 639 640 static int vmdk_open(BlockDriverState *bs, int flags) 641 { 642 int ret; 643 BDRVVmdkState *s = bs->opaque; 644 645 if (vmdk_open_sparse(bs, bs->file, flags) == 0) { 646 s->desc_offset = 0x200; 647 /* try to open parent images, if exist */ 648 ret = vmdk_parent_open(bs); 649 if (ret) { 650 vmdk_free_extents(bs); 651 return ret; 652 } 653 s->parent_cid = vmdk_read_cid(bs, 1); 654 return 0; 655 } else { 656 return vmdk_open_desc_file(bs, flags, 0); 657 } 658 } 659 660 static int get_whole_cluster(BlockDriverState *bs, 661 VmdkExtent *extent, 662 uint64_t cluster_offset, 663 uint64_t offset, 664 bool allocate) 665 { 666 /* 128 sectors * 512 bytes each = grain size 64KB */ 667 uint8_t whole_grain[extent->cluster_sectors * 512]; 668 669 /* we will be here if it's first write on non-exist grain(cluster). 670 * try to read from parent image, if exist */ 671 if (bs->backing_hd) { 672 int ret; 673 674 if (!vmdk_is_cid_valid(bs)) { 675 return -1; 676 } 677 678 /* floor offset to cluster */ 679 offset -= offset % (extent->cluster_sectors * 512); 680 ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain, 681 extent->cluster_sectors); 682 if (ret < 0) { 683 return -1; 684 } 685 686 /* Write grain only into the active image */ 687 ret = bdrv_write(extent->file, cluster_offset, whole_grain, 688 extent->cluster_sectors); 689 if (ret < 0) { 690 return -1; 691 } 692 } 693 return 0; 694 } 695 696 static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data) 697 { 698 /* update L2 table */ 699 if (bdrv_pwrite_sync( 700 extent->file, 701 ((int64_t)m_data->l2_offset * 512) 702 + (m_data->l2_index * sizeof(m_data->offset)), 703 &(m_data->offset), 704 sizeof(m_data->offset) 705 ) < 0) { 706 return -1; 707 } 708 /* update backup L2 table */ 709 if (extent->l1_backup_table_offset != 0) { 710 m_data->l2_offset = extent->l1_backup_table[m_data->l1_index]; 711 if (bdrv_pwrite_sync( 712 extent->file, 713 ((int64_t)m_data->l2_offset * 512) 714 + (m_data->l2_index * sizeof(m_data->offset)), 715 &(m_data->offset), sizeof(m_data->offset) 716 ) < 0) { 717 return -1; 718 } 719 } 720 721 return 0; 722 } 723 724 static int get_cluster_offset(BlockDriverState *bs, 725 VmdkExtent *extent, 726 VmdkMetaData *m_data, 727 uint64_t offset, 728 int allocate, 729 uint64_t *cluster_offset) 730 { 731 unsigned int l1_index, l2_offset, l2_index; 732 int min_index, i, j; 733 uint32_t min_count, *l2_table, tmp = 0; 734 735 if (m_data) { 736 m_data->valid = 0; 737 } 738 if (extent->flat) { 739 *cluster_offset = extent->flat_start_offset; 740 return 0; 741 } 742 743 offset -= (extent->end_sector - extent->sectors) * SECTOR_SIZE; 744 l1_index = (offset >> 9) / extent->l1_entry_sectors; 745 if (l1_index >= extent->l1_size) { 746 return -1; 747 } 748 l2_offset = extent->l1_table[l1_index]; 749 if (!l2_offset) { 750 return -1; 751 } 752 for (i = 0; i < L2_CACHE_SIZE; i++) { 753 if (l2_offset == extent->l2_cache_offsets[i]) { 754 /* increment the hit count */ 755 if (++extent->l2_cache_counts[i] == 0xffffffff) { 756 for (j = 0; j < L2_CACHE_SIZE; j++) { 757 extent->l2_cache_counts[j] >>= 1; 758 } 759 } 760 l2_table = extent->l2_cache + (i * extent->l2_size); 761 goto found; 762 } 763 } 764 /* not found: load a new entry in the least used one */ 765 min_index = 0; 766 min_count = 0xffffffff; 767 for (i = 0; i < L2_CACHE_SIZE; i++) { 768 if (extent->l2_cache_counts[i] < min_count) { 769 min_count = extent->l2_cache_counts[i]; 770 min_index = i; 771 } 772 } 773 l2_table = extent->l2_cache + (min_index * extent->l2_size); 774 if (bdrv_pread( 775 extent->file, 776 (int64_t)l2_offset * 512, 777 l2_table, 778 extent->l2_size * sizeof(uint32_t) 779 ) != extent->l2_size * sizeof(uint32_t)) { 780 return -1; 781 } 782 783 extent->l2_cache_offsets[min_index] = l2_offset; 784 extent->l2_cache_counts[min_index] = 1; 785 found: 786 l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size; 787 *cluster_offset = le32_to_cpu(l2_table[l2_index]); 788 789 if (!*cluster_offset) { 790 if (!allocate) { 791 return -1; 792 } 793 794 /* Avoid the L2 tables update for the images that have snapshots. */ 795 *cluster_offset = bdrv_getlength(extent->file); 796 if (!extent->compressed) { 797 bdrv_truncate( 798 extent->file, 799 *cluster_offset + (extent->cluster_sectors << 9) 800 ); 801 } 802 803 *cluster_offset >>= 9; 804 tmp = cpu_to_le32(*cluster_offset); 805 l2_table[l2_index] = tmp; 806 807 /* First of all we write grain itself, to avoid race condition 808 * that may to corrupt the image. 809 * This problem may occur because of insufficient space on host disk 810 * or inappropriate VM shutdown. 811 */ 812 if (get_whole_cluster( 813 bs, extent, *cluster_offset, offset, allocate) == -1) { 814 return -1; 815 } 816 817 if (m_data) { 818 m_data->offset = tmp; 819 m_data->l1_index = l1_index; 820 m_data->l2_index = l2_index; 821 m_data->l2_offset = l2_offset; 822 m_data->valid = 1; 823 } 824 } 825 *cluster_offset <<= 9; 826 return 0; 827 } 828 829 static VmdkExtent *find_extent(BDRVVmdkState *s, 830 int64_t sector_num, VmdkExtent *start_hint) 831 { 832 VmdkExtent *extent = start_hint; 833 834 if (!extent) { 835 extent = &s->extents[0]; 836 } 837 while (extent < &s->extents[s->num_extents]) { 838 if (sector_num < extent->end_sector) { 839 return extent; 840 } 841 extent++; 842 } 843 return NULL; 844 } 845 846 static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num, 847 int nb_sectors, int *pnum) 848 { 849 BDRVVmdkState *s = bs->opaque; 850 int64_t index_in_cluster, n, ret; 851 uint64_t offset; 852 VmdkExtent *extent; 853 854 extent = find_extent(s, sector_num, NULL); 855 if (!extent) { 856 return 0; 857 } 858 ret = get_cluster_offset(bs, extent, NULL, 859 sector_num * 512, 0, &offset); 860 /* get_cluster_offset returning 0 means success */ 861 ret = !ret; 862 863 index_in_cluster = sector_num % extent->cluster_sectors; 864 n = extent->cluster_sectors - index_in_cluster; 865 if (n > nb_sectors) { 866 n = nb_sectors; 867 } 868 *pnum = n; 869 return ret; 870 } 871 872 static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, 873 int64_t offset_in_cluster, const uint8_t *buf, 874 int nb_sectors, int64_t sector_num) 875 { 876 int ret; 877 VmdkGrainMarker *data = NULL; 878 uLongf buf_len; 879 const uint8_t *write_buf = buf; 880 int write_len = nb_sectors * 512; 881 882 if (extent->compressed) { 883 if (!extent->has_marker) { 884 ret = -EINVAL; 885 goto out; 886 } 887 buf_len = (extent->cluster_sectors << 9) * 2; 888 data = g_malloc(buf_len + sizeof(VmdkGrainMarker)); 889 if (compress(data->data, &buf_len, buf, nb_sectors << 9) != Z_OK || 890 buf_len == 0) { 891 ret = -EINVAL; 892 goto out; 893 } 894 data->lba = sector_num; 895 data->size = buf_len; 896 write_buf = (uint8_t *)data; 897 write_len = buf_len + sizeof(VmdkGrainMarker); 898 } 899 ret = bdrv_pwrite(extent->file, 900 cluster_offset + offset_in_cluster, 901 write_buf, 902 write_len); 903 if (ret != write_len) { 904 ret = ret < 0 ? ret : -EIO; 905 goto out; 906 } 907 ret = 0; 908 out: 909 g_free(data); 910 return ret; 911 } 912 913 static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, 914 int64_t offset_in_cluster, uint8_t *buf, 915 int nb_sectors) 916 { 917 int ret; 918 int cluster_bytes, buf_bytes; 919 uint8_t *cluster_buf, *compressed_data; 920 uint8_t *uncomp_buf; 921 uint32_t data_len; 922 VmdkGrainMarker *marker; 923 uLongf buf_len; 924 925 926 if (!extent->compressed) { 927 ret = bdrv_pread(extent->file, 928 cluster_offset + offset_in_cluster, 929 buf, nb_sectors * 512); 930 if (ret == nb_sectors * 512) { 931 return 0; 932 } else { 933 return -EIO; 934 } 935 } 936 cluster_bytes = extent->cluster_sectors * 512; 937 /* Read two clusters in case GrainMarker + compressed data > one cluster */ 938 buf_bytes = cluster_bytes * 2; 939 cluster_buf = g_malloc(buf_bytes); 940 uncomp_buf = g_malloc(cluster_bytes); 941 ret = bdrv_pread(extent->file, 942 cluster_offset, 943 cluster_buf, buf_bytes); 944 if (ret < 0) { 945 goto out; 946 } 947 compressed_data = cluster_buf; 948 buf_len = cluster_bytes; 949 data_len = cluster_bytes; 950 if (extent->has_marker) { 951 marker = (VmdkGrainMarker *)cluster_buf; 952 compressed_data = marker->data; 953 data_len = le32_to_cpu(marker->size); 954 } 955 if (!data_len || data_len > buf_bytes) { 956 ret = -EINVAL; 957 goto out; 958 } 959 ret = uncompress(uncomp_buf, &buf_len, compressed_data, data_len); 960 if (ret != Z_OK) { 961 ret = -EINVAL; 962 goto out; 963 964 } 965 if (offset_in_cluster < 0 || 966 offset_in_cluster + nb_sectors * 512 > buf_len) { 967 ret = -EINVAL; 968 goto out; 969 } 970 memcpy(buf, uncomp_buf + offset_in_cluster, nb_sectors * 512); 971 ret = 0; 972 973 out: 974 g_free(uncomp_buf); 975 g_free(cluster_buf); 976 return ret; 977 } 978 979 static int vmdk_read(BlockDriverState *bs, int64_t sector_num, 980 uint8_t *buf, int nb_sectors) 981 { 982 BDRVVmdkState *s = bs->opaque; 983 int ret; 984 uint64_t n, index_in_cluster; 985 VmdkExtent *extent = NULL; 986 uint64_t cluster_offset; 987 988 while (nb_sectors > 0) { 989 extent = find_extent(s, sector_num, extent); 990 if (!extent) { 991 return -EIO; 992 } 993 ret = get_cluster_offset( 994 bs, extent, NULL, 995 sector_num << 9, 0, &cluster_offset); 996 index_in_cluster = sector_num % extent->cluster_sectors; 997 n = extent->cluster_sectors - index_in_cluster; 998 if (n > nb_sectors) { 999 n = nb_sectors; 1000 } 1001 if (ret) { 1002 /* if not allocated, try to read from parent image, if exist */ 1003 if (bs->backing_hd) { 1004 if (!vmdk_is_cid_valid(bs)) { 1005 return -EINVAL; 1006 } 1007 ret = bdrv_read(bs->backing_hd, sector_num, buf, n); 1008 if (ret < 0) { 1009 return ret; 1010 } 1011 } else { 1012 memset(buf, 0, 512 * n); 1013 } 1014 } else { 1015 ret = vmdk_read_extent(extent, 1016 cluster_offset, index_in_cluster * 512, 1017 buf, n); 1018 if (ret) { 1019 return ret; 1020 } 1021 } 1022 nb_sectors -= n; 1023 sector_num += n; 1024 buf += n * 512; 1025 } 1026 return 0; 1027 } 1028 1029 static int vmdk_write(BlockDriverState *bs, int64_t sector_num, 1030 const uint8_t *buf, int nb_sectors) 1031 { 1032 BDRVVmdkState *s = bs->opaque; 1033 VmdkExtent *extent = NULL; 1034 int n, ret; 1035 int64_t index_in_cluster; 1036 uint64_t cluster_offset; 1037 VmdkMetaData m_data; 1038 1039 if (sector_num > bs->total_sectors) { 1040 fprintf(stderr, 1041 "(VMDK) Wrong offset: sector_num=0x%" PRIx64 1042 " total_sectors=0x%" PRIx64 "\n", 1043 sector_num, bs->total_sectors); 1044 return -EIO; 1045 } 1046 1047 while (nb_sectors > 0) { 1048 extent = find_extent(s, sector_num, extent); 1049 if (!extent) { 1050 return -EIO; 1051 } 1052 ret = get_cluster_offset( 1053 bs, 1054 extent, 1055 &m_data, 1056 sector_num << 9, !extent->compressed, 1057 &cluster_offset); 1058 if (extent->compressed) { 1059 if (ret == 0) { 1060 /* Refuse write to allocated cluster for streamOptimized */ 1061 fprintf(stderr, 1062 "VMDK: can't write to allocated cluster" 1063 " for streamOptimized\n"); 1064 return -EIO; 1065 } else { 1066 /* allocate */ 1067 ret = get_cluster_offset( 1068 bs, 1069 extent, 1070 &m_data, 1071 sector_num << 9, 1, 1072 &cluster_offset); 1073 } 1074 } 1075 if (ret) { 1076 return -EINVAL; 1077 } 1078 index_in_cluster = sector_num % extent->cluster_sectors; 1079 n = extent->cluster_sectors - index_in_cluster; 1080 if (n > nb_sectors) { 1081 n = nb_sectors; 1082 } 1083 1084 ret = vmdk_write_extent(extent, 1085 cluster_offset, index_in_cluster * 512, 1086 buf, n, sector_num); 1087 if (ret) { 1088 return ret; 1089 } 1090 if (m_data.valid) { 1091 /* update L2 tables */ 1092 if (vmdk_L2update(extent, &m_data) == -1) { 1093 return -EIO; 1094 } 1095 } 1096 nb_sectors -= n; 1097 sector_num += n; 1098 buf += n * 512; 1099 1100 /* update CID on the first write every time the virtual disk is 1101 * opened */ 1102 if (!s->cid_updated) { 1103 vmdk_write_cid(bs, time(NULL)); 1104 s->cid_updated = true; 1105 } 1106 } 1107 return 0; 1108 } 1109 1110 1111 static int vmdk_create_extent(const char *filename, int64_t filesize, 1112 bool flat, bool compress) 1113 { 1114 int ret, i; 1115 int fd = 0; 1116 VMDK4Header header; 1117 uint32_t tmp, magic, grains, gd_size, gt_size, gt_count; 1118 1119 fd = open( 1120 filename, 1121 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 1122 0644); 1123 if (fd < 0) { 1124 return -errno; 1125 } 1126 if (flat) { 1127 ret = ftruncate(fd, filesize); 1128 if (ret < 0) { 1129 ret = -errno; 1130 } 1131 goto exit; 1132 } 1133 magic = cpu_to_be32(VMDK4_MAGIC); 1134 memset(&header, 0, sizeof(header)); 1135 header.version = 1; 1136 header.flags = 1137 3 | (compress ? VMDK4_FLAG_COMPRESS | VMDK4_FLAG_MARKER : 0); 1138 header.compressAlgorithm = compress ? VMDK4_COMPRESSION_DEFLATE : 0; 1139 header.capacity = filesize / 512; 1140 header.granularity = 128; 1141 header.num_gtes_per_gte = 512; 1142 1143 grains = (filesize / 512 + header.granularity - 1) / header.granularity; 1144 gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9; 1145 gt_count = 1146 (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte; 1147 gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9; 1148 1149 header.desc_offset = 1; 1150 header.desc_size = 20; 1151 header.rgd_offset = header.desc_offset + header.desc_size; 1152 header.gd_offset = header.rgd_offset + gd_size + (gt_size * gt_count); 1153 header.grain_offset = 1154 ((header.gd_offset + gd_size + (gt_size * gt_count) + 1155 header.granularity - 1) / header.granularity) * 1156 header.granularity; 1157 /* swap endianness for all header fields */ 1158 header.version = cpu_to_le32(header.version); 1159 header.flags = cpu_to_le32(header.flags); 1160 header.capacity = cpu_to_le64(header.capacity); 1161 header.granularity = cpu_to_le64(header.granularity); 1162 header.num_gtes_per_gte = cpu_to_le32(header.num_gtes_per_gte); 1163 header.desc_offset = cpu_to_le64(header.desc_offset); 1164 header.desc_size = cpu_to_le64(header.desc_size); 1165 header.rgd_offset = cpu_to_le64(header.rgd_offset); 1166 header.gd_offset = cpu_to_le64(header.gd_offset); 1167 header.grain_offset = cpu_to_le64(header.grain_offset); 1168 header.compressAlgorithm = cpu_to_le16(header.compressAlgorithm); 1169 1170 header.check_bytes[0] = 0xa; 1171 header.check_bytes[1] = 0x20; 1172 header.check_bytes[2] = 0xd; 1173 header.check_bytes[3] = 0xa; 1174 1175 /* write all the data */ 1176 ret = qemu_write_full(fd, &magic, sizeof(magic)); 1177 if (ret != sizeof(magic)) { 1178 ret = -errno; 1179 goto exit; 1180 } 1181 ret = qemu_write_full(fd, &header, sizeof(header)); 1182 if (ret != sizeof(header)) { 1183 ret = -errno; 1184 goto exit; 1185 } 1186 1187 ret = ftruncate(fd, le64_to_cpu(header.grain_offset) << 9); 1188 if (ret < 0) { 1189 ret = -errno; 1190 goto exit; 1191 } 1192 1193 /* write grain directory */ 1194 lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET); 1195 for (i = 0, tmp = le64_to_cpu(header.rgd_offset) + gd_size; 1196 i < gt_count; i++, tmp += gt_size) { 1197 ret = qemu_write_full(fd, &tmp, sizeof(tmp)); 1198 if (ret != sizeof(tmp)) { 1199 ret = -errno; 1200 goto exit; 1201 } 1202 } 1203 1204 /* write backup grain directory */ 1205 lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET); 1206 for (i = 0, tmp = le64_to_cpu(header.gd_offset) + gd_size; 1207 i < gt_count; i++, tmp += gt_size) { 1208 ret = qemu_write_full(fd, &tmp, sizeof(tmp)); 1209 if (ret != sizeof(tmp)) { 1210 ret = -errno; 1211 goto exit; 1212 } 1213 } 1214 1215 ret = 0; 1216 exit: 1217 close(fd); 1218 return ret; 1219 } 1220 1221 static int filename_decompose(const char *filename, char *path, char *prefix, 1222 char *postfix, size_t buf_len) 1223 { 1224 const char *p, *q; 1225 1226 if (filename == NULL || !strlen(filename)) { 1227 fprintf(stderr, "Vmdk: no filename provided.\n"); 1228 return -1; 1229 } 1230 p = strrchr(filename, '/'); 1231 if (p == NULL) { 1232 p = strrchr(filename, '\\'); 1233 } 1234 if (p == NULL) { 1235 p = strrchr(filename, ':'); 1236 } 1237 if (p != NULL) { 1238 p++; 1239 if (p - filename >= buf_len) { 1240 return -1; 1241 } 1242 pstrcpy(path, p - filename + 1, filename); 1243 } else { 1244 p = filename; 1245 path[0] = '\0'; 1246 } 1247 q = strrchr(p, '.'); 1248 if (q == NULL) { 1249 pstrcpy(prefix, buf_len, p); 1250 postfix[0] = '\0'; 1251 } else { 1252 if (q - p >= buf_len) { 1253 return -1; 1254 } 1255 pstrcpy(prefix, q - p + 1, p); 1256 pstrcpy(postfix, buf_len, q); 1257 } 1258 return 0; 1259 } 1260 1261 static int relative_path(char *dest, int dest_size, 1262 const char *base, const char *target) 1263 { 1264 int i = 0; 1265 int n = 0; 1266 const char *p, *q; 1267 #ifdef _WIN32 1268 const char *sep = "\\"; 1269 #else 1270 const char *sep = "/"; 1271 #endif 1272 1273 if (!(dest && base && target)) { 1274 return -1; 1275 } 1276 if (path_is_absolute(target)) { 1277 dest[dest_size - 1] = '\0'; 1278 strncpy(dest, target, dest_size - 1); 1279 return 0; 1280 } 1281 while (base[i] == target[i]) { 1282 i++; 1283 } 1284 p = &base[i]; 1285 q = &target[i]; 1286 while (*p) { 1287 if (*p == *sep) { 1288 n++; 1289 } 1290 p++; 1291 } 1292 dest[0] = '\0'; 1293 for (; n; n--) { 1294 pstrcat(dest, dest_size, ".."); 1295 pstrcat(dest, dest_size, sep); 1296 } 1297 pstrcat(dest, dest_size, q); 1298 return 0; 1299 } 1300 1301 static int vmdk_create(const char *filename, QEMUOptionParameter *options) 1302 { 1303 int fd, idx = 0; 1304 char desc[BUF_SIZE]; 1305 int64_t total_size = 0, filesize; 1306 const char *backing_file = NULL; 1307 const char *fmt = NULL; 1308 int flags = 0; 1309 int ret = 0; 1310 bool flat, split, compress; 1311 char ext_desc_lines[BUF_SIZE] = ""; 1312 char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX]; 1313 const int64_t split_size = 0x80000000; /* VMDK has constant split size */ 1314 const char *desc_extent_line; 1315 char parent_desc_line[BUF_SIZE] = ""; 1316 uint32_t parent_cid = 0xffffffff; 1317 const char desc_template[] = 1318 "# Disk DescriptorFile\n" 1319 "version=1\n" 1320 "CID=%x\n" 1321 "parentCID=%x\n" 1322 "createType=\"%s\"\n" 1323 "%s" 1324 "\n" 1325 "# Extent description\n" 1326 "%s" 1327 "\n" 1328 "# The Disk Data Base\n" 1329 "#DDB\n" 1330 "\n" 1331 "ddb.virtualHWVersion = \"%d\"\n" 1332 "ddb.geometry.cylinders = \"%" PRId64 "\"\n" 1333 "ddb.geometry.heads = \"16\"\n" 1334 "ddb.geometry.sectors = \"63\"\n" 1335 "ddb.adapterType = \"ide\"\n"; 1336 1337 if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) { 1338 return -EINVAL; 1339 } 1340 /* Read out options */ 1341 while (options && options->name) { 1342 if (!strcmp(options->name, BLOCK_OPT_SIZE)) { 1343 total_size = options->value.n; 1344 } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { 1345 backing_file = options->value.s; 1346 } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) { 1347 flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0; 1348 } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) { 1349 fmt = options->value.s; 1350 } 1351 options++; 1352 } 1353 if (!fmt) { 1354 /* Default format to monolithicSparse */ 1355 fmt = "monolithicSparse"; 1356 } else if (strcmp(fmt, "monolithicFlat") && 1357 strcmp(fmt, "monolithicSparse") && 1358 strcmp(fmt, "twoGbMaxExtentSparse") && 1359 strcmp(fmt, "twoGbMaxExtentFlat") && 1360 strcmp(fmt, "streamOptimized")) { 1361 fprintf(stderr, "VMDK: Unknown subformat: %s\n", fmt); 1362 return -EINVAL; 1363 } 1364 split = !(strcmp(fmt, "twoGbMaxExtentFlat") && 1365 strcmp(fmt, "twoGbMaxExtentSparse")); 1366 flat = !(strcmp(fmt, "monolithicFlat") && 1367 strcmp(fmt, "twoGbMaxExtentFlat")); 1368 compress = !strcmp(fmt, "streamOptimized"); 1369 if (flat) { 1370 desc_extent_line = "RW %lld FLAT \"%s\" 0\n"; 1371 } else { 1372 desc_extent_line = "RW %lld SPARSE \"%s\"\n"; 1373 } 1374 if (flat && backing_file) { 1375 /* not supporting backing file for flat image */ 1376 return -ENOTSUP; 1377 } 1378 if (backing_file) { 1379 char parent_filename[PATH_MAX]; 1380 BlockDriverState *bs = bdrv_new(""); 1381 ret = bdrv_open(bs, backing_file, 0, NULL); 1382 if (ret != 0) { 1383 bdrv_delete(bs); 1384 return ret; 1385 } 1386 if (strcmp(bs->drv->format_name, "vmdk")) { 1387 bdrv_delete(bs); 1388 return -EINVAL; 1389 } 1390 filesize = bdrv_getlength(bs); 1391 parent_cid = vmdk_read_cid(bs, 0); 1392 bdrv_delete(bs); 1393 relative_path(parent_filename, sizeof(parent_filename), 1394 filename, backing_file); 1395 snprintf(parent_desc_line, sizeof(parent_desc_line), 1396 "parentFileNameHint=\"%s\"", parent_filename); 1397 } 1398 1399 /* Create extents */ 1400 filesize = total_size; 1401 while (filesize > 0) { 1402 char desc_line[BUF_SIZE]; 1403 char ext_filename[PATH_MAX]; 1404 char desc_filename[PATH_MAX]; 1405 int64_t size = filesize; 1406 1407 if (split && size > split_size) { 1408 size = split_size; 1409 } 1410 if (split) { 1411 snprintf(desc_filename, sizeof(desc_filename), "%s-%c%03d%s", 1412 prefix, flat ? 'f' : 's', ++idx, postfix); 1413 } else if (flat) { 1414 snprintf(desc_filename, sizeof(desc_filename), "%s-flat%s", 1415 prefix, postfix); 1416 } else { 1417 snprintf(desc_filename, sizeof(desc_filename), "%s%s", 1418 prefix, postfix); 1419 } 1420 snprintf(ext_filename, sizeof(ext_filename), "%s%s", 1421 path, desc_filename); 1422 1423 if (vmdk_create_extent(ext_filename, size, flat, compress)) { 1424 return -EINVAL; 1425 } 1426 filesize -= size; 1427 1428 /* Format description line */ 1429 snprintf(desc_line, sizeof(desc_line), 1430 desc_extent_line, size / 512, desc_filename); 1431 pstrcat(ext_desc_lines, sizeof(ext_desc_lines), desc_line); 1432 } 1433 /* generate descriptor file */ 1434 snprintf(desc, sizeof(desc), desc_template, 1435 (unsigned int)time(NULL), 1436 parent_cid, 1437 fmt, 1438 parent_desc_line, 1439 ext_desc_lines, 1440 (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4), 1441 total_size / (int64_t)(63 * 16 * 512)); 1442 if (split || flat) { 1443 fd = open( 1444 filename, 1445 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 1446 0644); 1447 } else { 1448 fd = open( 1449 filename, 1450 O_WRONLY | O_BINARY | O_LARGEFILE, 1451 0644); 1452 } 1453 if (fd < 0) { 1454 return -errno; 1455 } 1456 /* the descriptor offset = 0x200 */ 1457 if (!split && !flat && 0x200 != lseek(fd, 0x200, SEEK_SET)) { 1458 ret = -errno; 1459 goto exit; 1460 } 1461 ret = qemu_write_full(fd, desc, strlen(desc)); 1462 if (ret != strlen(desc)) { 1463 ret = -errno; 1464 goto exit; 1465 } 1466 ret = 0; 1467 exit: 1468 close(fd); 1469 return ret; 1470 } 1471 1472 static void vmdk_close(BlockDriverState *bs) 1473 { 1474 vmdk_free_extents(bs); 1475 } 1476 1477 static int vmdk_flush(BlockDriverState *bs) 1478 { 1479 int i, ret, err; 1480 BDRVVmdkState *s = bs->opaque; 1481 1482 ret = bdrv_flush(bs->file); 1483 for (i = 0; i < s->num_extents; i++) { 1484 err = bdrv_flush(s->extents[i].file); 1485 if (err < 0) { 1486 ret = err; 1487 } 1488 } 1489 return ret; 1490 } 1491 1492 static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs) 1493 { 1494 int i; 1495 int64_t ret = 0; 1496 int64_t r; 1497 BDRVVmdkState *s = bs->opaque; 1498 1499 ret = bdrv_get_allocated_file_size(bs->file); 1500 if (ret < 0) { 1501 return ret; 1502 } 1503 for (i = 0; i < s->num_extents; i++) { 1504 if (s->extents[i].file == bs->file) { 1505 continue; 1506 } 1507 r = bdrv_get_allocated_file_size(s->extents[i].file); 1508 if (r < 0) { 1509 return r; 1510 } 1511 ret += r; 1512 } 1513 return ret; 1514 } 1515 1516 static QEMUOptionParameter vmdk_create_options[] = { 1517 { 1518 .name = BLOCK_OPT_SIZE, 1519 .type = OPT_SIZE, 1520 .help = "Virtual disk size" 1521 }, 1522 { 1523 .name = BLOCK_OPT_BACKING_FILE, 1524 .type = OPT_STRING, 1525 .help = "File name of a base image" 1526 }, 1527 { 1528 .name = BLOCK_OPT_COMPAT6, 1529 .type = OPT_FLAG, 1530 .help = "VMDK version 6 image" 1531 }, 1532 { 1533 .name = BLOCK_OPT_SUBFMT, 1534 .type = OPT_STRING, 1535 .help = 1536 "VMDK flat extent format, can be one of " 1537 "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} " 1538 }, 1539 { NULL } 1540 }; 1541 1542 static BlockDriver bdrv_vmdk = { 1543 .format_name = "vmdk", 1544 .instance_size = sizeof(BDRVVmdkState), 1545 .bdrv_probe = vmdk_probe, 1546 .bdrv_open = vmdk_open, 1547 .bdrv_read = vmdk_read, 1548 .bdrv_write = vmdk_write, 1549 .bdrv_close = vmdk_close, 1550 .bdrv_create = vmdk_create, 1551 .bdrv_flush = vmdk_flush, 1552 .bdrv_is_allocated = vmdk_is_allocated, 1553 .bdrv_get_allocated_file_size = vmdk_get_allocated_file_size, 1554 1555 .create_options = vmdk_create_options, 1556 }; 1557 1558 static void bdrv_vmdk_init(void) 1559 { 1560 bdrv_register(&bdrv_vmdk); 1561 } 1562 1563 block_init(bdrv_vmdk_init); 1564