VirtualBox

Changeset 23037 in vbox for trunk/src


Ignore:
Timestamp:
Sep 15, 2009 8:00:08 PM (15 years ago)
Author:
vboxsync
Message:

VMR3Save: Code done. (Had to add VMSTATE_RESET_LS to deal with reset.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VM.cpp

    r23024 r23037  
    14281428
    14291429/**
     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 */
     1444static 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/**
    14301475 * Worker for VMR3Save continues a live save on EMT(0).
    14311476 *
     
    14401485    LogFlow(("vmR3SaveLiveStep2: pVM=%p pSSM=%p\n", pVM, pSSM));
    14411486    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);
    14461496
    14471497    return rc;
    14481498}
     1499
    14491500
    14501501
     
    14981549        &&  pSSM)
    14991550    {
    1500 #if 0 /** @todo later*/
    15011551        /*
    15021552         * 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.
    15031557         */
    15041558        rc = SSMR3LiveDoStep1(pSSM);
    15051559        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);
    15461563        else
    15471564        {
    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);
    15501567        }
    1551 #else
    1552         rc = VERR_NOT_IMPLEMENTED;
    1553         SSMR3LiveDone(pSSM);
    1554 #endif
    15551568    }
    15561569
     
    23352348static DECLCALLBACK(int) vmR3Reset(PVM pVM)
    23362349{
     2350    int    rcRet = VINF_EM_RESET;
    23372351    PVMCPU pVCpu = VMMGetCpu(pVM);
    23382352
     
    24192433        PUVM pUVM = pVM->pUVM;
    24202434        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        }
    24232443        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        }
    24252451        RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
    24262452
     
    24282454    }
    24292455
    2430     return VINF_EM_RESET;
     2456    return rcRet;
    24312457}
    24322458
     
    24862512        case VMSTATE_RESETTING:         return "RESETTING";
    24872513        case VMSTATE_RESETTING_LS:      return "RESETTING_LS";
     2514        case VMSTATE_RESET_LS:          return "RESET_LS";
    24882515        case VMSTATE_SUSPENDED:         return "SUSPENDED";
    24892516        case VMSTATE_SUSPENDED_LS:      return "SUSPENDED_LS";
     
    25832610
    25842611        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:
    25852618            AssertMsgReturn(enmStateNew == VMSTATE_RUNNING, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
    25862619            break;
     
    25912624
    25922625        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);
    25942629            break;
    25952630
     
    26202655
    26212656        case VMSTATE_DEBUGGING_LS:
    2622             AssertMsgReturn(   enmStateNew == VMSTATE_RUNNING_LS
     2657            AssertMsgReturn(   enmStateNew == VMSTATE_DEBUGGING
     2658                            || enmStateNew == VMSTATE_RUNNING_LS
    26232659                            || enmStateNew == VMSTATE_POWERING_OFF_LS
    26242660                            , ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette