VirtualBox

Changeset 32268 in vbox for trunk/src


Ignore:
Timestamp:
Sep 7, 2010 9:40:47 AM (14 years ago)
Author:
vboxsync
Message:

FT updates

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

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

    r32245 r32268  
    9292*******************************************************************************/
    9393static const char g_szWelcome[] = "VirtualBox-Fault-Tolerance-Sync-1.0\n";
     94
     95static DECLCALLBACK(int) ftmR3PageTreeDestroyCallback(PAVLOGCPHYSNODECORE pBaseNode, void *pvUser);
    9496
    9597/**
     
    171173        RTMemFree(pVM->ftm.s.pszPassword);
    172174
     175    /* Remove all pending memory updates. */
     176    if (pVM->ftm.s.standby.ppPhysPageTree)
     177    {
     178        RTAvloGCPhysDestroy(pVM->ftm.s.standby.ppPhysPageTree, ftmR3PageTreeDestroyCallback, NULL);
     179        pVM->ftm.s.standby.ppPhysPageTree = NULL;
     180    }
     181
    173182    pVM->ftm.s.pszAddress  = NULL;
    174183    pVM->ftm.s.pszPassword = NULL;
     
    797806
    798807/**
     808 * Syncs memory from the master VM
     809 *
     810 * @returns VBox status code.
     811 * @param   pVM             VM Handle.
     812 */
     813static int ftmR3SyncMem(PVM pVM)
     814{
     815    while (true)
     816    {
     817        FTMTCPHDRMEM Hdr;
     818        void *pPage;
     819        RTGCPHYS GCPhys;
     820
     821        /* Read memory header. */
     822        int rc = RTTcpRead(pVM->ftm.s.hSocket, &Hdr, sizeof(Hdr), NULL);
     823        if (RT_FAILURE(rc))
     824        {
     825            Log(("RTTcpRead failed with %Rrc\n", rc));
     826            break;
     827        }
     828        pVM->ftm.s.StatReceivedMem.c += sizeof(Hdr);
     829
     830        if (Hdr.cb == 0)
     831            break;  /* end of sync. */
     832
     833        Assert(Hdr.cb == Hdr.cbPageRange);  /** @todo uncompress */
     834        GCPhys = Hdr.GCPhys;
     835
     836        /* Must be a multiple of PAGE_SIZE. */
     837        Assert((Hdr.cbPageRange & 0xfff) == 0);
     838
     839        while (Hdr.cbPageRange)
     840        {
     841            PFTMPHYSPAGETREENODE pNode = (PFTMPHYSPAGETREENODE)RTAvloGCPhysGet(pVM->ftm.s.standby.ppPhysPageTree, GCPhys);
     842            if (!pNode)
     843            {
     844                /* Allocate memory for the node and page. */
     845                pNode = (PFTMPHYSPAGETREENODE)RTMemAllocZ(sizeof(*pNode) + PAGE_SIZE);
     846                AssertBreak(pNode);
     847
     848                /* Insert the node into the tree. */
     849                pNode->Core.Key = GCPhys;
     850                pNode->pPage = (void *)(pNode + 1);
     851                bool fRet = RTAvloGCPhysInsert(pVM->ftm.s.standby.ppPhysPageTree, &pNode->Core);
     852                Assert(fRet);
     853            }
     854            pPage = pNode->pPage;
     855
     856            /* Fetch the page. */
     857            rc = RTTcpRead(pVM->ftm.s.hSocket, pPage, PAGE_SIZE, NULL);
     858            if (RT_FAILURE(rc))
     859            {
     860                Log(("RTTcpRead page data (%d bytes) failed with %Rrc\n", Hdr.cb, rc));
     861                break;
     862            }
     863            pVM->ftm.s.StatReceivedMem.c += PAGE_SIZE;
     864            Hdr.cbPageRange -= PAGE_SIZE;
     865        }
     866    }
     867    return VINF_SUCCESS;
     868}
     869
     870
     871/**
     872 * Callback handler for RTAvloGCPhysDestroy
     873 *
     874 * @returns 0 to continue, otherwise stop
     875 * @param   pBaseNode       Node to destroy
     876 * @param   pvUser          User parameter
     877 */
     878static DECLCALLBACK(int) ftmR3PageTreeDestroyCallback(PAVLOGCPHYSNODECORE pBaseNode, void *pvUser)
     879{
     880    PVM pVM = (PVM)pvUser;
     881    PFTMPHYSPAGETREENODE pNode = (PFTMPHYSPAGETREENODE)pBaseNode;
     882
     883    if (pVM)    /* NULL when the VM is destroyed. */
     884    {
     885        /* Update the guest memory of the standby VM. */
     886        int rc = PGMR3PhysWriteExternal(pVM, pNode->Core.Key, pNode->pPage, PAGE_SIZE, "FTMemSync");
     887        AssertRC(rc);
     888    }
     889    RTMemFree(pNode);
     890    return 0;
     891}
     892
     893
     894/**
    799895 * Listen for incoming traffic destined for the standby VM.
    800896 *
     
    881977                continue;
    882978
    883             while (true)
    884             {
    885                 FTMTCPHDRMEM Hdr;
    886                 void *pPage;
    887 
    888                 /* Read memory header. */
    889                 rc = RTTcpRead(pVM->ftm.s.hSocket, &Hdr, sizeof(Hdr), NULL);
    890                 if (RT_FAILURE(rc))
    891                 {
    892                     Log(("RTTcpRead failed with %Rrc\n", rc));
    893                     break;
    894                 }
    895                 pVM->ftm.s.StatReceivedMem.c += sizeof(Hdr);
    896 
    897                 if (Hdr.cb == 0)
    898                     break;  /* end of sync. */
    899 
    900                 Assert(Hdr.cb == Hdr.cbPageRange);  /** @todo uncompress */
    901 
    902                 /* Allocate memory to hold the page(s). */
    903                 pPage = RTMemAlloc(Hdr.cbPageRange);
    904                 AssertBreak(pPage);
    905 
    906                 /* Fetch the page(s). */
    907                 rc = RTTcpRead(pVM->ftm.s.hSocket, pPage, Hdr.cb, NULL);
    908                 if (RT_FAILURE(rc))
    909                 {
    910                     Log(("RTTcpRead page data (%d bytes) failed with %Rrc\n", Hdr.cb, rc));
    911                     break;
    912                 }
    913                 pVM->ftm.s.StatReceivedMem.c += Hdr.cb;
    914 
    915                 /* Update the guest memory of the standby VM. */
    916 #if 1
    917                 rc = PGMR3PhysWriteExternal(pVM, Hdr.GCPhys, pPage, Hdr.cbPageRange, "FTMemSync");
    918 #else
    919                 rc = PGMPhysWrite(pVM, Hdr.GCPhys, pPage, Hdr.cbPageRange);
    920 #endif
    921                 AssertRC(rc);
    922 
    923                 RTMemFree(pPage);
    924             }
     979            rc = ftmR3SyncMem(pVM);
     980            AssertRC(rc);
    925981
    926982            rc = ftmR3TcpWriteACK(pVM);
     
    936992            if (RT_FAILURE(rc))
    937993                continue;
     994
     995            /* Flush all pending memory updates. */
     996            if (pVM->ftm.s.standby.ppPhysPageTree)
     997            {
     998                RTAvloGCPhysDestroy(pVM->ftm.s.standby.ppPhysPageTree, ftmR3PageTreeDestroyCallback, pVM);
     999                pVM->ftm.s.standby.ppPhysPageTree = NULL;
     1000            }
    9381001
    9391002            RTSocketRetain(pVM->ftm.s.hSocket); /* For concurrent access by I/O thread and EMT. */
  • trunk/src/VBox/VMM/FTMInternal.h

    r32193 r32268  
    2424#include <VBox/stam.h>
    2525#include <VBox/pdmcritsect.h>
     26#include <iprt/avl.h>
    2627
    2728/** @defgroup grp_ftm_int Internals.
     
    3031 */
    3132
     33/** Physical page tree node. */
     34typedef struct FTMPHYSPAGETREENODE
     35{
     36    AVLOGCPHYSNODECORE  Core;
     37    void               *pPage;
     38} FTMPHYSPAGETREENODE;
     39/** Pointer to FTMPHYSPAGETREENODE */
     40typedef FTMPHYSPAGETREENODE *PFTMPHYSPAGETREENODE;
    3241
    3342/**
     
    7483    {
    7584        R3PTRTYPE(PRTTCPSERVER) hServer;
     85        PPAVLOGCPHYSNODECORE    ppPhysPageTree;
    7686    } standby;
    7787
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