ConsoleImpl-LiveMigration.cpp revision bc0a19dc73b33c7e92288cc85eab1a5c1d459f3f
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * VBox Console COM Class implementation, The Live Migration Part.
af84459fbf938e508fd10b01cb8d699c79083813takashi * Copyright (C) 2009 Sun Microsystems, Inc.
af84459fbf938e508fd10b01cb8d699c79083813takashi * This file is part of VirtualBox Open Source Edition (OSE), as
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc * available from http://www.virtualbox.org. This file is free software;
af84459fbf938e508fd10b01cb8d699c79083813takashi * you can redistribute it and/or modify it under the terms of the GNU
af84459fbf938e508fd10b01cb8d699c79083813takashi * General Public License (GPL) as published by the Free Software
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * Foundation, in version 2 as it comes in the "COPYING" file of the
2e545ce2450a9953665f701bb05350f0d3f26275nd * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
af84459fbf938e508fd10b01cb8d699c79083813takashi * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
af84459fbf938e508fd10b01cb8d699c79083813takashi * Clara, CA 95054 USA or visit http://www.sun.com if you need
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * additional information or have any questions.
af84459fbf938e508fd10b01cb8d699c79083813takashi/*******************************************************************************
af84459fbf938e508fd10b01cb8d699c79083813takashi* Header Files *
3f08db06526d6901aa08c110b5bc7dde6bc39905nd*******************************************************************************/
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe/*******************************************************************************
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe* Structures and Typedefs *
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe*******************************************************************************/
fed47023e9be04c612b5f6d4a5ee2b8e7c587181rbowen * Argument package for Console::migrationServeConnection.
af84459fbf938e508fd10b01cb8d699c79083813takashi/*******************************************************************************
af84459fbf938e508fd10b01cb8d699c79083813takashi* Global Variables *
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe*******************************************************************************/
af84459fbf938e508fd10b01cb8d699c79083813takashistatic const char g_szWelcome[] = "VirtualBox-LiveMigration-1.0\n";
af84459fbf938e508fd10b01cb8d699c79083813takashi * @copydoc FNRTTIMERLR
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowestatic DECLCALLBACK(void) migrationTimeout(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick)
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe /* This is harmless for any open connections. */
cd34a6fbf0a2619544a72eadb73f309370bf6682wroweConsole::Migrate(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, IProgress **aProgress)
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe * Creates a TCP server that listens for the source machine and passes control
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe * over to Console::migrationServeConnection().
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe * @returns VBox status code.
fed47023e9be04c612b5f6d4a5ee2b8e7c587181rbowen * @param pVM The VM handle
fed47023e9be04c612b5f6d4a5ee2b8e7c587181rbowen * @param pMachine The IMachine for the virtual machine.
cd34a6fbf0a2619544a72eadb73f309370bf6682wroweConsole::migrationLoadRemote(PVM pVM, IMachine *pMachine)
4bebf996eb7002ebfe897d46a0e0572390604a77nd * Get the config.
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe HRESULT hrc = pMachine->COMGETTER(LiveMigrationPort)(&uPort);
af84459fbf938e508fd10b01cb8d699c79083813takashi hrc = pMachine->COMGETTER(LiveMigrationPassword)(bstrPassword.asOutParam());
af84459fbf938e508fd10b01cb8d699c79083813takashi strPassword.append('\n'); /* always ends with a newline. */
fed47023e9be04c612b5f6d4a5ee2b8e7c587181rbowen /** @todo Add a bind address property. */
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe const char *pszBindAddress = strBind.isEmpty() ? NULL : strBind.c_str();
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe * Create the TCP server.
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe rc = RTTcpServerCreateEx(pszBindAddress, uPort, &hServer);
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe uPort = RTRandU32Ex(cTries >= 8192 ? 49152 : 1024, 65534);
57c845e03570b3641fbf41d4f139e2a9b49e406and rc = RTTcpServerCreateEx(pszBindAddress, uPort, &hServer);
4b311579b2c8aebac85fb7cb8ac89e6c37b4bc1asf HRESULT hrc = pMachine->COMSETTER(LiveMigrationPort)(uPort);
fed47023e9be04c612b5f6d4a5ee2b8e7c587181rbowen * Create a timer for timing out after 5 mins.
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe rc = RTTimerLRCreateEx(&hTimer, 0, 0, migrationTimeout, hServer);
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe rc = RTTimerLRStart(hTimer, 5*60*UINT64_C(1000000000) /*ns*/);
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe * Do the job, when it returns we're done.
888cb40bdeec5abf452bd85d6bf63b26d5913d4chumbedooh rc = RTTcpServerListen(hServer, Console::migrationServeConnection, &Args);
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe * Reads a string from the socket.
888cb40bdeec5abf452bd85d6bf63b26d5913d4chumbedooh * @returns VBox status code.
888cb40bdeec5abf452bd85d6bf63b26d5913d4chumbedooh * @param Sock The socket.
20f499565e77defe9dab24dd85c02f38a1175855nd * @param pszBuf The output buffer.
888cb40bdeec5abf452bd85d6bf63b26d5913d4chumbedooh * @param cchBuf The size of the output buffer.
af84459fbf938e508fd10b01cb8d699c79083813takashistatic int migrationReadLine(RTSOCKET Sock, char *pszBuf, size_t cchBuf)
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe /* dead simple (stupid) approach. */
b7f8d802ecaed65eada1fc31472d06d8460d5528igalic LogRel(("Migration: RTTcpRead -> %Rrc while reading string ('%s')\n", rc, pszStart));
7c7e501f542451bf7225b23cb299ee4228bfe15dgryzor LogRel(("Migration: String buffer overflow: '%s'\n", pszStart));
7c7e501f542451bf7225b23cb299ee4228bfe15dgryzor * @copydoc FNRTTCPSERVE
4bebf996eb7002ebfe897d46a0e0572390604a77nd * VERR_TCP_SERVER_STOP
8559a67073808d84d85bb5dd552d4247caafe709sfConsole::migrationServeConnection(RTSOCKET Sock, void *pvUser)
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe PMIGRATIONSERVEARGS pArgs = (PMIGRATIONSERVEARGS)pvUser;
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe * Say hello.
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe int rc = RTTcpWrite(Sock, g_szWelcome, sizeof(g_szWelcome) - 1);
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe LogRel(("Migration: Failed to write welcome message: %Rrc\n", rc));
fed47023e9be04c612b5f6d4a5ee2b8e7c587181rbowen * Password (includes '\n', see migrationLoadRemote). If it's right, tell
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe * the TCP server to stop listening (frees up host resources and makes sure
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe * this is the last connection attempt).
cd34a6fbf0a2619544a72eadb73f309370bf6682wrowe unsigned off = 0;
253547fb9cc7986e84ff68aef076f664fc4169dctakashi LogRel(("Migration: Invalid password (off=%u)\n", off));
8559a67073808d84d85bb5dd552d4247caafe709sf * Command processing loop.
8559a67073808d84d85bb5dd552d4247caafe709sf /* restore the state. */