Revision d1833ef5
b/block/vmdk.c | ||
---|---|---|
526 | 526 |
return ret; |
527 | 527 |
} |
528 | 528 |
|
529 |
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, |
|
530 |
uint64_t desc_offset, Error **errp);
|
|
529 |
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
|
|
530 |
Error **errp); |
|
531 | 531 |
|
532 | 532 |
static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset, |
533 | 533 |
Error **errp) |
... | ... | |
576 | 576 |
if (header.capacity == 0) { |
577 | 577 |
uint64_t desc_offset = le64_to_cpu(header.desc_offset); |
578 | 578 |
if (desc_offset) { |
579 |
return vmdk_open_desc_file(bs, flags, desc_offset << 9, errp); |
|
579 |
char *buf = vmdk_read_desc(file, desc_offset << 9, errp); |
|
580 |
if (!buf) { |
|
581 |
return -EINVAL; |
|
582 |
} |
|
583 |
ret = vmdk_open_desc_file(bs, flags, buf, errp); |
|
584 |
g_free(buf); |
|
585 |
return ret; |
|
580 | 586 |
} |
581 | 587 |
} |
582 | 588 |
|
... | ... | |
727 | 733 |
|
728 | 734 |
/* Open an extent file and append to bs array */ |
729 | 735 |
static int vmdk_open_sparse(BlockDriverState *bs, |
730 |
BlockDriverState *file, |
|
731 |
int flags, Error **errp)
|
|
736 |
BlockDriverState *file, int flags,
|
|
737 |
char *buf, Error **errp)
|
|
732 | 738 |
{ |
733 | 739 |
uint32_t magic; |
734 | 740 |
|
735 |
if (bdrv_pread(file, 0, &magic, sizeof(magic)) != sizeof(magic)) { |
|
736 |
return -EIO; |
|
737 |
} |
|
738 |
|
|
739 |
magic = be32_to_cpu(magic); |
|
741 |
magic = ldl_be_p(buf); |
|
740 | 742 |
switch (magic) { |
741 | 743 |
case VMDK3_MAGIC: |
742 | 744 |
return vmdk_open_vmfs_sparse(bs, file, flags, errp); |
... | ... | |
821 | 823 |
extent->flat_start_offset = flat_offset << 9; |
822 | 824 |
} else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) { |
823 | 825 |
/* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/ |
824 |
ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, errp); |
|
826 |
char *buf = vmdk_read_desc(extent_file, 0, errp); |
|
827 |
if (!buf) { |
|
828 |
ret = -EINVAL; |
|
829 |
} else { |
|
830 |
ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, buf, errp); |
|
831 |
} |
|
825 | 832 |
if (ret) { |
833 |
g_free(buf); |
|
826 | 834 |
bdrv_unref(extent_file); |
827 | 835 |
return ret; |
828 | 836 |
} |
... | ... | |
845 | 853 |
return 0; |
846 | 854 |
} |
847 | 855 |
|
848 |
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, |
|
849 |
uint64_t desc_offset, Error **errp)
|
|
856 |
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
|
|
857 |
Error **errp) |
|
850 | 858 |
{ |
851 | 859 |
int ret; |
852 |
char *buf; |
|
853 | 860 |
char ct[128]; |
854 | 861 |
BDRVVmdkState *s = bs->opaque; |
855 | 862 |
|
856 |
buf = vmdk_read_desc(bs->file, desc_offset, errp); |
|
857 |
if (!buf) { |
|
858 |
return -EINVAL; |
|
859 |
goto exit; |
|
860 |
} |
|
861 |
|
|
862 | 863 |
if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) { |
863 | 864 |
ret = -EMEDIUMTYPE; |
864 | 865 |
goto exit; |
... | ... | |
876 | 877 |
s->desc_offset = 0; |
877 | 878 |
ret = vmdk_parse_extents(buf, bs, bs->file->filename, errp); |
878 | 879 |
exit: |
879 |
g_free(buf); |
|
880 | 880 |
return ret; |
881 | 881 |
} |
882 | 882 |
|
883 | 883 |
static int vmdk_open(BlockDriverState *bs, QDict *options, int flags, |
884 | 884 |
Error **errp) |
885 | 885 |
{ |
886 |
char *buf = NULL; |
|
886 | 887 |
int ret; |
887 | 888 |
BDRVVmdkState *s = bs->opaque; |
888 | 889 |
|
889 |
if (vmdk_open_sparse(bs, bs->file, flags, errp) == 0) { |
|
890 |
buf = vmdk_read_desc(bs->file, 0, errp); |
|
891 |
if (!buf) { |
|
892 |
return -EINVAL; |
|
893 |
} |
|
894 |
|
|
895 |
if (vmdk_open_sparse(bs, bs->file, flags, buf, errp) == 0) { |
|
890 | 896 |
s->desc_offset = 0x200; |
891 | 897 |
} else { |
892 |
ret = vmdk_open_desc_file(bs, flags, 0, errp);
|
|
898 |
ret = vmdk_open_desc_file(bs, flags, buf, errp);
|
|
893 | 899 |
if (ret) { |
894 | 900 |
goto fail; |
895 | 901 |
} |
... | ... | |
908 | 914 |
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, |
909 | 915 |
"vmdk", bs->device_name, "live migration"); |
910 | 916 |
migrate_add_blocker(s->migration_blocker); |
911 |
|
|
917 |
g_free(buf); |
|
912 | 918 |
return 0; |
913 | 919 |
|
914 | 920 |
fail: |
921 |
g_free(buf); |
|
915 | 922 |
g_free(s->create_type); |
916 | 923 |
s->create_type = NULL; |
917 | 924 |
vmdk_free_extents(bs); |
Also available in: Unified diff