- Timestamp:
- Sep 7, 2010 9:40:47 AM (14 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/FTM.cpp
r32245 r32268 92 92 *******************************************************************************/ 93 93 static const char g_szWelcome[] = "VirtualBox-Fault-Tolerance-Sync-1.0\n"; 94 95 static DECLCALLBACK(int) ftmR3PageTreeDestroyCallback(PAVLOGCPHYSNODECORE pBaseNode, void *pvUser); 94 96 95 97 /** … … 171 173 RTMemFree(pVM->ftm.s.pszPassword); 172 174 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 173 182 pVM->ftm.s.pszAddress = NULL; 174 183 pVM->ftm.s.pszPassword = NULL; … … 797 806 798 807 /** 808 * Syncs memory from the master VM 809 * 810 * @returns VBox status code. 811 * @param pVM VM Handle. 812 */ 813 static 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 */ 878 static 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 /** 799 895 * Listen for incoming traffic destined for the standby VM. 800 896 * … … 881 977 continue; 882 978 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); 925 981 926 982 rc = ftmR3TcpWriteACK(pVM); … … 936 992 if (RT_FAILURE(rc)) 937 993 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 } 938 1001 939 1002 RTSocketRetain(pVM->ftm.s.hSocket); /* For concurrent access by I/O thread and EMT. */ -
trunk/src/VBox/VMM/FTMInternal.h
r32193 r32268 24 24 #include <VBox/stam.h> 25 25 #include <VBox/pdmcritsect.h> 26 #include <iprt/avl.h> 26 27 27 28 /** @defgroup grp_ftm_int Internals. … … 30 31 */ 31 32 33 /** Physical page tree node. */ 34 typedef struct FTMPHYSPAGETREENODE 35 { 36 AVLOGCPHYSNODECORE Core; 37 void *pPage; 38 } FTMPHYSPAGETREENODE; 39 /** Pointer to FTMPHYSPAGETREENODE */ 40 typedef FTMPHYSPAGETREENODE *PFTMPHYSPAGETREENODE; 32 41 33 42 /** … … 74 83 { 75 84 R3PTRTYPE(PRTTCPSERVER) hServer; 85 PPAVLOGCPHYSNODECORE ppPhysPageTree; 76 86 } standby; 77 87
Note:
See TracChangeset
for help on using the changeset viewer.