Changeset 63800 in vbox
- Timestamp:
- Sep 12, 2016 1:44:06 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/VMDK.cpp
r63799 r63800 154 154 155 155 156 #ifdef VBOX_WITH_VMDK_ESX157 158 /** @todo the ESX code is not tested, not used, and lacks error messages. */159 160 /**161 * Magic number for images created by VMware GSX Server 3 or ESX Server 3.162 */163 #define VMDK_ESX_SPARSE_MAGICNUMBER 0x44574f43 /* 'C' 'O' 'W' 'D' */164 165 #pragma pack(1)166 typedef struct COWDisk_Header167 {168 uint32_t magicNumber;169 uint32_t version;170 uint32_t flags;171 uint32_t numSectors;172 uint32_t grainSize;173 uint32_t gdOffset;174 uint32_t numGDEntries;175 uint32_t freeSector;176 /* The spec incompletely documents quite a few further fields, but states177 * that they are unused by the current format. Replace them by padding. */178 char reserved1[1604];179 uint32_t savedGeneration;180 char reserved2[8];181 uint32_t uncleanShutdown;182 char padding[396];183 } COWDisk_Header;184 #pragma pack()185 #endif /* VBOX_WITH_VMDK_ESX */186 187 188 156 /** Convert sector number/size to byte offset/size. */ 189 157 #define VMDK_SECTOR2BYTE(u) ((uint64_t)(u) << 9) … … 205 173 /** VMFS extent, used by ESX. */ 206 174 VMDKETYPE_VMFS 207 #ifdef VBOX_WITH_VMDK_ESX208 ,209 /** ESX sparse extent. */210 VMDKETYPE_ESX_SPARSE211 #endif /* VBOX_WITH_VMDK_ESX */212 175 } VMDKETYPE, *PVMDKETYPE; 213 176 … … 2170 2133 2171 2134 /* Type of the extent. */ 2172 #ifdef VBOX_WITH_VMDK_ESX2173 /** @todo Add the ESX extent types. Not necessary for now because2174 * the ESX extent types are only used inside an ESX server. They are2175 * automatically converted if the VMDK is exported. */2176 #endif /* VBOX_WITH_VMDK_ESX */2177 2135 if (!strncmp(pszLine, "SPARSE", 6)) 2178 2136 { … … 2833 2791 } 2834 2792 2835 #ifdef VBOX_WITH_VMDK_ESX2836 /**2837 * Internal: unused code to read the metadata of a sparse ESX extent.2838 *2839 * Such extents never leave ESX server, so this isn't ever used.2840 */2841 static int vmdkReadMetaESXSparseExtent(PVMDKEXTENT pExtent)2842 {2843 COWDisk_Header Header;2844 2845 int rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage, 0,2846 &Header, sizeof(Header));2847 if (RT_SUCCESS(rc))2848 {2849 if ( RT_LE2H_U32(Header.magicNumber) == VMDK_ESX_SPARSE_MAGICNUMBER2850 && RT_LE2H_U32(Header.version) == 12851 && RT_LE2H_U32(Header.flags) == 3)2852 {2853 pExtent->enmType = VMDKETYPE_ESX_SPARSE;2854 pExtent->cSectors = RT_LE2H_U32(Header.numSectors);2855 pExtent->cSectorsPerGrain = RT_LE2H_U32(Header.grainSize);2856 pExtent->uDescriptorSector = 0;2857 pExtent->cDescriptorSectors = 0;2858 pExtent->uSectorGD = RT_LE2H_U32(Header.gdOffset);2859 pExtent->uSectorRGD = 0;2860 pExtent->cOverheadSectors = 0;2861 pExtent->cGTEntries = 4096;2862 pExtent->cSectorsPerGDE = cSectorsPerGDE;2863 pExtent->cGDEntries = (pExtent->cSectors + cSectorsPerGDE - 1) / cSectorsPerGDE;2864 pExtent->uFreeSector = RT_LE2H_U32(Header.freeSector);2865 pExtent->fUncleanShutdown = !!Header.uncleanShutdown;2866 2867 uint64_t cSectorsPerGDE = pExtent->cGTEntries * pExtent->cSectorsPerGrain;2868 2869 /*2870 * The spec says that this must be between 1 sector and 1MB. This code2871 * assumes it's a power of two, so check that requirement, too.2872 *2873 * Check that the number of computed GD entries matches the2874 * stored value. Better be safe than sorry.2875 */2876 if ( (pExtent->cSectorsPerGrain & (pExtent->cSectorsPerGrain - 1))2877 || pExtent->cSectorsPerGrain == 02878 || pExtent->cSectorsPerGrain > 20482879 || !cSectorsPerGDE2880 || cSectorsPerGDE > UINT32_MAX)2881 || pExtent->cGDEntries != RT_LE2H_U32(Header.numGDEntries))2882 rc = VERR_VD_VMDK_INVALID_HEADER;2883 else2884 rc = vmdkReadGrainDirectory(pImage, pExtent);2885 }2886 else2887 rc = VERR_VD_VMDK_INVALID_HEADER;2888 }2889 else2890 {2891 vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error reading ESX sparse extent header in '%s'"), pExtent->pszFullname);2892 rc = VERR_VD_VMDK_INVALID_HEADER;2893 }2894 2895 if (RT_FAILURE(rc))2896 vmdkFreeExtentData(pImage, pExtent, false);2897 2898 return rc;2899 }2900 #endif /* VBOX_WITH_VMDK_ESX */2901 2902 2793 /** 2903 2794 * Internal: free the buffers used for streamOptimized images. … … 2972 2863 { 2973 2864 pExtent = &pImage->pExtents[i]; 2974 if ( pExtent->enmType == VMDKETYPE_HOSTED_SPARSE 2975 #ifdef VBOX_WITH_VMDK_ESX 2976 || pExtent->enmType == VMDKETYPE_ESX_SPARSE 2977 #endif /* VBOX_WITH_VMDK_ESX */ 2978 ) 2865 if (pExtent->enmType == VMDKETYPE_HOSTED_SPARSE) 2979 2866 { 2980 2867 /* Allocate grain table cache. */ … … 3361 3248 { 3362 3249 pExtent = &pImage->pExtents[i]; 3363 if ( pExtent->enmType == VMDKETYPE_HOSTED_SPARSE 3364 #ifdef VBOX_WITH_VMDK_ESX 3365 || pExtent->enmType == VMDKETYPE_ESX_SPARSE 3366 #endif /* VBOX_WITH_VMDK_ESX */ 3367 ) 3250 if (pExtent->enmType == VMDKETYPE_HOSTED_SPARSE) 3368 3251 { 3369 3252 /* Here used to be a check whether the nominal size of an extent … … 4254 4137 for (unsigned i = 0; i < pImage->cExtents; i++) 4255 4138 { 4256 if ( ( pImage->pExtents[i].enmType == VMDKETYPE_HOSTED_SPARSE 4257 #ifdef VBOX_WITH_VMDK_ESX 4258 || pImage->pExtents[i].enmType == VMDKETYPE_ESX_SPARSE 4259 #endif /* VBOX_WITH_VMDK_ESX */ 4260 ) 4139 if ( pImage->pExtents[i].enmType == VMDKETYPE_HOSTED_SPARSE 4261 4140 && pImage->pExtents[i].fUncleanShutdown) 4262 4141 { … … 4430 4309 } 4431 4310 break; 4432 #ifdef VBOX_WITH_VMDK_ESX4433 case VMDKETYPE_ESX_SPARSE:4434 /** @todo update the header. */4435 break;4436 #endif /* VBOX_WITH_VMDK_ESX */4437 4311 case VMDKETYPE_VMFS: 4438 4312 case VMDKETYPE_FLAT: … … 4449 4323 { 4450 4324 case VMDKETYPE_HOSTED_SPARSE: 4451 #ifdef VBOX_WITH_VMDK_ESX4452 case VMDKETYPE_ESX_SPARSE:4453 #endif /* VBOX_WITH_VMDK_ESX */4454 4325 case VMDKETYPE_VMFS: 4455 4326 case VMDKETYPE_FLAT: … … 4775 4646 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write updated backup grain table in '%s'"), pExtent->pszFullname); 4776 4647 } 4777 #ifdef VBOX_WITH_VMDK_ESX4778 if (RT_SUCCESS(rc) && pExtent->enmType == VMDKETYPE_ESX_SPARSE)4779 {4780 pExtent->uFreeSector = uGTSector + VMDK_BYTE2SECTOR(cbWrite);4781 pExtent->fMetaDirty = true;4782 }4783 #endif /* VBOX_WITH_VMDK_ESX */4784 4648 4785 4649 LogFlowFunc(("leaving rc=%Rrc\n", rc)); 4786 4787 4650 return rc; 4788 4651 } … … 5389 5252 || !VALID_PTR(pPCHSGeometry) 5390 5253 || !VALID_PTR(pLCHSGeometry) 5391 #ifndef VBOX_WITH_VMDK_ESX5392 || ( uImageFlags & VD_VMDK_IMAGE_FLAGS_ESX5393 && !(uImageFlags & VD_IMAGE_FLAGS_FIXED))5394 #endif5395 5254 || ( (uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED) 5396 5255 && (uImageFlags & ~(VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED | VD_IMAGE_FLAGS_DIFF)))) … … 5767 5626 { 5768 5627 case VMDKETYPE_HOSTED_SPARSE: 5769 #ifdef VBOX_WITH_VMDK_ESX5770 case VMDKETYPE_ESX_SPARSE:5771 #endif /* VBOX_WITH_VMDK_ESX */5772 5628 rc = vmdkGetSector(pImage, pIoCtx, pExtent, uSectorExtentRel, &uSectorExtentAbs); 5773 5629 if (RT_FAILURE(rc)) … … 5903 5759 { 5904 5760 case VMDKETYPE_HOSTED_SPARSE: 5905 #ifdef VBOX_WITH_VMDK_ESX5906 case VMDKETYPE_ESX_SPARSE:5907 #endif /* VBOX_WITH_VMDK_ESX */5908 5761 rc = vmdkGetSector(pImage, pIoCtx, pExtent, uSectorExtentRel, &uSectorExtentAbs); 5909 5762 if (RT_FAILURE(rc))
Note:
See TracChangeset
for help on using the changeset viewer.