VirtualBox

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


Ignore:
Timestamp:
Oct 8, 2009 10:14:29 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
53318
Message:

Main: A little more live migration bits.

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

Legend:

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

    r23626 r23633  
    4545 * Argument package for Console::migrationServeConnection.
    4646 */
    47 typedef struct MIGRATIONSERVEARGS
     47typedef struct MIGRATIONSTATE
    4848{
    4949    Console    *pConsole;
     
    5151    PVM         pVM;
    5252    const char *pszPassword;
    53     RTTIMERLR   hTimer;
    54 } MIGRATIONSERVEARGS;
    55 typedef MIGRATIONSERVEARGS *PMIGRATIONSERVEARGS;
     53    void       *pvVMCallbackTask;
     54    RTSOCKET    hSocket;
     55    uint64_t    offStream;
     56    int         rc;
     57} MIGRATIONSTATE;
     58typedef MIGRATIONSTATE *PMIGRATIONSTATE;
    5659
    5760
     
    6265
    6366
     67/**
     68 * @copydoc SSMSTRMOPS::pfnWrite
     69 */
     70static DECLCALLBACK(int) migrationTcpOpWrite(void *pvUser, uint64_t offStream, const void *pvBuf, size_t cbToWrite)
     71{
     72    PMIGRATIONSTATE pState = (PMIGRATIONSTATE)pvUser;
     73    int rc = RTTcpWrite(pState->hSocket, pvBuf, cbToWrite);
     74    if (RT_SUCCESS(rc))
     75    {
     76        pState->offStream += cbToWrite;
     77        return VINF_SUCCESS;
     78    }
     79    return rc;
     80}
     81
     82
     83/**
     84 * @copydoc SSMSTRMOPS::pfnRead
     85 */
     86static DECLCALLBACK(int) migrationTcpOpRead(void *pvUser, uint64_t offStream, void *pvBuf, size_t cbToRead, size_t *pcbRead)
     87{
     88    PMIGRATIONSTATE pState = (PMIGRATIONSTATE)pvUser;
     89    int rc = RTTcpRead(pState->hSocket, pvBuf, cbToRead, pcbRead);
     90    if (RT_SUCCESS(rc))
     91    {
     92        pState->offStream += pcbRead ? *pcbRead : cbToRead;
     93        return VINF_SUCCESS;
     94    }
     95    return rc;
     96}
     97
     98
     99/**
     100 * @copydoc SSMSTRMOPS::pfnSeek
     101 */
     102static DECLCALLBACK(int) migrationTcpOpSeek(void *pvUser, int64_t offSeek, unsigned uMethod, uint64_t *poffActual)
     103{
     104    return VERR_NOT_SUPPORTED;
     105}
     106
     107
     108/**
     109 * @copydoc SSMSTRMOPS::pfnTell
     110 */
     111static DECLCALLBACK(uint64_t) migrationTcpOpTell(void *pvUser)
     112{
     113    PMIGRATIONSTATE pState = (PMIGRATIONSTATE)pvUser;
     114    return pState->offStream;
     115}
     116
     117
     118/**
     119 * @copydoc SSMSTRMOPS::pfnSize
     120 */
     121static DECLCALLBACK(int) migrationTcpOpSize(void *pvUser, uint64_t *pcb)
     122{
     123    return VERR_NOT_SUPPORTED;
     124}
     125
     126
     127/**
     128 * @copydoc SSMSTRMOPS::pfnClose
     129 */
     130static DECLCALLBACK(int) migrationTcpOpClose(void *pvUser)
     131{
     132    return VINF_SUCCESS;
     133}
     134
     135
     136/**
     137 * Method table for a TCP based stream.
     138 */
     139static SSMSTRMOPS const g_migrationTcpOps =
     140{
     141    SSMSTRMOPS_VERSION,
     142    migrationTcpOpWrite,
     143    migrationTcpOpRead,
     144    migrationTcpOpSeek,
     145    migrationTcpOpTell,
     146    migrationTcpOpSize,
     147    migrationTcpOpClose,
     148    SSMSTRMOPS_VERSION
     149};
     150
    64151
    65152/**
     
    73160
    74161
     162/**
     163 * Start live migration to the specified target.
     164 *
     165 * @returns COM status code.
     166 *
     167 * @param   aHostname   The name of the target host.
     168 * @param   aPort       The TCP port number.
     169 * @param   aPassword   The password.
     170 * @param   aProgress   Where to return the progress object.
     171 */
    75172STDMETHODIMP
    76173Console::Migrate(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, IProgress **aProgress)
    77174{
     175    /*
     176     * Validate parameters.
     177     */
     178
     179    /*
     180     * Try change the state, create a progress object and spawn a worker thread.
     181     */
     182
    78183    return E_FAIL;
    79184}
     
    87192 * @param   pVM                 The VM handle
    88193 * @param   pMachine            The IMachine for the virtual machine.
     194 * @param   pvVMCallbackTask    The callback task pointer for
     195 *                              stateProgressCallback().
    89196 */
    90197int
    91 Console::migrationLoadRemote(PVM pVM, IMachine *pMachine)
     198Console::migrationLoadRemote(PVM pVM, IMachine *pMachine, void *pvVMCallbackTask)
    92199{
    93200    /*
     
    140247
    141248    /*
    142      * Create a timer for timing out after 5 mins.
    143      */
    144     RTTIMERLR hTimer;
    145     rc = RTTimerLRCreateEx(&hTimer, 0, 0, migrationTimeout, hServer);
     249     * Create a one-shot timer for timing out after 5 mins.
     250     */
     251    RTTIMERLR hTimerLR;
     252    rc = RTTimerLRCreateEx(&hTimerLR, 0 /*ns*/, RTTIMER_FLAGS_CPU_ANY, migrationTimeout, hServer);
    146253    if (RT_SUCCESS(rc))
    147254    {
    148         rc = RTTimerLRStart(hTimer, 5*60*UINT64_C(1000000000) /*ns*/);
     255        rc = RTTimerLRStart(hTimerLR, 5*60*UINT64_C(1000000000) /*ns*/);
    149256        if (RT_SUCCESS(rc))
    150257        {
     
    152259             * Do the job, when it returns we're done.
    153260             */
    154             MIGRATIONSERVEARGS Args;
    155             Args.pConsole    = this;
    156             Args.pMachine    = pMachine;
    157             Args.pVM         = pVM;
    158             Args.pszPassword = strPassword.c_str();
    159             Args.hTimer      = hTimer;
    160             rc = RTTcpServerListen(hServer, Console::migrationServeConnection, &Args);
    161         }
    162 
    163         RTTimerLRDestroy(hTimer);
     261            MIGRATIONSTATE State;
     262            State.pConsole      = this;
     263            State.pMachine      = pMachine;
     264            State.pVM           = pVM;
     265            State.pszPassword   = strPassword.c_str();
     266            State.hSocket       = NIL_RTSOCKET;
     267            State.offStream     = UINT64_MAX / 2;
     268            State.rc            = VINF_SUCCESS;
     269
     270            rc = RTTcpServerListen(hServer, Console::migrationServeConnection, &State);
     271            if (rc == VERR_TCP_SERVER_STOP)
     272                rc = State.rc;
     273            if (RT_FAILURE(rc))
     274                LogRel(("Migration: RTTcpServerListen -> %Rrc\n", rc));
     275        }
     276
     277        RTTimerLRDestroy(hTimerLR);
    164278    }
    165279    RTTcpServerDestroy(hServer);
     
    167281    return rc;
    168282}
     283
    169284
    170285/**
     
    215330Console::migrationServeConnection(RTSOCKET Sock, void *pvUser)
    216331{
    217     PMIGRATIONSERVEARGS pArgs       = (PMIGRATIONSERVEARGS)pvUser;
    218     Console            *pConsole    = pArgs->pConsole;
    219     IMachine           *pMachine    = pArgs->pMachine;
    220     PVM                 pVM         = pArgs->pVM;
    221     const char         *pszPassword = pArgs->pszPassword;
     332    PMIGRATIONSTATE pState   = (PMIGRATIONSTATE)pvUser;
     333    Console        *pConsole = pState->pConsole;
     334    IMachine       *pMachine = pState->pMachine;
    222335
    223336    /*
     
    236349     * this is the last connection attempt).
    237350     */
    238     unsigned off = 0;
     351    const char *pszPassword = pState->pszPassword;
     352    unsigned    off = 0;
    239353    while (pszPassword[off])
    240354    {
     
    256370     * Command processing loop.
    257371     */
     372    pState->hSocket = Sock;
    258373    for (;;)
    259374    {
     
    263378            break;
    264379
    265         if (!strcmp(szCmd, "state"))
    266         {
    267             /* restore the state. */
    268         }
     380        if (!strcmp(szCmd, "load"))
     381        {
     382            pState->offStream = 0;
     383            rc = VMR3LoadFromStream(pState->pVM, &g_migrationTcpOps, pState,
     384                                    Console::stateProgressCallback, pState->pvVMCallbackTask);
     385            if (RT_FAILURE(rc))
     386            {
     387                LogRel(("Migration: VMR3LoadFromStream -> %Rrc\n", rc));
     388                break;
     389            }
     390        }
     391        /** @todo implement config verification and hardware compatability checks. Or
     392         *        maybe leave part of these to the saved state machinery? */
    269393        else if (!strcmp(szCmd, "done"))
    270394            break;
     
    275399        }
    276400    }
     401    pState->hSocket = NIL_RTSOCKET;
    277402
    278403    return VERR_TCP_SERVER_STOP;
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r23624 r23633  
    67286728                else if (task->mLiveMigrationTarget)
    67296729                    /* -> ConsoleImpl-LiveMigration.cpp */
    6730                     vrc = console->migrationLoadRemote(pVM, pMachine);
     6730                    vrc = console->migrationLoadRemote(pVM, pMachine, static_cast<VMProgressTask*>(task.get()));
    67316731                else if (task->mStartPaused)
    67326732                    /* done */
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r23626 r23633  
    514514    /** @name Live migration support
    515515     * @{ */
    516     int                         migrationLoadRemote(PVM pVM, IMachine *pMachine);
     516    int                         migrationLoadRemote(PVM pVM, IMachine *pMachine, void *pvVMCallbackTask);
    517517    static DECLCALLBACK(int)    migrationServeConnection(RTSOCKET Sock, void *pvUser);
    518518    /** @} */
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