Revision 5fafdf24 block-vmdk.c
b/block-vmdk.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* Block driver for the VMDK format |
3 |
*
|
|
3 |
* |
|
4 | 4 |
* Copyright (c) 2004 Fabrice Bellard |
5 | 5 |
* Copyright (c) 2005 Filip Navara |
6 |
*
|
|
6 |
* |
|
7 | 7 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
8 | 8 |
* of this software and associated documentation files (the "Software"), to deal |
9 | 9 |
* in the Software without restriction, including without limitation the rights |
... | ... | |
110 | 110 |
|
111 | 111 |
#define CHECK_CID 1 |
112 | 112 |
|
113 |
#define SECTOR_SIZE 512
|
|
113 |
#define SECTOR_SIZE 512 |
|
114 | 114 |
#define DESC_SIZE 20*SECTOR_SIZE // 20 sectors of 512 bytes each |
115 |
#define HEADER_SIZE 512 // first sector of 512 bytes
|
|
115 |
#define HEADER_SIZE 512 // first sector of 512 bytes |
|
116 | 116 |
|
117 | 117 |
static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent) |
118 | 118 |
{ |
119 | 119 |
BDRVVmdkState *s = bs->opaque; |
120 | 120 |
char desc[DESC_SIZE]; |
121 | 121 |
uint32_t cid; |
122 |
char *p_name, *cid_str;
|
|
122 |
char *p_name, *cid_str; |
|
123 | 123 |
size_t cid_str_size; |
124 | 124 |
|
125 | 125 |
/* the descriptor offset = 0x200 */ |
... | ... | |
187 | 187 |
{ |
188 | 188 |
int snp_fd, p_fd; |
189 | 189 |
uint32_t p_cid; |
190 |
char *p_name, *gd_buf, *rgd_buf;
|
|
190 |
char *p_name, *gd_buf, *rgd_buf; |
|
191 | 191 |
const char *real_filename, *temp_str; |
192 | 192 |
VMDK4Header header; |
193 | 193 |
uint32_t gde_entries, gd_size; |
... | ... | |
271 | 271 |
gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE; |
272 | 272 |
if (!gt_size) |
273 | 273 |
goto fail; |
274 |
gde_entries = (uint32_t)(capacity / gt_size); // number of gde/rgde
|
|
274 |
gde_entries = (uint32_t)(capacity / gt_size); // number of gde/rgde |
|
275 | 275 |
gd_size = gde_entries * sizeof(uint32_t); |
276 | 276 |
|
277 | 277 |
/* write RGD */ |
... | ... | |
308 | 308 |
|
309 | 309 |
fail_gd: |
310 | 310 |
qemu_free(gd_buf); |
311 |
fail_rgd:
|
|
311 |
fail_rgd: |
|
312 | 312 |
qemu_free(rgd_buf); |
313 | 313 |
fail: |
314 | 314 |
close(p_fd); |
... | ... | |
326 | 326 |
static int vmdk_parent_open(BlockDriverState *bs, const char * filename) |
327 | 327 |
{ |
328 | 328 |
BDRVVmdkState *s = bs->opaque; |
329 |
char *p_name;
|
|
329 |
char *p_name; |
|
330 | 330 |
char desc[DESC_SIZE]; |
331 | 331 |
char parent_img_name[1024]; |
332 | 332 |
|
... | ... | |
341 | 341 |
p_name += sizeof("parentFileNameHint") + 1; |
342 | 342 |
if ((end_name = strchr(p_name,'\"')) == 0) |
343 | 343 |
return -1; |
344 |
|
|
344 |
|
|
345 | 345 |
strncpy(s->hd->backing_file, p_name, end_name - p_name); |
346 | 346 |
if (stat(s->hd->backing_file, &file_buf) != 0) { |
347 | 347 |
path_combine(parent_img_name, sizeof(parent_img_name), |
... | ... | |
406 | 406 |
s->l1_entry_sectors = s->l2_size * s->cluster_sectors; |
407 | 407 |
if (s->l1_entry_sectors <= 0) |
408 | 408 |
goto fail; |
409 |
s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
|
|
409 |
s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1) |
|
410 | 410 |
/ s->l1_entry_sectors; |
411 | 411 |
s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9; |
412 | 412 |
s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9; |
... | ... | |
552 | 552 |
} |
553 | 553 |
} |
554 | 554 |
l2_table = s->l2_cache + (min_index * s->l2_size); |
555 |
if (bdrv_pread(s->hd, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) !=
|
|
555 |
if (bdrv_pread(s->hd, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) != |
|
556 | 556 |
s->l2_size * sizeof(uint32_t)) |
557 | 557 |
return 0; |
558 | 558 |
|
... | ... | |
597 | 597 |
return cluster_offset; |
598 | 598 |
} |
599 | 599 |
|
600 |
static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
|
|
600 |
static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num, |
|
601 | 601 |
int nb_sectors, int *pnum) |
602 | 602 |
{ |
603 | 603 |
BDRVVmdkState *s = bs->opaque; |
... | ... | |
613 | 613 |
return (cluster_offset != 0); |
614 | 614 |
} |
615 | 615 |
|
616 |
static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
|
|
616 |
static int vmdk_read(BlockDriverState *bs, int64_t sector_num, |
|
617 | 617 |
uint8_t *buf, int nb_sectors) |
618 | 618 |
{ |
619 | 619 |
BDRVVmdkState *s = bs->opaque; |
... | ... | |
648 | 648 |
return 0; |
649 | 649 |
} |
650 | 650 |
|
651 |
static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
|
|
651 |
static int vmdk_write(BlockDriverState *bs, int64_t sector_num, |
|
652 | 652 |
const uint8_t *buf, int nb_sectors) |
653 | 653 |
{ |
654 | 654 |
BDRVVmdkState *s = bs->opaque; |
... | ... | |
761 | 761 |
header.check_bytes[1] = 0x20; |
762 | 762 |
header.check_bytes[2] = 0xd; |
763 | 763 |
header.check_bytes[3] = 0xa; |
764 |
|
|
765 |
/* write all the data */
|
|
764 |
|
|
765 |
/* write all the data */ |
|
766 | 766 |
write(fd, &magic, sizeof(magic)); |
767 | 767 |
write(fd, &header, sizeof(header)); |
768 | 768 |
|
... | ... | |
773 | 773 |
for (i = 0, tmp = header.rgd_offset + gd_size; |
774 | 774 |
i < gt_count; i++, tmp += gt_size) |
775 | 775 |
write(fd, &tmp, sizeof(tmp)); |
776 |
|
|
776 |
|
|
777 | 777 |
/* write backup grain directory */ |
778 | 778 |
lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET); |
779 | 779 |
for (i = 0, tmp = header.gd_offset + gd_size; |
Also available in: Unified diff