- Timestamp:
- Sep 15, 2009 8:00:08 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VM.cpp
r23024 r23037 1428 1428 1429 1429 /** 1430 * Worker for VMR3Save to clean up a SSMR3LiveDoStep1 failure. 1431 * 1432 * We failed after hitting the RunningLS state, but before trying to suspend the 1433 * VM before vmR3SaveLiveStep2. There are a number of state transisions in this 1434 * state, some, like ResetLS, that requires some special handling. (ResetLS is 1435 * the excuse for doing this all on EMT(0). 1436 * 1437 * @returns VBox status code. 1438 * 1439 * @param pVM The VM handle. 1440 * @param pSSM The handle of saved state operation. This will be 1441 * closed. 1442 * @thread EMT(0) 1443 */ 1444 static DECLCALLBACK(int) vmR3SaveLiveStep1Cleanup(PVM pVM, PSSMHANDLE pSSM) 1445 { 1446 LogFlow(("vmR3SaveLiveStep2: pVM=%p pSSM=%p\n", pVM, pSSM)); 1447 VM_ASSERT_EMT0(pVM); 1448 1449 /* 1450 * Finish the SSM state first (or move the ssmR3SetCancellable call), 1451 * then change the state out of the *LS variants. 1452 */ 1453 int rc = SSMR3LiveDone(pSSM); 1454 int rc2 = vmR3TrySetState(pVM, "vmR3SaveLiveStep1Cleanup", 8, 1455 VMSTATE_RUNNING, VMSTATE_RUNNING_LS, 1456 VMSTATE_RUNNING, VMSTATE_RESET_LS, 1457 VMSTATE_SUSPENDING, VMSTATE_SUSPENDING_LS, /* external*/ 1458 VMSTATE_GURU_MEDITATION, VMSTATE_GURU_MEDITATION_LS, 1459 VMSTATE_FATAL_ERROR, VMSTATE_FATAL_ERROR_LS, 1460 VMSTATE_POWERING_OFF, VMSTATE_POWERING_OFF_LS, 1461 VMSTATE_OFF, VMSTATE_OFF_LS, 1462 VMSTATE_DEBUGGING, VMSTATE_DEBUGGING_LS); 1463 if (RT_SUCCESS(rc)) 1464 { 1465 if (RT_SUCCESS(rc2)) 1466 rc = rc2 == 2 /* ResetLS -> Running */ ? VINF_EM_RESUME : VINF_SUCCESS; 1467 else 1468 rc = rc2; 1469 } 1470 return rc; 1471 } 1472 1473 1474 /** 1430 1475 * Worker for VMR3Save continues a live save on EMT(0). 1431 1476 * … … 1440 1485 LogFlow(("vmR3SaveLiveStep2: pVM=%p pSSM=%p\n", pVM, pSSM)); 1441 1486 VM_ASSERT_EMT0(pVM); 1442 Assert(VMR3GetState(pVM) == VMSTATE_SUSPENDED_LS); 1443 1444 int rc = SSMR3LiveDoStep2(pSSM); 1445 vmR3SetState(pVM, VMSTATE_SUSPENDED, VMSTATE_SUSPENDED_LS); 1487 1488 vmR3SetState(pVM, VMSTATE_SAVING, VMSTATE_SUSPENDED_LS); 1489 1490 int rc = SSMR3LiveDoStep2(pSSM); 1491 int rc2 = SSMR3LiveDone(pSSM); 1492 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 1493 rc = rc2; 1494 1495 vmR3SetState(pVM, VMSTATE_SUSPENDED, VMSTATE_SAVING); 1446 1496 1447 1497 return rc; 1448 1498 } 1499 1449 1500 1450 1501 … … 1498 1549 && pSSM) 1499 1550 { 1500 #if 0 /** @todo later*/1501 1551 /* 1502 1552 * Live snapshot. 1553 * 1554 * The state handling here is kind of tricky, doing it on EMT(0) 1555 * helps abit. See the VMSTATE diagram for details. The EMT(0) calls 1556 * consumes the pSSM handle and calls SSMR3LiveDone. 1503 1557 */ 1504 1558 rc = SSMR3LiveDoStep1(pSSM); 1505 1559 if (RT_SUCCESS(rc)) 1506 { 1507 rc = vmR3SuspendCommon(pVM, false /*fFatal*/); 1508 if (RT_SUCCESS(rc)) 1509 rc = VMR3ReqCallWaitU(pVM->pUVM, 0 /*idDstCpu*/, (PFNRT)vmR3SaveLiveStep2, 2, pVM, pSSM); 1510 } 1511 else 1512 AssertLogRelMsg( pVM->enmVMState == VMSTATE_RUNNING_LS 1513 || pVM->enmVMState == VMSTATE_RESETTING_LS 1514 || pVM->enmVMState == VMSTATE_POWERING_OFF_LS 1515 || pVM->enmVMState == VMSTATE_FATAL_ERROR_LS 1516 || pVM->enmVMState == VMSTATE_GURU_MEDITATION_LS, 1517 ("%s rc=%Rrc\n", pVM->enmVMState, rc)); 1518 1519 int rc2 = SSMR3LiveDone(pSSM); 1520 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 1521 rc = rc2; 1522 1523 /* 1524 * Work the state. 1525 */ 1526 if (pVM->enmVMState == VMSTATE_SUSPENDED) 1527 Log(("VMR3Save: Suspended; rc=%Rrc\n", rc)); 1528 else if (vmR3TrySetState(pVM, VMSTATE_RUNNING, VMSTATE_RUNNING_LS)) 1529 Log(("VMR3Save: Cancelled while running; rc=%Rrc\n", rc)); 1530 else if (vmR3TrySetState(pVM, VMSTATE_SUSPEND, VMSTATE_SUSPEND_LS)) 1531 Log(("VMR3Save: Cancelled while suspended; rc=%Rrc\n", rc)); 1532 else if (vmR3TrySetState(pVM, VMSTATE_POWERING_OFF, VMSTATE_POWERING_OFF_LS)) 1533 { 1534 /** @todo needs more work. */ 1535 Log(("VMR3Save: Powering off; rc=%Rrc\n", rc)); 1536 } 1537 else if (vmR3TrySetState(pVM, VMSTATE_RESETTING, VMSTATE_RESETTING_LS)) 1538 { 1539 /** @todo needs more work. */ 1540 Log(("VMR3Save: Resetting; rc=%Rrc\n", rc)); 1541 } 1542 else if (vmR3TrySetState(pVM, VMSTATE_FATAL_ERROR, VMSTATE_FATAL_ERROR_LS)) 1543 Log(("VMR3Save: Fatal error; rc=%Rrc\n", rc)); 1544 else if (vmR3TrySetState(pVM, VMSTATE_GURU_MEDITATION, VMSTATE_GURU_MEDITATION_LS)) 1545 Log(("VMR3Save: Guru meditation; rc=%Rrc\n", rc)); 1560 rc = vmR3SuspendCommon(pVM, false /*fFatal*/); /** @todo this races external VMR3Suspend calls and may cause trouble (goes for any VMCPUID_ALL* calls messing with the state in the handler). */ 1561 if (RT_SUCCESS(rc)) 1562 rc = VMR3ReqCallWaitU(pVM->pUVM, 0 /*idDstCpu*/, (PFNRT)vmR3SaveLiveStep2, 2, pVM, pSSM); 1546 1563 else 1547 1564 { 1548 AssertLogRelMsgFailed(("%s rc=%Rrc\n", pVM->enmVMState, rc));1549 rc = VERR_INTERNAL_ERROR_4;1565 int rc2 = VMR3ReqCallWait(pVM, 0 /*idDstCpu*/, (PFNRT)vmR3SaveLiveStep1Cleanup, 2, pVM, pSSM); 1566 AssertLogRelRC(rc2); 1550 1567 } 1551 #else1552 rc = VERR_NOT_IMPLEMENTED;1553 SSMR3LiveDone(pSSM);1554 #endif1555 1568 } 1556 1569 … … 2335 2348 static DECLCALLBACK(int) vmR3Reset(PVM pVM) 2336 2349 { 2350 int rcRet = VINF_EM_RESET; 2337 2351 PVMCPU pVCpu = VMMGetCpu(pVM); 2338 2352 … … 2419 2433 PUVM pUVM = pVM->pUVM; 2420 2434 RTCritSectEnter(&pUVM->vm.s.AtStateCritSect); 2421 if (pUVM->vm.s.enmPrevVMState == VMSTATE_SUSPENDED) 2422 vmR3SetStateLocked(pVM, pUVM, VMSTATE_SUSPENDED, VMSTATE_RESETTING); 2435 enmVMState = pVM->enmVMState; 2436 if (enmVMState == VMSTATE_RESETTING) 2437 { 2438 if (pUVM->vm.s.enmPrevVMState == VMSTATE_SUSPENDED) 2439 vmR3SetStateLocked(pVM, pUVM, VMSTATE_SUSPENDED, VMSTATE_RESETTING); 2440 else 2441 vmR3SetStateLocked(pVM, pUVM, VMSTATE_RUNNING, VMSTATE_RESETTING); 2442 } 2423 2443 else 2424 vmR3SetStateLocked(pVM, pUVM, VMSTATE_RUNNING, pVM->enmVMState); 2444 { 2445 /** @todo EMT(0) should not execute code if the state is 2446 * VMSTATE_RESETTING_LS... This requires adding 2447 * VINF_EM_RESET_AND_SUSPEND. Can be done later. */ 2448 vmR3SetStateLocked(pVM, pUVM, VMSTATE_RESET_LS, VMSTATE_RESETTING_LS); 2449 rcRet = VINF_EM_RESET/*_AND_SUSPEND*/; 2450 } 2425 2451 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect); 2426 2452 … … 2428 2454 } 2429 2455 2430 return VINF_EM_RESET;2456 return rcRet; 2431 2457 } 2432 2458 … … 2486 2512 case VMSTATE_RESETTING: return "RESETTING"; 2487 2513 case VMSTATE_RESETTING_LS: return "RESETTING_LS"; 2514 case VMSTATE_RESET_LS: return "RESET_LS"; 2488 2515 case VMSTATE_SUSPENDED: return "SUSPENDED"; 2489 2516 case VMSTATE_SUSPENDED_LS: return "SUSPENDED_LS"; … … 2583 2610 2584 2611 case VMSTATE_RESETTING_LS: 2612 AssertMsgReturn( enmStateNew == VMSTATE_RUNNING 2613 || enmStateNew == VMSTATE_RESET_LS 2614 , ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false); 2615 break; 2616 2617 case VMSTATE_RESET_LS: 2585 2618 AssertMsgReturn(enmStateNew == VMSTATE_RUNNING, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false); 2586 2619 break; … … 2591 2624 2592 2625 case VMSTATE_SUSPENDING_LS: 2593 AssertMsgReturn(enmStateNew == VMSTATE_SUSPENDED_LS, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false); 2626 AssertMsgReturn( enmStateNew == VMSTATE_SUSPENDING 2627 || enmStateNew == VMSTATE_SUSPENDED_LS 2628 , ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false); 2594 2629 break; 2595 2630 … … 2620 2655 2621 2656 case VMSTATE_DEBUGGING_LS: 2622 AssertMsgReturn( enmStateNew == VMSTATE_RUNNING_LS 2657 AssertMsgReturn( enmStateNew == VMSTATE_DEBUGGING 2658 || enmStateNew == VMSTATE_RUNNING_LS 2623 2659 || enmStateNew == VMSTATE_POWERING_OFF_LS 2624 2660 , ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
Note:
See TracChangeset
for help on using the changeset viewer.