Changeset 4185 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Aug 16, 2007 10:44:44 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/SSM.cpp
r4071 r4185 91 91 /** The VM handle. */ 92 92 PVM pVM; 93 /** The size of the file header. 94 * Because the file header was incorrectly aligned there we've ended up with 95 * differences between the 64-bit and 32-bit file header. */ 96 size_t cbFileHdr; 93 97 /** The current operation. */ 94 98 SSMSTATE enmOp; … … 139 143 /** File checksum. The actual calculation skips past the u32CRC field. */ 140 144 uint32_t u32CRC; 145 /** Padding. */ 146 uint32_t u32Reserved; 141 147 /** The machine UUID. (Ignored if NIL.) */ 142 148 RTUUID MachineUuid; 143 149 } SSMFILEHDR, *PSSMFILEHDR; 150 AssertCompileSize(SSMFILEHDR, 64); 151 152 153 /** 154 * The x86 edition of the 1.0 header. 155 */ 156 #pragma pack(1) /* darn, MachineUuid got missaligned! */ 157 typedef struct SSMFILEHDRV10X86 158 { 159 /** Magic string which identifies this file as a version of VBox saved state file format. */ 160 char achMagic[32]; 161 /** The size of this file. Used to check 162 * whether the save completed and that things are fine otherwise. */ 163 uint64_t cbFile; 164 /** File checksum. The actual calculation skips past the u32CRC field. */ 165 uint32_t u32CRC; 166 /** The machine UUID. (Ignored if NIL.) */ 167 RTUUID MachineUuid; 168 } SSMFILEHDRV10X86, *PSSMFILEHDRV10X86; 169 #pragma pack() 170 171 /** 172 * The amd64 edition of the 1.0 header. 173 */ 174 typedef SSMFILEHDR SSMFILEHDRV10AMD64, *PSSMFILEHDRV10AMD64; 144 175 145 176 /** Saved state file magic base string. */ 146 177 #define SSMFILEHDR_MAGIC_BASE "\177VirtualBox SavedState " 147 178 /** Saved state file v1.0 magic. */ 148 #define SSMFILEHDR_MAGIC_V1 "\177VirtualBox SavedState V1.0\n" 179 #define SSMFILEHDR_MAGIC_V1_0 "\177VirtualBox SavedState V1.0\n" 180 /** Saved state file v1.1 magic. */ 181 #define SSMFILEHDR_MAGIC_V1_1 "\177VirtualBox SavedState V1.1\n" 149 182 150 183 … … 183 216 static int ssmr3CalcChecksum(RTFILE File, uint64_t cbFile, uint32_t *pu32CRC); 184 217 static void ssmR3Progress(PSSMHANDLE pSSM, uint64_t cbAdvance); 185 static int ssmr3Validate(RTFILE File, PSSMFILEHDR pHdr );218 static int ssmr3Validate(RTFILE File, PSSMFILEHDR pHdr, size_t *pcbFileHdr); 186 219 static PSSMUNIT ssmr3Find(PVM pVM, const char *pszName, uint32_t u32Instance); 187 220 static int ssmr3WriteFinish(PSSMHANDLE pSSM); … … 744 777 * Validate input. 745 778 */ 746 if (enmAfter != SSMAFTER_DESTROY && enmAfter != SSMAFTER_CONTINUE) 779 if ( enmAfter != SSMAFTER_DESTROY 780 && enmAfter != SSMAFTER_CONTINUE) 747 781 { 748 782 AssertMsgFailed(("Invalid enmAfter=%d!\n", enmAfter)); … … 756 790 Handle.enmAfter = enmAfter; 757 791 Handle.pVM = pVM; 792 Handle.cbFileHdr = sizeof(SSMFILEHDR); 758 793 Handle.pfnProgress = pfnProgress; 759 794 Handle.pvUser = pvUser; … … 778 813 * Write header. 779 814 */ 780 SSMFILEHDR Hdr = { SSMFILEHDR_MAGIC_V1 , 0, 0 };815 SSMFILEHDR Hdr = { SSMFILEHDR_MAGIC_V1_1, 0, 0, 0 }; 781 816 rc = RTFileWrite(Handle.File, &Hdr, sizeof(Hdr), NULL); 782 817 if (VBOX_SUCCESS(rc)) … … 1071 1106 * 1072 1107 * @returns VBox status. 1073 * @param File File to validate. 1074 * The file position is undefined on return. 1075 * @param pHdr Where to store the file header. 1076 */ 1077 static int ssmr3Validate(RTFILE File, PSSMFILEHDR pHdr) 1108 * @param File File to validate. 1109 * The file position is undefined on return. 1110 * @param pHdr Where to store the file header. 1111 * @param pcbFileHdr Where to store the file header size. 1112 */ 1113 static int ssmr3Validate(RTFILE File, PSSMFILEHDR pHdr, size_t *pcbFileHdr) 1078 1114 { 1079 1115 /* … … 1088 1124 1089 1125 /* 1090 * Verify the magic .1126 * Verify the magic and make adjustments for versions differences. 1091 1127 */ 1092 1128 if (memcmp(pHdr->achMagic, SSMFILEHDR_MAGIC_BASE, sizeof(SSMFILEHDR_MAGIC_BASE) - 1)) … … 1095 1131 return VERR_SSM_INTEGRITY_MAGIC; 1096 1132 } 1097 if (memcmp(pHdr->achMagic, SSMFILEHDR_MAGIC_V1, sizeof(SSMFILEHDR_MAGIC_V1))) 1133 1134 size_t offCrc32 = RT_OFFSETOF(SSMFILEHDR, u32CRC) + sizeof(pHdr->u32CRC); 1135 *pcbFileHdr = sizeof(*pHdr); 1136 if (!memcmp(pHdr->achMagic, SSMFILEHDR_MAGIC_V1_0, sizeof(SSMFILEHDR_MAGIC_V1_0))) 1137 { 1138 if (pHdr->MachineUuid.au32[3]) 1139 { 1140 SSMFILEHDRV10X86 OldHdr; 1141 memcpy(&OldHdr, pHdr, sizeof(OldHdr)); 1142 pHdr->cbFile = OldHdr.cbFile; 1143 pHdr->u32CRC = OldHdr.u32CRC; 1144 pHdr->u32Reserved = 0; 1145 pHdr->MachineUuid = OldHdr.MachineUuid; 1146 1147 offCrc32 = RT_OFFSETOF(SSMFILEHDRV10X86, u32CRC) + sizeof(pHdr->u32CRC); 1148 *pcbFileHdr = sizeof(OldHdr); 1149 } 1150 else 1151 { 1152 /* (It's identical, but this doesn't harm us and will continue working after future changes.) */ 1153 SSMFILEHDRV10AMD64 OldHdr; 1154 memcpy(&OldHdr, pHdr, sizeof(OldHdr)); 1155 pHdr->cbFile = OldHdr.cbFile; 1156 pHdr->u32CRC = OldHdr.u32CRC; 1157 pHdr->u32Reserved = 0; 1158 pHdr->MachineUuid = OldHdr.MachineUuid; 1159 1160 offCrc32 = RT_OFFSETOF(SSMFILEHDRV10AMD64, u32CRC) + sizeof(pHdr->u32CRC); 1161 *pcbFileHdr = sizeof(OldHdr); 1162 } 1163 } 1164 else if (memcmp(pHdr->achMagic, SSMFILEHDR_MAGIC_V1_1, sizeof(SSMFILEHDR_MAGIC_V1_1))) 1098 1165 { 1099 1166 Log(("SSM: Unknown file format version. magic=%.*s\n", sizeof(pHdr->achMagic) - 1, pHdr->achMagic)); … … 1120 1187 * Verify the checksum. 1121 1188 */ 1122 rc = RTFileSeek(File, RT_OFFSETOF(SSMFILEHDR, u32CRC) + sizeof(pHdr->u32CRC), RTFILE_SEEK_BEGIN, NULL);1189 rc = RTFileSeek(File, offCrc32, RTFILE_SEEK_BEGIN, NULL); 1123 1190 if (VBOX_FAILURE(rc)) 1124 1191 { … … 1127 1194 } 1128 1195 uint32_t u32CRC; 1129 rc = ssmr3CalcChecksum(File, pHdr->cbFile - sizeof(*pHdr), &u32CRC);1196 rc = ssmr3CalcChecksum(File, pHdr->cbFile - *pcbFileHdr, &u32CRC); 1130 1197 if (VBOX_FAILURE(rc)) 1131 1198 return rc; … … 1139 1206 * Verify Virtual Machine UUID. 1140 1207 */ 1141 RTUUID 1208 RTUUID Uuid; 1142 1209 memset(&Uuid, 0, sizeof(Uuid)); 1143 1210 /** @todo get machine uuids CFGGetUuid(, &Uuid); */ … … 1182 1249 * @param pVM The VM handle. 1183 1250 * @param pszFilename Name of the file to save the state in. 1184 * @param enmAfter What is planned after a successful save operation. 1251 * @param enmAfter What is planned after a successful load operation. 1252 * Only acceptable values are SSMAFTER_RESUME and SSMAFTER_DEBUG_IT. 1185 1253 * @param pfnProgress Progress callback. Optional. 1186 1254 * @param pvUser User argument for the progress callback. … … 1193 1261 * Validate input. 1194 1262 */ 1195 if (enmAfter != SSMAFTER_RESUME) 1263 if ( enmAfter != SSMAFTER_RESUME 1264 && enmAfter != SSMAFTER_DEBUG_IT) 1196 1265 { 1197 1266 AssertMsgFailed(("Invalid enmAfter=%d!\n", enmAfter)); … … 1205 1274 Handle.enmAfter = enmAfter; 1206 1275 Handle.pVM = pVM; 1276 Handle.cbFileHdr = sizeof(SSMFILEHDR); 1207 1277 Handle.pfnProgress = pfnProgress; 1208 1278 Handle.pvUser = pvUser; … … 1220 1290 */ 1221 1291 SSMFILEHDR Hdr; 1222 rc = ssmr3Validate(Handle.File, &Hdr );1292 rc = ssmr3Validate(Handle.File, &Hdr, &Handle.cbFileHdr); 1223 1293 if (VBOX_SUCCESS(rc)) 1224 1294 { … … 1285 1355 */ 1286 1356 if (VBOX_SUCCESS(rc)) 1287 rc = RTFileSeek(Handle.File, sizeof(Hdr), RTFILE_SEEK_BEGIN, NULL);1357 rc = RTFileSeek(Handle.File, Handle.cbFileHdr, RTFILE_SEEK_BEGIN, NULL); 1288 1358 if (VBOX_SUCCESS(rc)) 1289 1359 { … … 1396 1466 pUnit->fCalled = true; 1397 1467 if (VBOX_SUCCESS(rc)) 1468 rc = Handle.rc; 1469 if (VBOX_SUCCESS(rc)) 1398 1470 { 1399 1471 /* … … 1423 1495 else 1424 1496 { 1497 /* 1498 * We failed, but if loading for the debugger ignore certain failures 1499 * just to get it all loaded (big hack). 1500 */ 1425 1501 LogRel(("SSM: LoadExec failed with rc=%Vrc for unit '%s'!\n", rc, pszName)); 1426 break; 1502 if ( Handle.enmAfter != SSMAFTER_DEBUG_IT 1503 || rc != VERR_SSM_LOADED_TOO_MUCH) 1504 break; 1505 Handle.rc = rc = VINF_SUCCESS; 1506 ssmR3Progress(&Handle, Handle.offEstUnitEnd - Handle.offEst); 1427 1507 } 1428 1508 } … … 1436 1516 else 1437 1517 { 1518 /* 1519 * SSM unit wasn't found - ignore this when loading for the debugger. 1520 */ 1438 1521 LogRel(("SSM: Found no handler for unit '%s'!\n", pszName)); 1439 1522 rc = VERR_SSM_INTEGRITY_UNIT_NOT_FOUND; 1440 break; 1523 if (Handle.enmAfter != SSMAFTER_DEBUG_IT) 1524 break; 1525 rc = RTFileSeek(Handle.File, offUnit + UnitHdr.cbUnit, RTFILE_SEEK_BEGIN, NULL); 1441 1526 } 1442 1527 } … … 1560 1645 if (VBOX_SUCCESS(rc)) 1561 1646 { 1647 size_t cbFileHdr; 1562 1648 SSMFILEHDR Hdr; 1563 rc = ssmr3Validate(File, &Hdr );1649 rc = ssmr3Validate(File, &Hdr, &cbFileHdr); 1564 1650 RTFileClose(File); 1565 1651 } … … 1602 1688 { 1603 1689 SSMFILEHDR Hdr; 1604 rc = ssmr3Validate(pSSM->File, &Hdr); 1690 size_t cbFileHdr; 1691 rc = ssmr3Validate(pSSM->File, &Hdr, &cbFileHdr); 1605 1692 if (VBOX_SUCCESS(rc)) 1606 1693 { 1607 1694 //pSSM->pVM = NULL; 1695 pSSM->cbFileHdr = cbFileHdr; 1608 1696 pSSM->enmOp = SSMSTATE_OPEN_READ; 1609 1697 pSSM->enmAfter = SSMAFTER_OPENED; … … 1709 1797 size_t cchName = 0; 1710 1798 SSMFILEUNITHDR UnitHdr; 1711 for (RTFOFF off = sizeof(SSMFILEHDR); ; off += UnitHdr.cbUnit)1799 for (RTFOFF off = pSSM->cbFileHdr; ; off += UnitHdr.cbUnit) 1712 1800 { 1713 1801 /* … … 2388 2476 } 2389 2477 2390 AssertMsgFailed(("SSM: attempted reading more than the unit!\n")); 2478 /** @todo weed out lazy saving */ 2479 if (pSSM->enmAfter != SSMAFTER_DEBUG_IT) 2480 AssertMsgFailed(("SSM: attempted reading more than the unit!\n")); 2391 2481 return VERR_SSM_LOADED_TOO_MUCH; 2392 2482 } … … 2864 2954 * @param pSSM SSM operation handle. 2865 2955 */ 2866 SSMR3DECL( int) SSMR3HandleGetAfter(PSSMHANDLE pSSM)2956 SSMR3DECL(SSMAFTER) SSMR3HandleGetAfter(PSSMHANDLE pSSM) 2867 2957 { 2868 2958 return pSSM->enmAfter;
Note:
See TracChangeset
for help on using the changeset viewer.