diff options
Diffstat (limited to 'src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp')
| -rw-r--r-- | src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp | 94 |
1 files changed, 74 insertions, 20 deletions
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp index 07778cd70..794c19bf6 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2012 Oracle Corporation + * Copyright (C) 2012-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -41,6 +41,8 @@ using namespace guestControl; static uint32_t g_uControlIntervalMS = 0; /** The semaphore we're blocking our main control thread on. */ static RTSEMEVENTMULTI g_hControlEvent = NIL_RTSEMEVENTMULTI; +/** The VM session ID. Changes whenever the VM is restored or reset. */ +static uint64_t g_idControlSession; /** The guest control service client ID. */ static uint32_t g_uControlSvcClientID = 0; /** How many started guest processes are kept into memory for supplying @@ -69,17 +71,19 @@ static uint32_t g_uControlFileCount = 0; * Internal Functions * *******************************************************************************/ /** @todo Shorten "VBoxServiceControl" to "gstsvcCntl". */ -static int VBoxServiceControlReapThreads(void); -static int VBoxServiceControlStartAllowed(bool *pbAllowed); -static int VBoxServiceControlHandleCmdStartProc(uint32_t u32ClientId, uint32_t uNumParms); -static int VBoxServiceControlHandleCmdSetInput(uint32_t u32ClientId, uint32_t uNumParms, void *pvScratchBuf, size_t cbScratchBuf); -static int VBoxServiceControlHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNumParms); -static int VBoxServiceControlHandleFileOpen(uint32_t idClient, uint32_t cParms); -static int VBoxServiceControlHandleFileClose(uint32_t idClient, uint32_t cParms); -static int VBoxServiceControlHandleFileRead(uint32_t idClient, uint32_t cParms); -static int VBoxServiceControlHandleFileWrite(uint32_t idClient, uint32_t cParms, void *pvScratchBuf, size_t cbScratchBuf); -static int VBoxServiceControlHandleFileSeek(uint32_t idClient, uint32_t cParms); -static int VBoxServiceControlHandleFileTell(uint32_t idClient, uint32_t cParms); +static int VBoxServiceControlHandleCmdStartProc(uint32_t u32ClientId, uint32_t uNumParms); +static int VBoxServiceControlHandleCmdSetInput(uint32_t u32ClientId, uint32_t uNumParms, void *pvScratchBuf, size_t cbScratchBuf); +static int VBoxServiceControlHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNumParms); +static int VBoxServiceControlHandleFileOpen(uint32_t idClient, uint32_t cParms); +static int VBoxServiceControlHandleFileClose(uint32_t idClient, uint32_t cParms); +static int VBoxServiceControlHandleFileRead(uint32_t idClient, uint32_t cParms); +static int VBoxServiceControlHandleFileWrite(uint32_t idClient, uint32_t cParms, void *pvScratchBuf, size_t cbScratchBuf); +static int VBoxServiceControlHandleFileSeek(uint32_t idClient, uint32_t cParms); +static int VBoxServiceControlHandleFileTell(uint32_t idClient, uint32_t cParms); +static int VBoxServiceControlReapThreads(void); +static void VBoxServiceControlShutdown(void); +static int vboxServiceControlSessionCloseAll(void); +static int VBoxServiceControlStartAllowed(bool *pbAllowed); #ifdef DEBUG static int vboxServiceControlDump(const char *pszFileName, void *pvBuf, size_t cbBuf) @@ -193,6 +197,9 @@ static DECLCALLBACK(int) VBoxServiceControlInit(void) int rc = RTSemEventMultiCreate(&g_hControlEvent); AssertRCReturn(rc, rc); + VbglR3GetSessionId(&g_idControlSession); + /* The status code is ignored as this information is not available with VBox < 3.2.10. */ + rc = VbglR3GuestCtrlConnect(&g_uControlSvcClientID); if (RT_SUCCESS(rc)) { @@ -265,10 +272,25 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown) if (RT_SUCCESS(rc)) { VBoxServiceVerbose(3, "Msg=%u (%u parms) retrieved\n", uMsg, cParms); + + uint64_t idNewSession = g_idControlSession; + int rc2 = VbglR3GetSessionId(&idNewSession); + if ( RT_SUCCESS(rc2) + && (idNewSession != g_idControlSession)) + { + VBoxServiceVerbose(1, "The VM session ID changed\n"); + g_idControlSession = idNewSession; + + /* Close all opened guest sessions -- all context IDs, sessions etc. + * are now invalid. */ + rc2 = vboxServiceControlSessionCloseAll(); + AssertRC(rc2); + } + switch (uMsg) { case HOST_CANCEL_PENDING_WAITS: - VBoxServiceVerbose(3, "Host asked us to quit ...\n"); + VBoxServiceVerbose(1, "We were asked to quit ...\n"); break; case HOST_EXEC_CMD: @@ -320,7 +342,6 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown) if ( *pfShutdown || (RT_SUCCESS(rc) && uMsg == HOST_CANCEL_PENDING_WAITS)) { - rc = VINF_SUCCESS; break; } @@ -328,6 +349,8 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown) RTThreadYield(); } + VBoxServiceVerbose(0, "Guest control service stopped\n"); + /* Delete scratch buffer. */ if (pvScratchBuf) RTMemFree(pvScratchBuf); @@ -1033,11 +1056,14 @@ static int VBoxServiceControlReapThreads(void) /** - * Destroys all guest process threads which are still active. + * Closes a formerly opened guest session. + * + * @return IPRT status code. + * @param uSessionID Guest session to close. */ -static void VBoxServiceControlShutdown(void) +static int vboxServiceControlSessionClose(uint32_t uSessionID) { - VBoxServiceVerbose(2, "Shutting down ...\n"); + /* Note: Sessions are not implemented yet, so just shutdown all started guest processes. */ /* Signal all threads in the active list that we want to shutdown. */ PVBOXSERVICECTRLTHREAD pThread; @@ -1055,7 +1081,10 @@ static void VBoxServiceControlShutdown(void) 30 * 1000 /* Wait 30 seconds max. */, NULL /* rc */); if (RT_FAILURE(rc2)) + { VBoxServiceError("Guest process thread failed to stop; rc=%Rrc\n", rc2); + /* Keep going. */ + } if (fLast) break; @@ -1063,15 +1092,40 @@ static void VBoxServiceControlShutdown(void) pThread = pNext; } - int rc2 = VBoxServiceControlReapThreads(); - if (RT_FAILURE(rc2)) - VBoxServiceError("Reaping inactive threads failed with rc=%Rrc\n", rc2); + int rc = VBoxServiceControlReapThreads(); + if (RT_FAILURE(rc)) + VBoxServiceError("Reaping inactive threads failed with rc=%Rrc\n", rc); AssertMsg(RTListIsEmpty(&g_lstControlThreadsActive), ("Guest process active thread list still contains entries when it should not\n")); AssertMsg(RTListIsEmpty(&g_lstControlThreadsInactive), ("Guest process inactive thread list still contains entries when it should not\n")); + return rc; +} + + +/** + * Closes (shuts down) all opened guest sessions. + * + * @return IPRT status code. + */ +static int vboxServiceControlSessionCloseAll(void) +{ + return vboxServiceControlSessionClose(0 /* Session ID, not used yet */); +} + + +/** + * Destroys all guest process threads which are still active. + */ +static void VBoxServiceControlShutdown(void) +{ + VBoxServiceVerbose(2, "Shutting down ...\n"); + + int rc2 = vboxServiceControlSessionCloseAll(); + AssertRC(rc2); + /* Destroy critical section. */ RTCritSectDelete(&g_csControlThreads); |
