VirtualBox

Changeset 22915 in vbox


Ignore:
Timestamp:
Sep 10, 2009 1:43:25 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
52177
Message:

VMM: some state stuff (work in progress, back out on bustage).

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/types.h

    r22578 r22915  
    152152    /** The VM is created. */
    153153    VMSTATE_CREATED,
     154    /** The VM state is being loaded from file. */
     155    VMSTATE_LOADING,
    154156    /** The VM is runnning. */
    155157    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,
    158184    /** The VM is screwed because of a failed state loading. */
    159185    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,
    168186    /** The VM is switched off, awaiting destruction. */
    169187    VMSTATE_OFF,
  • trunk/include/VBox/vmapi.h

    r22890 r22915  
    352352VMMR3DECL(int)  VMR3PowerOn(PVM pVM);
    353353VMMR3DECL(int)  VMR3Suspend(PVM pVM);
    354 VMMR3DECL(int)  VMR3SuspendNoSave(PVM pVM);
    355354VMMR3DECL(int)  VMR3Resume(PVM pVM);
    356355VMMR3DECL(int)  VMR3Reset(PVM pVM);
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r22866 r22915  
    57985798        }
    57995799
    5800         case VMSTATE_GURU_MEDITATION:
     5800        case VMSTATE_FATAL_ERROR:
    58015801        {
    58025802            AutoWriteLock alock(that);
     
    58055805                break;
    58065806
    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 */
    58085827            Assert (Global::IsOnline (that->mMachineState));
    58095828
  • trunk/src/VBox/VMM/VM.cpp

    r22890 r22915  
    133133static DECLCALLBACK(size_t) vmR3LogPrefixCallback(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser);
    134134static DECLCALLBACK(int) vmR3PowerOn(PVM pVM);
    135 static DECLCALLBACK(int) vmR3Suspend(PVM pVM);
     135static int               vmR3SuspendCommon(PVM pVM, bool fFatal);
     136static DECLCALLBACK(int) vmR3Suspend(PVM pVM, bool fFatal);
    136137static DECLCALLBACK(int) vmR3Resume(PVM pVM);
    137 static DECLCALLBACK(int) vmR3Save(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser);
     138static DECLCALLBACK(int) vmR3Save(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser, PSSMHANDLE *ppSSM);
    138139static DECLCALLBACK(int) vmR3Load(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser);
    139140static DECLCALLBACK(int) vmR3PowerOff(PVM pVM);
     
    12271228
    12281229    /*
    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 */
     1254static int vmR3SuspendCommon(PVM pVM, bool fFatal)
     1255{
    12371256    /*
    12381257     * Request the operation in EMT. (in reverse order as VCPU 0 does the actual work)
    12391258     */
    12401259    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);
    12421262    if (RT_SUCCESS(rc))
    12431263    {
     
    12481268        Assert(pReq == NULL);
    12491269
    1250     LogFlow(("VMR3Suspend: returns %Rrc\n", rc));
    12511270    return rc;
    12521271}
     
    12541273
    12551274/**
    1256  * Suspends a running VM and prevent state saving until the VM is resumed or stopped.
     1275 * Suspends a running VM.
    12571276 *
    12581277 * @returns 0 on success.
    12591278 * @returns VBox error code on failure.
    12601279 * @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.
    12781281 * @thread  EMT
    12791282 */
    1280 static DECLCALLBACK(int) vmR3Suspend(PVM pVM)
     1283static DECLCALLBACK(int) vmR3Suspend(PVM pVM, bool fFatal)
    12811284{
    12821285    LogFlow(("vmR3Suspend: pVM=%p\n", pVM));
     
    12991302     * Change the state, notify the components and resume the execution.
    13001303     */
    1301     vmR3SetState(pVM, VMSTATE_SUSPENDED);
     1304    vmR3SetState(pVM, fFatal ? VMSTATE_FATAL_ERROR : VMSTATE_SUSPENDED);
    13021305    PDMR3Suspend(pVM);
    13031306
     
    13991402 * @param   pVM                 VM which state should be saved.
    14001403 * @param   pszFilename         Name of the save state file.
    1401  * @param   fContinueAftewards Continue execution afterwards. When in doubt,
     1404 * @param   fContinueAfterwards Continue execution afterwards. When in doubt,
    14021405 *                              set this to true.
    14031406 * @param   pfnProgress         Progress callback. Optional.
     
    14081411 * @vmstateto   Suspended.
    14091412 */
    1410 VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAftewards, PFNVMPROGRESS pfnProgress, void *pvUser)
    1411 {
    1412     LogFlow(("VMR3Save: pVM=%p pszFilename=%p:{%s} fContinueAftewards=%RTbool pfnProgress=%p pvUser=%p\n",
    1413              pVM, pszFilename, pszFilename, fContinueAftewards, pfnProgress, pvUser));
     1413VMMR3DECL(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));
    14141417
    14151418    /*
     
    14241427     * Request the operation in EMT(0).
    14251428     */
    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;
    14281432    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);
    14301434    if (RT_SUCCESS(rc))
    14311435    {
    14321436        rc = pReq->iStatus;
    14331437        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
    14341460    }
    14351461
     
    14491475 * @param   pfnProgress     Progress callback. Optional.
    14501476 * @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.
    14511479 * @thread  EMT
    14521480 */
    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));
     1481static 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));
    14561484
    14571485    /*
     
    14591487     */
    14601488    /** @todo SMP: Check that vmR3SetState always done by EMT(0). If not add a vmR3TrySetState(). */
     1489    *ppSSM = NULL;
    14611490    AssertMsgReturn(   pVM->enmVMState == VMSTATE_SUSPENDED
    14621491                    || pVM->enmVMState == VMSTATE_RUNNING,
     
    14721501
    14731502    /*
    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    }
    14801517
    14811518    return rc;
     
    16421679        &&  pVM->enmVMState != VMSTATE_SUSPENDED
    16431680        &&  pVM->enmVMState != VMSTATE_LOAD_FAILURE
     1681        &&  pVM->enmVMState != VMSTATE_FATAL_ERROR
    16441682        &&  pVM->enmVMState != VMSTATE_GURU_MEDITATION)
    16451683    {
     
    27042742        case VMSTATE_CREATING:          return "CREATING";
    27052743        case VMSTATE_CREATED:           return "CREATED";
     2744        case VMSTATE_LOADING:           return "LOADING";
    27062745        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";
    27082758        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";
    27132759        case VMSTATE_OFF:               return "OFF";
    27142760        case VMSTATE_DESTROYING:        return "DESTROYING";
    27152761        case VMSTATE_TERMINATED:        return "TERMINATED";
     2762
    27162763        default:
    27172764            AssertMsgFailed(("Unknown state %d\n", enmState));
     
    27302777void vmR3SetState(PVM pVM, VMSTATE enmStateNew)
    27312778{
     2779#ifdef DEBUG_bird /** @todo remove when sorted out. */
     2780    VM_ASSERT_EMT0(pVM);
     2781#endif
     2782
    27322783    /*
    27332784     * Validate state machine transitions before doing the actual change.
     
    34113462    int rc = VINF_SUCCESS;
    34123463    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*/);
    34163465    else if (fFlags & VMSETRTERR_FLAGS_SUSPEND)
    34173466        rc = VMR3Suspend(pVM);
     
    34923541 * @param   fFlags          The error flags.
    34933542 * @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.
    34963544 *
    34973545 * @thread  EMT
    34983546 */
    3499 DECLCALLBACK(int) vmR3SetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list *pVa)
    3500 {
     3547DECLCALLBACK(int) vmR3SetRuntimeError(PVM pVM, uint32_t fFlags, const char *pszErrorId, char *pszMessage)
     3548{
     3549#if 0 /** @todo make copy of the error msg. */
    35013550    /*
    35023551     * Make a copy of the message.
     
    35063555    vmSetRuntimeErrorCopy(pVM, fFlags, pszErrorId, pszFormat, va2);
    35073556    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 */
     3581DECLCALLBACK(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);
    35083590
    35093591    /*
  • trunk/src/VBox/VMM/VMInternal.h

    r20374 r22915  
    461461DECLCALLBACK(void)  vmR3SetErrorUV(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list *args);
    462462void                vmSetErrorCopy(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args);
     463DECLCALLBACK(int)   vmR3SetRuntimeError(PVM pVM, uint32_t fFlags, const char *pszErrorId, char *pszMessage);
    463464DECLCALLBACK(int)   vmR3SetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list *pVa);
    464465void                vmSetRuntimeErrorCopy(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va);
  • trunk/src/VBox/VMM/VMMAll/VMAll.cpp

    r20874 r22915  
    255255    /*
    256256     * 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     */
    260262    int rc;
    261263    PVMREQ pReq;
     
    263265        ||  VM_IS_EMT(pVM))
    264266    {
     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. */
    265271        rc = VMR3ReqCallU(pVM->pUVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, VMREQFLAGS_VBOX_STATUS,
    266272                          (PFNRT)vmR3SetRuntimeErrorV, 5, pVM, fFlags, pszErrorId, pszFormat, &va2);
     273        va_end(va2);
    267274        if (RT_SUCCESS(rc))
    268275            rc = pReq->iStatus;
    269276    }
    270277    else
     278    {
     279        char *pszMessage = MMR3HeapAPrintfV(pVM, MM_TAG_VM, pszFormat, va);
     280
    271281        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    }
    273286    VMR3ReqFree(pReq);
    274     va_end(va2);
    275287
    276288#else
Note: See TracChangeset for help on using the changeset viewer.

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