Changeset 22915 in vbox
- Timestamp:
- Sep 10, 2009 1:43:25 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 52177
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/types.h
r22578 r22915 152 152 /** The VM is created. */ 153 153 VMSTATE_CREATED, 154 /** The VM state is being loaded from file. */ 155 VMSTATE_LOADING, 154 156 /** The VM is runnning. */ 155 157 VMSTATE_RUNNING, 156 /** The VM state is being loaded from file. */ 157 VMSTATE_LOADING, 158 /** Live save: The VM is running and the state is being saved. */ 159 VMSTATE_LS_RUNNING, 160 /** The VM is being reset. */ 161 VMSTATE_RESETTING, 162 /** Live save: The VM is being reset, suspended, and awaiting cancellation 163 * of the live save operation. */ 164 VMSTATE_LS_RESETTING, 165 /** The VM is suspended. */ 166 VMSTATE_SUSPENDED, 167 /** Live save: The VM has been suspended and is av 168 * the live save operation. */ 169 VMSTATE_LS_SUSPENDING, 170 /** The VM is suspended and its state is being saved by EMT(0). */ 171 VMSTATE_SAVING, 172 /** Live save: The VM is suspended and its state is being saved by EMT(0). */ 173 VMSTATE_LS_SAVING, 174 /** Live save: The VM is being powered off and the save cancelled. */ 175 VMSTATE_LS_POWERING_OFF, 176 /** The VM is suspended because of a fatal error. */ 177 VMSTATE_FATAL_ERROR, 178 /** Live save: Waiting for cancellation and transition to FatalError. */ 179 VMSTATE_LS_FATAL_ERROR, 180 /** The VM is in guru meditation over a fatal failure. */ 181 VMSTATE_GURU_MEDITATION, 182 /** Live save: Waiting for cancellation and transition to GuruMeditation. */ 183 VMSTATE_LS_GURU_MEDIATION, 158 184 /** The VM is screwed because of a failed state loading. */ 159 185 VMSTATE_LOAD_FAILURE, 160 /** The VM state is being saved to file. */161 VMSTATE_SAVING,162 /** The VM is suspended. */163 VMSTATE_SUSPENDED,164 /** The VM is being reset. */165 VMSTATE_RESETTING,166 /** The VM is in guru meditation over a fatal failure. */167 VMSTATE_GURU_MEDITATION,168 186 /** The VM is switched off, awaiting destruction. */ 169 187 VMSTATE_OFF, -
trunk/include/VBox/vmapi.h
r22890 r22915 352 352 VMMR3DECL(int) VMR3PowerOn(PVM pVM); 353 353 VMMR3DECL(int) VMR3Suspend(PVM pVM); 354 VMMR3DECL(int) VMR3SuspendNoSave(PVM pVM);355 354 VMMR3DECL(int) VMR3Resume(PVM pVM); 356 355 VMMR3DECL(int) VMR3Reset(PVM pVM); -
trunk/src/VBox/Main/ConsoleImpl.cpp
r22866 r22915 5798 5798 } 5799 5799 5800 case VMSTATE_ GURU_MEDITATION:5800 case VMSTATE_FATAL_ERROR: 5801 5801 { 5802 5802 AutoWriteLock alock(that); … … 5805 5805 break; 5806 5806 5807 /* Guru respects only running VMs */ 5807 /* Fatal errors are only for running VMs. */ 5808 Assert(Global::IsOnline(that->mMachineState)); 5809 5810 /* Note! 'Pause' is used here in want of something better. There 5811 * are currently only two places where fatal errors might be 5812 * raised, so it is not worth adding a new externally 5813 * visible state for this yet. */ 5814 that->setMachineState(MachineState_Paused); 5815 5816 break; 5817 } 5818 5819 case VMSTATE_GURU_MEDITATION: 5820 { 5821 AutoWriteLock alock(that); 5822 5823 if (that->mVMStateChangeCallbackDisabled) 5824 break; 5825 5826 /* Guru are only for running VMs */ 5808 5827 Assert (Global::IsOnline (that->mMachineState)); 5809 5828 -
trunk/src/VBox/VMM/VM.cpp
r22890 r22915 133 133 static DECLCALLBACK(size_t) vmR3LogPrefixCallback(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser); 134 134 static DECLCALLBACK(int) vmR3PowerOn(PVM pVM); 135 static DECLCALLBACK(int) vmR3Suspend(PVM pVM); 135 static int vmR3SuspendCommon(PVM pVM, bool fFatal); 136 static DECLCALLBACK(int) vmR3Suspend(PVM pVM, bool fFatal); 136 137 static DECLCALLBACK(int) vmR3Resume(PVM pVM); 137 static DECLCALLBACK(int) vmR3Save(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser );138 static DECLCALLBACK(int) vmR3Save(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser, PSSMHANDLE *ppSSM); 138 139 static DECLCALLBACK(int) vmR3Load(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser); 139 140 static DECLCALLBACK(int) vmR3PowerOff(PVM pVM); … … 1227 1228 1228 1229 /* 1229 * Validate input. 1230 */ 1231 if (!pVM) 1232 { 1233 AssertMsgFailed(("Invalid VM pointer\n")); 1234 return VERR_INVALID_PARAMETER; 1235 } 1236 1230 * Validate input and pass it on to the internal worker. 1231 */ 1232 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1233 int rc = vmR3SuspendCommon(pVM, false /*fFatal*/); 1234 1235 LogFlow(("VMR3Suspend: returns %Rrc\n", rc)); 1236 return rc; 1237 } 1238 1239 1240 /** 1241 * Common worker for VMR3Suspend and vmR3SetRuntimeErrorCommon. 1242 * 1243 * They both suspends the VM, but the latter ends up in the VMSTATE_FATAL_ERROR 1244 * instead of VMSTATE_SUSPENDED. 1245 * 1246 * @returns VBox status code. 1247 * @param pVM The VM handle. 1248 * @param fFatal Whether it's a fatal error or not. 1249 * 1250 * @thread Any thread. 1251 * @vmstate Running 1252 * @vmstateto Suspended, FatalError 1253 */ 1254 static int vmR3SuspendCommon(PVM pVM, bool fFatal) 1255 { 1237 1256 /* 1238 1257 * Request the operation in EMT. (in reverse order as VCPU 0 does the actual work) 1239 1258 */ 1240 1259 PVMREQ pReq = NULL; 1241 int rc = VMR3ReqCall(pVM, VMCPUID_ALL_REVERSE, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Suspend, 1, pVM); 1260 int rc = VMR3ReqCall(pVM, VMCPUID_ALL_REVERSE, &pReq, RT_INDEFINITE_WAIT, 1261 (PFNRT)vmR3Suspend, 2, pVM, fFatal); 1242 1262 if (RT_SUCCESS(rc)) 1243 1263 { … … 1248 1268 Assert(pReq == NULL); 1249 1269 1250 LogFlow(("VMR3Suspend: returns %Rrc\n", rc));1251 1270 return rc; 1252 1271 } … … 1254 1273 1255 1274 /** 1256 * Suspends a running VM and prevent state saving until the VM is resumed or stopped.1275 * Suspends a running VM. 1257 1276 * 1258 1277 * @returns 0 on success. 1259 1278 * @returns VBox error code on failure. 1260 1279 * @param pVM VM to suspend. 1261 * @thread Any thread. 1262 * @vmstate Running 1263 * @vmstateto Suspended 1264 */ 1265 VMMR3DECL(int) VMR3SuspendNoSave(PVM pVM) 1266 { 1267 pVM->vm.s.fPreventSaveState = true; 1268 return VMR3Suspend(pVM); 1269 } 1270 1271 1272 /** 1273 * Suspends a running VM. 1274 * 1275 * @returns 0 on success. 1276 * @returns VBox error code on failure. 1277 * @param pVM VM to suspend. 1280 * @param fFatal Whether it's a fatal error or normal suspend. 1278 1281 * @thread EMT 1279 1282 */ 1280 static DECLCALLBACK(int) vmR3Suspend(PVM pVM )1283 static DECLCALLBACK(int) vmR3Suspend(PVM pVM, bool fFatal) 1281 1284 { 1282 1285 LogFlow(("vmR3Suspend: pVM=%p\n", pVM)); … … 1299 1302 * Change the state, notify the components and resume the execution. 1300 1303 */ 1301 vmR3SetState(pVM, VMSTATE_SUSPENDED);1304 vmR3SetState(pVM, fFatal ? VMSTATE_FATAL_ERROR : VMSTATE_SUSPENDED); 1302 1305 PDMR3Suspend(pVM); 1303 1306 … … 1399 1402 * @param pVM VM which state should be saved. 1400 1403 * @param pszFilename Name of the save state file. 1401 * @param fContinueAfte wardsContinue execution afterwards. When in doubt,1404 * @param fContinueAfterwards Continue execution afterwards. When in doubt, 1402 1405 * set this to true. 1403 1406 * @param pfnProgress Progress callback. Optional. … … 1408 1411 * @vmstateto Suspended. 1409 1412 */ 1410 VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAfte wards, PFNVMPROGRESS pfnProgress, void *pvUser)1411 { 1412 LogFlow(("VMR3Save: pVM=%p pszFilename=%p:{%s} fContinueAfte wards=%RTbool pfnProgress=%p pvUser=%p\n",1413 pVM, pszFilename, pszFilename, fContinueAfte wards, pfnProgress, pvUser));1413 VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser) 1414 { 1415 LogFlow(("VMR3Save: pVM=%p pszFilename=%p:{%s} fContinueAfterwards=%RTbool pfnProgress=%p pvUser=%p\n", 1416 pVM, pszFilename, pszFilename, fContinueAfterwards, pfnProgress, pvUser)); 1414 1417 1415 1418 /* … … 1424 1427 * Request the operation in EMT(0). 1425 1428 */ 1426 SSMAFTER enmAfter = fContinueAftewards ? SSMAFTER_CONTINUE : SSMAFTER_DESTROY; 1427 PVMREQ pReq; 1429 SSMAFTER enmAfter = fContinueAfterwards ? SSMAFTER_CONTINUE : SSMAFTER_DESTROY; 1430 PSSMHANDLE pSSM; 1431 PVMREQ pReq; 1428 1432 int rc = VMR3ReqCall(pVM, 0 /* VCPU 0 */, &pReq, RT_INDEFINITE_WAIT, 1429 (PFNRT)vmR3Save, 5, pVM, pszFilename, enmAfter, pfnProgress, pvUser);1433 (PFNRT)vmR3Save, 6, pVM, pszFilename, enmAfter, pfnProgress, pvUser, &pSSM); 1430 1434 if (RT_SUCCESS(rc)) 1431 1435 { 1432 1436 rc = pReq->iStatus; 1433 1437 VMR3ReqFree(pReq); 1438 } 1439 if ( RT_SUCCESS(rc) 1440 && pSSM) 1441 { 1442 #if 1 1443 /**@todo*/ rc = VERR_NOT_IMPLEMENTED; 1444 #else 1445 /* 1446 * Live snapshot. 1447 */ 1448 rc = SSMR3LiveDoStep1(pSSM); 1449 if (RT_SUCCESS(rc)) 1450 { 1451 rc = VMR3ReqCall(pVM, 0 /* VCPU 0 */, &pReq, RT_INDEFINITE_WAIT, 1452 (PFNRT)vmR3SaveLive, 2, pVM, pSSM); 1453 if (RT_SUCCESS(rc)) 1454 { 1455 rc = pReq->iStatus; 1456 VMR3ReqFree(pReq); 1457 } 1458 } 1459 #endif 1434 1460 } 1435 1461 … … 1449 1475 * @param pfnProgress Progress callback. Optional. 1450 1476 * @param pvUser User argument for the progress callback. 1477 * @param ppSSM Where to return the saved state handle in case of a 1478 * live snapshot scenario. 1451 1479 * @thread EMT 1452 1480 */ 1453 static DECLCALLBACK(int) vmR3Save(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser )1454 { 1455 LogFlow(("vmR3Save: pVM=%p pszFilename=%p:{%s} enmAfter=%d pfnProgress=%p pvUser=%p \n", pVM, pszFilename, pszFilename, enmAfter, pfnProgress, pvUser));1481 static DECLCALLBACK(int) vmR3Save(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser, PSSMHANDLE *ppSSM) 1482 { 1483 LogFlow(("vmR3Save: pVM=%p pszFilename=%p:{%s} enmAfter=%d pfnProgress=%p pvUser=%p ppSSM=%p\n", pVM, pszFilename, pszFilename, enmAfter, pfnProgress, pvUser, ppSSM)); 1456 1484 1457 1485 /* … … 1459 1487 */ 1460 1488 /** @todo SMP: Check that vmR3SetState always done by EMT(0). If not add a vmR3TrySetState(). */ 1489 *ppSSM = NULL; 1461 1490 AssertMsgReturn( pVM->enmVMState == VMSTATE_SUSPENDED 1462 1491 || pVM->enmVMState == VMSTATE_RUNNING, … … 1472 1501 1473 1502 /* 1474 * Change the state and perform the save. 1475 */ 1476 bool fLive = pVM->enmVMState == VMSTATE_RUNNING; 1477 vmR3SetState(pVM, VMSTATE_SAVING); /** @todo Should probably use a different state for live snapshots and/or live migration. Will fix the state machine later. */ 1478 int rc = SSMR3Save(pVM, pszFilename, enmAfter, pfnProgress, pvUser); 1479 vmR3SetState(pVM, VMSTATE_SUSPENDED); 1503 * Change the state and perform/start the saveing. 1504 */ 1505 int rc; 1506 if (pVM->enmVMState == VMSTATE_RUNNING) 1507 { 1508 /** @todo state mess. */ 1509 rc = SSMR3LiveToFile(pVM, pszFilename, enmAfter, pfnProgress, pvUser, ppSSM); 1510 } 1511 else 1512 { 1513 vmR3SetState(pVM, VMSTATE_SAVING); /** @todo Should probably use a different state for live snapshots and/or live migration. Will fix the state machine later. */ 1514 rc = SSMR3Save(pVM, pszFilename, enmAfter, pfnProgress, pvUser); 1515 vmR3SetState(pVM, VMSTATE_SUSPENDED); 1516 } 1480 1517 1481 1518 return rc; … … 1642 1679 && pVM->enmVMState != VMSTATE_SUSPENDED 1643 1680 && pVM->enmVMState != VMSTATE_LOAD_FAILURE 1681 && pVM->enmVMState != VMSTATE_FATAL_ERROR 1644 1682 && pVM->enmVMState != VMSTATE_GURU_MEDITATION) 1645 1683 { … … 2704 2742 case VMSTATE_CREATING: return "CREATING"; 2705 2743 case VMSTATE_CREATED: return "CREATED"; 2744 case VMSTATE_LOADING: return "LOADING"; 2706 2745 case VMSTATE_RUNNING: return "RUNNING"; 2707 case VMSTATE_LOADING: return "LOADING"; 2746 case VMSTATE_LS_RUNNING: return "LS_RUNNING"; 2747 case VMSTATE_RESETTING: return "RESETTING"; 2748 case VMSTATE_LS_RESETTING: return "LS_RESETTING"; 2749 case VMSTATE_SUSPENDED: return "SUSPENDED"; 2750 case VMSTATE_LS_SUSPENDING: return "LS_SUSPENDING"; 2751 case VMSTATE_SAVING: return "SAVING"; 2752 case VMSTATE_LS_SAVING: return "LS_SAVING"; 2753 case VMSTATE_LS_POWERING_OFF: return "LS_POWERING_OFF"; 2754 case VMSTATE_FATAL_ERROR: return "FATAL_ERROR"; 2755 case VMSTATE_LS_FATAL_ERROR: return "LS_FATAL_ERROR"; 2756 case VMSTATE_GURU_MEDITATION: return "GURU_MEDITATION"; 2757 case VMSTATE_LS_GURU_MEDIATION: return "LS_GURU_MEDIATION"; 2708 2758 case VMSTATE_LOAD_FAILURE: return "LOAD_FAILURE"; 2709 case VMSTATE_SAVING: return "SAVING";2710 case VMSTATE_SUSPENDED: return "SUSPENDED";2711 case VMSTATE_RESETTING: return "RESETTING";2712 case VMSTATE_GURU_MEDITATION: return "GURU_MEDITATION";2713 2759 case VMSTATE_OFF: return "OFF"; 2714 2760 case VMSTATE_DESTROYING: return "DESTROYING"; 2715 2761 case VMSTATE_TERMINATED: return "TERMINATED"; 2762 2716 2763 default: 2717 2764 AssertMsgFailed(("Unknown state %d\n", enmState)); … … 2730 2777 void vmR3SetState(PVM pVM, VMSTATE enmStateNew) 2731 2778 { 2779 #ifdef DEBUG_bird /** @todo remove when sorted out. */ 2780 VM_ASSERT_EMT0(pVM); 2781 #endif 2782 2732 2783 /* 2733 2784 * Validate state machine transitions before doing the actual change. … … 3411 3462 int rc = VINF_SUCCESS; 3412 3463 if (fFlags & VMSETRTERR_FLAGS_FATAL) 3413 /** @todo Add some special VM state for the FATAL variant that isn't resumable. 3414 * It's too risky for 2.2.0, do after branching. */ 3415 rc = VMR3SuspendNoSave(pVM); 3464 rc = vmR3SuspendCommon(pVM, true /*fFatal*/); 3416 3465 else if (fFlags & VMSETRTERR_FLAGS_SUSPEND) 3417 3466 rc = VMR3Suspend(pVM); … … 3492 3541 * @param fFlags The error flags. 3493 3542 * @param pszErrorId Error ID string. 3494 * @param pszFormat Format string. 3495 * @param pVa Pointer to the format arguments. 3543 * @param pszMessage The error message residing the MM heap. 3496 3544 * 3497 3545 * @thread EMT 3498 3546 */ 3499 DECLCALLBACK(int) vmR3SetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list *pVa) 3500 { 3547 DECLCALLBACK(int) vmR3SetRuntimeError(PVM pVM, uint32_t fFlags, const char *pszErrorId, char *pszMessage) 3548 { 3549 #if 0 /** @todo make copy of the error msg. */ 3501 3550 /* 3502 3551 * Make a copy of the message. … … 3506 3555 vmSetRuntimeErrorCopy(pVM, fFlags, pszErrorId, pszFormat, va2); 3507 3556 va_end(va2); 3557 #endif 3558 3559 /* 3560 * Join paths with VMR3SetRuntimeErrorWorker. 3561 */ 3562 int rc = vmR3SetRuntimeErrorCommonF(pVM, fFlags, pszErrorId, "%s", pszMessage); 3563 MMR3HeapFree(pszMessage); 3564 return rc; 3565 } 3566 3567 3568 /** 3569 * Worker for VMSetRuntimeErrorV for doing the job on EMT in ring-3. 3570 * 3571 * @returns VBox status code with modifications, see VMSetRuntimeErrorV. 3572 * 3573 * @param pVM The VM handle. 3574 * @param fFlags The error flags. 3575 * @param pszErrorId Error ID string. 3576 * @param pszFormat Format string. 3577 * @param pVa Pointer to the format arguments. 3578 * 3579 * @thread EMT 3580 */ 3581 DECLCALLBACK(int) vmR3SetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list *pVa) 3582 { 3583 /* 3584 * Make a copy of the message. 3585 */ 3586 va_list va2; 3587 va_copy(va2, *pVa); 3588 vmSetRuntimeErrorCopy(pVM, fFlags, pszErrorId, pszFormat, va2); 3589 va_end(va2); 3508 3590 3509 3591 /* -
trunk/src/VBox/VMM/VMInternal.h
r20374 r22915 461 461 DECLCALLBACK(void) vmR3SetErrorUV(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list *args); 462 462 void vmSetErrorCopy(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args); 463 DECLCALLBACK(int) vmR3SetRuntimeError(PVM pVM, uint32_t fFlags, const char *pszErrorId, char *pszMessage); 463 464 DECLCALLBACK(int) vmR3SetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list *pVa); 464 465 void vmSetRuntimeErrorCopy(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va); -
trunk/src/VBox/VMM/VMMAll/VMAll.cpp
r20874 r22915 255 255 /* 256 256 * Switch to EMT. 257 */ 258 va_list va2; 259 va_copy(va2, va); /* Have to make a copy here or GCC will break. */ 257 * 258 * If it's a no-wait request, we have to format the message into a buffer 259 * here since the variable arguments list will become invalid once we call 260 * va_end and return. 261 */ 260 262 int rc; 261 263 PVMREQ pReq; … … 263 265 || VM_IS_EMT(pVM)) 264 266 { 267 fFlags &= ~VMSETRTERR_FLAGS_NO_WAIT; 268 269 va_list va2; 270 va_copy(va2, va); /* Have to make a copy here or GCC will break. */ 265 271 rc = VMR3ReqCallU(pVM->pUVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, VMREQFLAGS_VBOX_STATUS, 266 272 (PFNRT)vmR3SetRuntimeErrorV, 5, pVM, fFlags, pszErrorId, pszFormat, &va2); 273 va_end(va2); 267 274 if (RT_SUCCESS(rc)) 268 275 rc = pReq->iStatus; 269 276 } 270 277 else 278 { 279 char *pszMessage = MMR3HeapAPrintfV(pVM, MM_TAG_VM, pszFormat, va); 280 271 281 rc = VMR3ReqCallU(pVM->pUVM, VMCPUID_ANY, &pReq, 0, VMREQFLAGS_VBOX_STATUS | VMREQFLAGS_NO_WAIT, 272 (PFNRT)vmR3SetRuntimeErrorV, 5, pVM, fFlags, pszErrorId, pszFormat, &va2); 282 (PFNRT)vmR3SetRuntimeError, 4, pVM, fFlags, pszErrorId, pszMessage); 283 if (RT_FAILURE(rc)) 284 MMR3HeapFree(pszMessage); 285 } 273 286 VMR3ReqFree(pReq); 274 va_end(va2);275 287 276 288 #else
Note:
See TracChangeset
for help on using the changeset viewer.