VirtualBox

Changeset 24558 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Nov 10, 2009 3:59:07 PM (15 years ago)
Author:
vboxsync
Message:

Main: Teleport to local process with disks attached. Delays the LockMedia call till after the source machine has unlocked them.

Location:
trunk/src/VBox/Main
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r24552 r24558  
    66866686        }
    66876687
    6688         /* lock attached media. This method will also check their
    6689          * accessibility. Note that the media will be unlocked automatically
    6690          * by SessionMachine::setMachineState() when the VM is powered down. */
    6691         rc = console->mControl->LockMedia();
    6692         CheckComRCThrowRC(rc);
     6688        /*
     6689         * Lock attached media. This method will also check their accessibility.
     6690         * If we're a teleporter, we'll have to postpone this action so we can
     6691         * migrate between local processes.
     6692         *
     6693         * Note! The media will be unlocked automatically by
     6694         *       SessionMachine::setMachineState() when the VM is powered down.
     6695         */
     6696        if (!task->mTeleporterEnabled)
     6697        {
     6698            rc = console->mControl->LockMedia();
     6699            CheckComRCThrowRC(rc);
     6700        }
    66936701
    66946702#ifdef VBOX_WITH_VRDP
  • trunk/src/VBox/Main/ConsoleImplTeleporter.cpp

    r24365 r24558  
    9494    MachineState_T      menmOldMachineState;
    9595    bool                mfSuspendedByUs;
     96    bool                mfUnlockedMedia;
    9697
    9798    TeleporterStateSrc(Console *pConsole, PVM pVM, Progress *pProgress, MachineState_T enmOldMachineState)
     
    100101        , menmOldMachineState(enmOldMachineState)
    101102        , mfSuspendedByUs(false)
     103        , mfUnlockedMedia(false)
    102104    {
    103105    }
     
    111113{
    112114public:
    113     IMachine           *mpMachine;
    114     PRTTCPSERVER        mhServer;
    115     PRTTIMERLR          mphTimerLR;
    116     bool                mfStartPaused;
    117     int                 mRc;
     115    IMachine                   *mpMachine;
     116    IInternalMachineControl    *mpControl;
     117    PRTTCPSERVER                mhServer;
     118    PRTTIMERLR                  mphTimerLR;
     119    bool                        mfStartPaused;
     120    bool                        mfLockedMedia;
     121    int                         mRc;
    118122
    119123    TeleporterStateTrg(Console *pConsole, PVM pVM, Progress *pProgress,
    120                        IMachine *pMachine, PRTTIMERLR phTimerLR, bool fStartPaused)
     124                       IMachine *pMachine, IInternalMachineControl *pControl,
     125                       PRTTIMERLR phTimerLR, bool fStartPaused)
    121126        : TeleporterState(pConsole, pVM, pProgress, false /*fIsSource*/)
    122127        , mpMachine(pMachine)
     128        , mpControl(pControl)
    123129        , mhServer(NULL)
    124130        , mphTimerLR(phTimerLR)
    125131        , mfStartPaused(false)
     132        , mfLockedMedia(false)
    126133        , mRc(VINF_SUCCESS)
    127134    {
     
    651658        return E_FAIL;
    652659    }
     660
     661    /*
     662     * The last thing we do is to hand over any media we might have locked.
     663     */
     664    /** @todo Maybe we should only do this if it's a local teleportation... */
     665    hrc = mControl->UnlockMedia();
     666    if (FAILED(hrc))
     667        return hrc;
     668    pState->mfUnlockedMedia = true;
     669
     670    hrc = teleporterSrcSubmitCommand(pState, "lock-media");
     671    if (FAILED(hrc))
     672        return hrc;
     673
    653674    hrc = teleporterSrcSubmitCommand(pState, "done");
    654675    if (FAILED(hrc))
     
    727748           )
    728749        {
     750            if (pState->mfUnlockedMedia)
     751            {
     752                ErrorInfoKeeper Oak;
     753                HRESULT hrc2 = pState->mptrConsole->mControl->LockMedia();
     754                if (FAILED(hrc2))
     755                {
     756                    uint64_t StartMS = RTTimeMilliTS();
     757                    do
     758                    {
     759                        RTThreadSleep(2);
     760                        hrc2 = pState->mptrConsole->mControl->LockMedia();
     761                    } while (   FAILED(hrc2)
     762                             && RTTimeMilliTS() - StartMS < 2000);
     763                }
     764                if (SUCCEEDED(hrc2))
     765                    pState->mfUnlockedMedia = true;
     766                else
     767                    LogRel(("FATAL ERROR: Failed to re-take the media locks. hrc2=%Rhrc\n", hrc2));
     768            }
     769
    729770            switch (enmVMState)
    730771            {
     
    738779                case VMSTATE_RESETTING_LS:
    739780                    Assert(!pState->mfSuspendedByUs);
     781                    Assert(!pState->mfUnlockedMedia);
    740782                    pState->mptrConsole->setMachineState(MachineState_Running);
    741783                    break;
     
    758800                case VMSTATE_SUSPENDING_LS:
    759801                case VMSTATE_SUSPENDING_EXT_LS:
    760                     pState->mptrConsole->setMachineState(MachineState_Paused);
    761                     if (pState->mfSuspendedByUs)
     802                    if (!pState->mfUnlockedMedia)
    762803                    {
    763                         autoLock.leave();
    764                         int rc = VMR3Resume(pState->mpVM);
    765                         AssertLogRelMsgRC(rc, ("VMR3Resume -> %Rrc\n", rc));
    766                         autoLock.enter();
     804                        pState->mptrConsole->setMachineState(MachineState_Paused);
     805                        if (pState->mfSuspendedByUs)
     806                        {
     807                            autoLock.leave();
     808                            int rc = VMR3Resume(pState->mpVM);
     809                            AssertLogRelMsgRC(rc, ("VMR3Resume -> %Rrc\n", rc));
     810                            autoLock.enter();
     811                        }
     812                    }
     813                    else
     814                    {
     815                        /* Faking a guru meditation is the best I can think of doing here... */
     816                        pState->mptrConsole->setMachineState(MachineState_Stuck);
    767817                    }
    768818                    break;
     
    9561006             * Do the job, when it returns we're done.
    9571007             */
    958             TeleporterStateTrg State(this, pVM, pProgress, pMachine, &hTimerLR, fStartPaused);
     1008            TeleporterStateTrg State(this, pVM, pProgress, pMachine, mControl, &hTimerLR, fStartPaused);
    9591009            State.mstrPassword      = strPassword;
    9601010            State.mhServer          = hServer;
     
    10361086
    10371087
     1088/**
     1089 * Unlock the media.
     1090 *
     1091 * This is used in error paths.
     1092 *
     1093 * @param  pState           The teleporter state.
     1094 */
     1095static void teleporterTrgUnlockMedia(TeleporterStateTrg *pState)
     1096{
     1097    if (pState->mfLockedMedia)
     1098    {
     1099        pState->mpControl->UnlockMedia();
     1100        pState->mfLockedMedia = false;
     1101    }
     1102}
     1103
     1104
    10381105static int teleporterTcpWriteACK(TeleporterStateTrg *pState)
    10391106{
    10401107    int rc = RTTcpWrite(pState->mhSocket, "ACK\n", sizeof("ACK\n") - 1);
    10411108    if (RT_FAILURE(rc))
     1109    {
    10421110        LogRel(("Teleporter: RTTcpWrite(,ACK,) -> %Rrc\n", rc));
     1111        teleporterTrgUnlockMedia(pState);
     1112    }
    10431113    RTTcpFlush(pState->mhSocket);
    10441114    return rc;
     
    10481118static int teleporterTcpWriteNACK(TeleporterStateTrg *pState, int32_t rc2)
    10491119{
     1120    /*
     1121     * Unlock media sending the NACK. That way the other doesn't have to spin
     1122     * waiting to regain the locks.
     1123     */
     1124    teleporterTrgUnlockMedia(pState);
     1125
    10501126    char    szMsg[64];
    10511127    size_t  cch = RTStrPrintf(szMsg, sizeof(szMsg), "NACK=%d\n", rc2);
     
    11171193     * Command processing loop.
    11181194     */
     1195    bool fDone = false;
    11191196    for (;;)
    11201197    {
     
    11541231            vrc = teleporterTcpWriteACK(pState);
    11551232        }
    1156         /** @todo implement config verification and hardware compatability checks. Or
    1157          *        maybe leave part of these to the saved state machinery?
    1158          * Update: We're doing as much as possible in the first SSM pass. */
    11591233        else if (!strcmp(szCmd, "cancel"))
    11601234        {
     
    11681242            vrc = teleporterTcpWriteACK(pState);
    11691243        }
     1244        else if (!strcmp(szCmd, "lock-media"))
     1245        {
     1246            HRESULT hrc = pState->mpControl->LockMedia();
     1247            if (SUCCEEDED(hrc))
     1248            {
     1249                pState->mfLockedMedia = true;
     1250                vrc = teleporterTcpWriteACK(pState);
     1251            }
     1252            else
     1253            {
     1254                vrc = VERR_FILE_LOCK_FAILED;
     1255                teleporterTcpWriteNACK(pState, vrc);
     1256            }
     1257        }
    11701258        else if (!strcmp(szCmd, "done"))
    11711259        {
     
    11731261             * The ACK is the point of no return.
    11741262             */
    1175             if (pState->mptrProgress->notifyPointOfNoReturn())
     1263            if (   pState->mptrProgress->notifyPointOfNoReturn()
     1264                && pState->mfLockedMedia)
    11761265                vrc = teleporterTcpWriteACK(pState);
    11771266            else
    11781267            {
    1179                 vrc = VERR_SSM_CANCELLED;
     1268                vrc = pState->mfLockedMedia ? VERR_WRONG_ORDER : VERR_SSM_CANCELLED;
    11801269                teleporterTcpWriteNACK(pState, vrc);
    11811270            }
     1271            fDone = true;
    11821272            break;
    11831273        }
     
    11941284    }
    11951285
     1286    if (RT_SUCCESS(vrc) && !fDone)
     1287        vrc = VERR_WRONG_ORDER;
     1288    if (RT_FAILURE(vrc))
     1289        teleporterTrgUnlockMedia(pState);
     1290
    11961291    pState->mRc = vrc;
    11971292    pState->mhSocket = NIL_RTSOCKET;
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r24539 r24558  
    36823682  <interface
    36833683     name="IInternalMachineControl" extends="$unknown"
    3684      uuid="4e2b8f0f-6575-49d2-bb19-5cd15a6ca2f0"
     3684     uuid="35d8d838-d066-447d-927a-fd93afdbec90"
    36853685     internal="yes"
    36863686     wsmap="suppress"
     
    40404040        Restoring state. The locked media will be automatically unlocked when
    40414041        the machine is powered off or crashed.
     4042      </desc>
     4043    </method>
     4044    <method name="unlockMedia">
     4045      <desc>
     4046        Unlocks all media previously locked using
     4047        <link to="IInternalMachineControl::lockMedia"/>.
     4048
     4049        This method is intended to be used with teleportation so that it is
     4050        possible to teleport between processes on the same machine.
    40424051      </desc>
    40434052    </method>
     
    58035812        <desc>
    58045813          How to order bytes in the pixel. A pixel consists of 4 bytes. If this parameter is true, then
    5805           bytes order is: B, G, R, 0xFF. If this parameter is false, then bytes order is: R, G, B, 0xFF. 
     5814          bytes order is: B, G, R, 0xFF. If this parameter is false, then bytes order is: R, G, B, 0xFF.
    58065815        </desc>
    58075816      </param>
  • trunk/src/VBox/Main/include/MachineImpl.h

    r24539 r24558  
    998998    STDMETHOD(PushGuestProperty)(IN_BSTR aName, IN_BSTR aValue,
    999999                                  ULONG64 aTimestamp, IN_BSTR aFlags);
    1000     STDMETHOD(LockMedia)() { return lockMedia(); }
     1000    STDMETHOD(LockMedia)()   { return lockMedia(); }
     1001    STDMETHOD(UnlockMedia)() { unlockMedia(); return S_OK; }
    10011002
    10021003    // public methods only for internal purposes
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