diff options
Diffstat (limited to 'src/VBox/Additions')
18 files changed, 520 insertions, 244 deletions
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp index d84cbdd85..4540dc16a 100644 --- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp +++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxGuest.cpp 29250 2010-05-09 17:53:58Z vboxsync $ */ +/* $Id: VBoxGuest.cpp 29625 2010-05-18 12:40:24Z vboxsync $ */ /** @file * VBoxGuest - Guest Additions Driver, Common Code. */ @@ -245,10 +245,8 @@ static int vboxGuestSetFilterMask(PVBOXGUESTDEVEXT pDevExt, uint32_t fMask) pReq->u32OrMask = fMask; pReq->u32NotMask = ~fMask; rc = VbglGRPerform(&pReq->header); - if ( RT_FAILURE(rc) - || RT_FAILURE(pReq->header.rc)) - LogRel(("vboxGuestSetFilterMask: failed with rc=%Rrc and VMMDev rc=%Rrc\n", - rc, pReq->header.rc)); + if (RT_FAILURE(rc)) + LogRel(("vboxGuestSetFilterMask: failed with rc=%Rrc\n", rc)); VbglGRFree(&pReq->header); } return rc; @@ -271,10 +269,8 @@ static int vboxGuestInitReportGuestInfo(PVBOXGUESTDEVEXT pDevExt, VBOXOSTYPE enm pReq->guestInfo.additionsVersion = VMMDEV_VERSION; pReq->guestInfo.osType = enmOSType; rc = VbglGRPerform(&pReq->header); - if ( RT_FAILURE(rc) - || RT_FAILURE(pReq->header.rc)) - LogRel(("vboxGuestInitReportGuestInfo: failed with rc=%Rrc and VMMDev rc=%Rrc\n", - rc, pReq->header.rc)); + if (RT_FAILURE(rc)) + LogRel(("vboxGuestInitReportGuestInfo: 1st part failed with rc=%Rrc\n", rc)); VbglGRFree(&pReq->header); } VMMDevReportGuestInfo2 *pReq2; @@ -291,10 +287,8 @@ static int vboxGuestInitReportGuestInfo(PVBOXGUESTDEVEXT pDevExt, VBOXOSTYPE enm rc = VbglGRPerform(&pReq2->header); if (rc == VERR_NOT_IMPLEMENTED) /* compatibility with older hosts */ rc = VINF_SUCCESS; - if ( RT_FAILURE(rc) - || RT_FAILURE(pReq2->header.rc)) - LogRel(("vboxGuestInitReportGuestInfo2: failed with rc=%Rrc and VMMDev rc=%Rrc\n", - rc, pReq2->header.rc)); + if (RT_FAILURE(rc)) + LogRel(("vboxGuestInitReportGuestInfo: 2nd part failed with rc=%Rrc\n", rc)); VbglGRFree(&pReq2->header); } return rc; @@ -1146,12 +1140,7 @@ int VBoxGuestSetGuestCapabilities(uint32_t fOr, uint32_t fNot) rc = VbglGRPerform(&pReq->header); if (RT_FAILURE(rc)) - Log(("VBoxGuestSetGuestCapabilities:VbglGRPerform failed, rc=%Rrc!\n", rc)); - else if (RT_FAILURE(pReq->header.rc)) - { - Log(("VBoxGuestSetGuestCapabilities: The request failed; VMMDev rc=%Rrc!\n", pReq->header.rc)); - rc = pReq->header.rc; - } + Log(("VBoxGuestSetGuestCapabilities: VbglGRPerform failed, rc=%Rrc!\n", rc)); VbglGRFree(&pReq->header); return rc; @@ -1495,11 +1484,6 @@ static int VBoxGuestCommonIOCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt, VBoxGues rc = VbglGRPerform(&pReq->header); if (RT_FAILURE(rc)) Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK: VbglGRPerform failed, rc=%Rrc!\n", rc)); - else if (RT_FAILURE(pReq->header.rc)) - { - Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK: The request failed; VMMDev rc=%Rrc!\n", pReq->header.rc)); - rc = pReq->header.rc; - } VbglGRFree(&pReq->header); return rc; diff --git a/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk b/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk index 60b68f9d3..593e106f9 100644 --- a/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk +++ b/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk @@ -1,4 +1,4 @@ -# $Id: Makefile.kmk 28800 2010-04-27 08:22:32Z vboxsync $ +# $Id: Makefile.kmk 29535 2010-05-17 11:57:06Z vboxsync $ ## @file # Sub-Makefile for the common guest addition code library. # @@ -88,9 +88,6 @@ VBoxGuestR3Lib_DEFS = \ VBOX_WITH_HGCM \ $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) \ $(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL,) -ifdef VBOX_WITH_PAGE_SHARING - VBoxGuestR3Lib_DEFS += VBOX_WITH_PAGE_SHARING -endif VBoxGuestR3Lib_SOURCES = \ VBoxGuestR3Lib.cpp \ VBoxGuestR3LibAdditions.cpp \ @@ -103,7 +100,8 @@ VBoxGuestR3Lib_SOURCES = \ VBoxGuestR3LibLog.cpp \ VBoxGuestR3LibMisc.cpp \ VBoxGuestR3LibStat.cpp \ - VBoxGuestR3LibTime.cpp + VBoxGuestR3LibTime.cpp \ + VBoxGuestR3LibModule.cpp ifneq ($(KBUILD_TARGET),win) ## @todo get rid of this hack (as soon as it's all implemented / #defined). VBoxGuestR3Lib_SOURCES += \ VBoxGuestR3LibDaemonize.cpp \ @@ -120,10 +118,6 @@ ifdef VBOX_WITH_GUEST_CONTROL VBoxGuestR3Lib_SOURCES += \ VBoxGuestR3LibGuestCtrl.cpp endif -ifdef VBOX_WITH_PAGE_SHARING - VBoxGuestR3Lib_SOURCES += \ - VBoxGuestR3LibModule.cpp -endif VBoxGuestR3LibAdditions.cpp_DEFS = VBOX_SVN_REV=$(VBOX_SVN_REV) diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp index f196ffb90..b81791d2d 100644 --- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp +++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxGuestR3LibGuestCtrl.cpp 28887 2010-04-29 11:19:17Z vboxsync $ */ +/* $Id: VBoxGuestR3LibGuestCtrl.cpp 29516 2010-05-17 09:55:17Z vboxsync $ */ /** @file * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, guest control. */ @@ -102,7 +102,7 @@ VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t u32ClientId) * @param puNumParms Where to store the number of parameters which will be received * in a second call to the host. */ -VBGLR3DECL(int) VbglR3GuestCtrlGetHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms, uint32_t u32Timeout) +VBGLR3DECL(int) VbglR3GuestCtrlGetHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms) { AssertPtr(puMsg); AssertPtr(puNumParms); @@ -132,6 +132,32 @@ VBGLR3DECL(int) VbglR3GuestCtrlGetHostMsg(uint32_t u32ClientId, uint32_t *puMsg, /** + * Asks the host to cancel (release) all pending waits which were deferred. + * + * @returns VBox status code. + * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect(). + */ +VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId) +{ + VBoxGuestCtrlHGCMMsgCancelPendingWaits Msg; + + Msg.hdr.result = VERR_WRONG_ORDER; + Msg.hdr.u32ClientID = u32ClientId; + Msg.hdr.u32Function = GUEST_CANCEL_PENDING_WAITS; + Msg.hdr.cParms = 0; + + int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); + if (RT_SUCCESS(rc)) + { + int rc2 = Msg.hdr.result; + if (RT_FAILURE(rc2)) + rc = rc2; + } + return rc; +} + + +/** * Allocates and gets host data, based on the message id. * * This will block until data becomes available. @@ -147,9 +173,6 @@ VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmd(uint32_t u32ClientId, uint32_t uint32_t *puFlags, char *pszArgs, uint32_t cbArgs, uint32_t *puNumArgs, char *pszEnv, uint32_t *pcbEnv, uint32_t *puNumEnvVars, - char *pszStdIn, uint32_t cbStdIn, - char *pszStdOut, uint32_t cbStdOut, - char *pszStdErr, uint32_t cbStdErr, char *pszUser, uint32_t cbUser, char *pszPassword, uint32_t cbPassword, uint32_t *puTimeLimit) @@ -162,10 +185,6 @@ VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmd(uint32_t u32ClientId, uint32_t AssertPtr(pszEnv); AssertPtr(pcbEnv); AssertPtr(puNumEnvVars); - AssertPtr(pszStdIn); - AssertPtr(pszStdOut); - AssertPtr(pszStdOut); - AssertPtr(pszStdErr); AssertPtr(pszUser); AssertPtr(pszPassword); AssertPtr(puTimeLimit); @@ -185,9 +204,6 @@ VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmd(uint32_t u32ClientId, uint32_t VbglHGCMParmUInt32Set(&Msg.num_env, 0); VbglHGCMParmUInt32Set(&Msg.cb_env, 0); VbglHGCMParmPtrSet(&Msg.env, pszEnv, *pcbEnv); - VbglHGCMParmPtrSet(&Msg.std_in, pszStdIn, cbStdIn); - VbglHGCMParmPtrSet(&Msg.std_out, pszStdOut, cbStdOut); - VbglHGCMParmPtrSet(&Msg.std_err, pszStdErr, cbStdErr); VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser); VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword); VbglHGCMParmUInt32Set(&Msg.timeout, 0); diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibModule.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibModule.cpp index de324ed11..9482c4081 100644 --- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibModule.cpp +++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibModule.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxGuestR3LibModule.cpp 29395 2010-05-12 07:33:28Z vboxsync $ */ +/* $Id: VBoxGuestR3LibModule.cpp 29538 2010-05-17 12:07:00Z vboxsync $ */ /** @file * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Shared modules. */ @@ -69,7 +69,7 @@ VBGLR3DECL(int) VbglR3RegisterSharedModule(char *pszModuleName, char *pszVersion # endif #else /** todo */ - pReq->enmGuestOS = VBOXOSFAMILY_unknown; + pReq->enmGuestOS = VBOXOSFAMILY_Unknown; #endif for (unsigned i = 0; i < cRegions; i++) pReq->aRegions[i] = pRegions[i]; diff --git a/src/VBox/Additions/common/VBoxService/Makefile.kmk b/src/VBox/Additions/common/VBoxService/Makefile.kmk index 197c194bb..e2dfee32a 100644 --- a/src/VBox/Additions/common/VBoxService/Makefile.kmk +++ b/src/VBox/Additions/common/VBoxService/Makefile.kmk @@ -1,4 +1,4 @@ -# $Id: Makefile.kmk 29313 2010-05-11 07:08:01Z vboxsync $ +# $Id: Makefile.kmk 29583 2010-05-17 19:41:27Z vboxsync $ ## @file # Sub-Makefile for the Cross Platform Guest Addition Services. # @@ -43,7 +43,7 @@ endif ifdef VBOX_WITH_MEMBALLOON VBoxService_DEFS += VBOX_WITH_MEMBALLOON endif -ifdef VBOX_WITH_PAGE_SHARING +if1of ($(KBUILD_TARGET), win) VBoxService_DEFS += VBOX_WITH_PAGE_SHARING endif if1of ($(KBUILD_TARGET), linux) @@ -64,7 +64,7 @@ ifdef VBOX_WITH_MEMBALLOON VBoxService_SOURCES += \ VBoxServiceBalloon.cpp endif -ifdef VBOX_WITH_PAGE_SHARING +if1of ($(KBUILD_TARGET), win) VBoxService_SOURCES += \ VBoxServicePageSharing.cpp endif @@ -91,6 +91,10 @@ VBoxService_LIBS = \ $(VBOX_LIB_IPRT_GUEST_R3) \ $(VBOX_LIB_VBGL_R3) \ $(VBOX_LIB_IPRT_GUEST_R3) +if1of ($(KBUILD_TARGET), linux) + VBoxService_LIBS += \ + crypt +endif ifdef VBOX_WITH_GUEST_PROPS VBoxService_LIBS.win += \ Secur32.lib \ diff --git a/src/VBox/Additions/common/VBoxService/VBoxService.cpp b/src/VBox/Additions/common/VBoxService/VBoxService.cpp index 894c75944..cf696b2c8 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxService.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxService.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxService.cpp 29345 2010-05-11 12:22:48Z vboxsync $ */ +/* $Id: VBoxService.cpp 29647 2010-05-18 15:59:51Z vboxsync $ */ /** @file * VBoxService - Guest Additions Service Skeleton. */ @@ -109,31 +109,33 @@ static struct */ static int VBoxServiceUsage(void) { - RTPrintf("usage: %s [-f|--foreground] [-v|--verbose] [-i|--interval <seconds>]\n" - " [--disable-<service>] [--enable-<service>] [-h|-?|--help]\n", g_pszProgName); + RTPrintf("Usage:\n" + " %-12s [-f|--foreground] [-v|--verbose] [-i|--interval <seconds>]\n" + " [--disable-<service>] [--enable-<service>] [-h|-?|--help]\n", g_pszProgName); #ifdef RT_OS_WINDOWS - RTPrintf(" [-r|--register] [-u|--unregister]\n"); + RTPrintf(" [-r|--register] [-u|--unregister]\n"); #endif for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) - RTPrintf(" %s\n", g_aServices[j].pDesc->pszUsage); + if (g_aServices[j].pDesc->pszUsage) + RTPrintf("%s\n", g_aServices[j].pDesc->pszUsage); RTPrintf("\n" "Options:\n" - " -i | --interval The default interval.\n" - " -f | --foreground Don't daemonzie the program. For debugging.\n" - " -v | --verbose Increment the verbosity level. For debugging.\n" - " -h | -? | --help Show this message and exit with status 1.\n" + " -i | --interval The default interval.\n" + " -f | --foreground Don't daemonzie the program. For debugging.\n" + " -v | --verbose Increment the verbosity level. For debugging.\n" + " -h | -? | --help Show this message and exit with status 1.\n" ); #ifdef RT_OS_WINDOWS - RTPrintf(" -r | --register Installs the service.\n" - " -u | --unregister Uninstall service.\n"); + RTPrintf(" -r | --register Installs the service.\n" + " -u | --unregister Uninstall service.\n"); #endif RTPrintf("\n" - "Service specific options:\n"); + "Service-specific options:\n"); for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) { - RTPrintf(" --enable-%-10s Enables the %s service. (default)\n", g_aServices[j].pDesc->pszName, g_aServices[j].pDesc->pszName); - RTPrintf(" --disable-%-9s Disables the %s service.\n", g_aServices[j].pDesc->pszName, g_aServices[j].pDesc->pszName); + RTPrintf(" --enable-%-14s Enables the %s service. (default)\n", g_aServices[j].pDesc->pszName, g_aServices[j].pDesc->pszName); + RTPrintf(" --disable-%-13s Disables the %s service.\n", g_aServices[j].pDesc->pszName, g_aServices[j].pDesc->pszName); if (g_aServices[j].pDesc->pszOptions) RTPrintf("%s", g_aServices[j].pDesc->pszOptions); } @@ -357,10 +359,11 @@ int VBoxServiceStartServices(unsigned iMain) /* The final service runs in the main thread. */ VBoxServiceVerbose(1, "Starting '%s' in the main thread\n", g_aServices[iMain].pDesc->pszName); rc = g_aServices[iMain].pDesc->pfnWorker(&g_fShutdown); - if (rc != VINF_SUCCESS) /* Only complain if service returned an error. Otherwise the service is a one-timer. */ - { + if (RT_SUCCESS(rc)) + VBoxServiceVerbose(1, "Main service '%s' successfully stopped.\n", g_aServices[iMain].pDesc->pszName); + else /* Only complain if service returned an error. Otherwise the service is a one-timer. */ VBoxServiceError("Service '%s' stopped unexpected; rc=%Rrc\n", g_aServices[iMain].pDesc->pszName, rc); - } + g_aServices[iMain].pDesc->pfnTerm(); } return rc; } @@ -375,14 +378,24 @@ int VBoxServiceStartServices(unsigned iMain) int VBoxServiceStopServices(void) { int rc = VINF_SUCCESS; + unsigned iMain = VBoxServiceGetStartedServices(); for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) ASMAtomicXchgBool(&g_aServices[j].fShutdown, true); for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) if (g_aServices[j].fStarted) + { + VBoxServiceVerbose(3, "Calling stop function for service '%s' ...\n", g_aServices[j].pDesc->pszName); g_aServices[j].pDesc->pfnStop(); + } for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) - if (g_aServices[j].fEnabled) + + if ( !g_aServices[j].fEnabled /* Only stop services which were started before. */ + || j == iMain) /* Don't call the termination function for main service yet. */ + { + continue; + } + else { if (g_aServices[j].Thread != NIL_RTTHREAD) { @@ -404,10 +417,27 @@ int VBoxServiceStopServices(void) g_aServices[j].pDesc->pfnTerm(); } +#ifdef RT_OS_WINDOWS + /* + * As we're now done terminating all service threads, + * we have to stop the main thread as well (if defined). Note that the termination + * function will be called in a later context (when the main thread returns from the worker + * function). + */ + if (iMain != ~0U) + { + VBoxServiceVerbose(3, "Stopping main service '%s' (%d) ...\n", g_aServices[iMain].pDesc->pszName, iMain); + + ASMAtomicXchgBool(&g_fShutdown, true); + g_aServices[iMain].pDesc->pfnStop(); + } +#endif + VBoxServiceVerbose(2, "Stopping services returned: rc=%Rrc\n", rc); return rc; } + #ifndef RT_OS_WINDOWS /* * Block all important signals, then explicitly wait until one of these signal arrives. @@ -423,29 +453,17 @@ static void VBoxServiceWaitSignal(void) sigaddset(&signalMask, SIGABRT); sigaddset(&signalMask, SIGTERM); pthread_sigmask(SIG_BLOCK, &signalMask, NULL); - sigwait(&signalMask, &iSignal); - VBoxServiceVerbose(3, "VBoxServiceWaitSignal: Received signal %d\n", iSignal); -} -#endif + int rc; + do + { + iSignal = -1; + rc = sigwait(&signalMask, &iSignal); + } + while ( rc == EINTR + || rc == ERESTART); -#ifndef RT_OS_WINDOWS -/* - * Block all important signals, then explicitly wait until one of these signal arrives. - */ -static void VBoxServiceWaitSignal(void) -{ - sigset_t signalMask; - int iSignal; - sigemptyset(&signalMask); - sigaddset(&signalMask, SIGHUP); - sigaddset(&signalMask, SIGINT); - sigaddset(&signalMask, SIGQUIT); - sigaddset(&signalMask, SIGABRT); - sigaddset(&signalMask, SIGTERM); - pthread_sigmask(SIG_BLOCK, &signalMask, NULL); - sigwait(&signalMask, &iSignal); - VBoxServiceVerbose(3, "VBoxServiceWaitSignal: Received signal %d\n", iSignal); + VBoxServiceVerbose(3, "VBoxServiceWaitSignal: Received signal %d (rc=%d)\n", iSignal, rc); } #endif /* !RT_OS_WINDOWS */ diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp index 6d5e9ad2d..e28434dd3 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxServiceBalloon.cpp 29345 2010-05-11 12:22:48Z vboxsync $ */ +/* $Id: VBoxServiceBalloon.cpp 29543 2010-05-17 14:01:31Z vboxsync $ */ /** @file * VBoxService - Memory Ballooning. */ @@ -62,9 +62,12 @@ static bool g_fSysMadviseWorks; static void VBoxServiceBalloonInitMadvise(void) { #ifdef RT_OS_LINUX - void *pv = RTMemPageAlloc(PAGE_SIZE); - g_fSysMadviseWorks = madvise(pv, PAGE_SIZE, MADV_DONTFORK) == 0; - RTMemPageFree(pv, PAGE_SIZE); + void *pv = (void*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (pv != MAP_FAILED) + { + g_fSysMadviseWorks = madvise(pv, PAGE_SIZE, MADV_DONTFORK) == 0; + munmap(pv, PAGE_SIZE); + } #endif } diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp index 3fb181266..bcb447101 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxServiceControl.cpp 29345 2010-05-11 12:22:48Z vboxsync $ */ +/* $Id: VBoxServiceControl.cpp 29594 2010-05-18 07:45:58Z vboxsync $ */ /** @file * VBoxServiceControl - Host-driven Guest Control. */ @@ -114,14 +114,11 @@ static int VBoxServiceControlHandleCmdStartProcess(uint32_t u32ClientId, uint32_ char szEnv[_64K]; uint32_t cbEnv = sizeof(szEnv); uint32_t uNumEnvVars; - char szStdIn[_1K]; - char szStdOut[_1K]; - char szStdErr[_1K]; char szUser[128]; char szPassword[128]; uint32_t uTimeLimitMS; - if (uNumParms != 14) + if (uNumParms != 11) return VERR_INVALID_PARAMETER; int rc = VbglR3GuestCtrlExecGetHostCmd(u32ClientId, @@ -135,10 +132,6 @@ static int VBoxServiceControlHandleCmdStartProcess(uint32_t u32ClientId, uint32_ szArgs, sizeof(szArgs), &uNumArgs, /* Environment */ szEnv, &cbEnv, &uNumEnvVars, - /* Pipes */ - szStdIn, sizeof(szStdIn), - szStdOut, sizeof(szStdOut), - szStdErr, sizeof(szStdErr), /* Credentials */ szUser, sizeof(szUser), szPassword, sizeof(szPassword), @@ -152,7 +145,6 @@ static int VBoxServiceControlHandleCmdStartProcess(uint32_t u32ClientId, uint32_ { rc = VBoxServiceControlExecProcess(uContextID, szCmd, uFlags, szArgs, uNumArgs, szEnv, cbEnv, uNumEnvVars, - szStdIn, szStdOut, szStdErr, szUser, szPassword, uTimeLimitMS); } @@ -178,7 +170,7 @@ static int VBoxServiceControlHandleCmdGetOutput(uint32_t u32ClientId, uint32_t u { /* Let's have a look if we have a running process with PID = uPID ... */ PVBOXSERVICECTRLTHREAD pNode; - bool bFound = false; + bool fFound = false; RTListForEach(&g_GuestControlExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node) { if ( pNode->fStarted @@ -187,18 +179,18 @@ static int VBoxServiceControlHandleCmdGetOutput(uint32_t u32ClientId, uint32_t u PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData; if (pData && pData->uPID == uPID) { - bFound = true; + fFound = true; break; } } } - if (bFound) + if (fFound) { PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData; AssertPtr(pData); - uint32_t cbSize = _4K; + const uint32_t cbSize = _4K; uint32_t cbRead = cbSize; uint8_t *pBuf = (uint8_t*)RTMemAlloc(cbSize); if (pBuf) @@ -206,7 +198,6 @@ static int VBoxServiceControlHandleCmdGetOutput(uint32_t u32ClientId, uint32_t u rc = VBoxServiceControlExecReadPipeBufferContent(&pData->stdOut, pBuf, cbSize, &cbRead); if (RT_SUCCESS(rc)) { - AssertPtr(pBuf); /* cbRead now contains actual size. */ rc = VbglR3GuestCtrlExecSendOut(u32ClientId, uContextID, uPID, 0 /* handle ID */, 0 /* flags */, pBuf, cbRead); @@ -246,12 +237,12 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown) uint32_t uMsg; uint32_t uNumParms; VBoxServiceVerbose(3, "Control: Waiting for host msg ...\n"); - rc = VbglR3GuestCtrlGetHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms, 1000 /* 1s timeout */); + rc = VbglR3GuestCtrlGetHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms); if (RT_FAILURE(rc)) { if (rc == VERR_TOO_MUCH_DATA) { - VBoxServiceVerbose(3, "Control: Message requires %ld parameters, but only 2 supplied -- retrying request ...\n", uNumParms); + VBoxServiceVerbose(4, "Control: Message requires %ld parameters, but only 2 supplied -- retrying request (no error!)...\n", uNumParms); rc = VINF_SUCCESS; /* Try to get "real" message in next block below. */ } else @@ -263,6 +254,10 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown) VBoxServiceVerbose(3, "Control: Msg=%u (%u parms) retrieved\n", uMsg, uNumParms); switch(uMsg) { + case GETHOSTMSG_EXEC_HOST_CANCEL_WAIT: + VBoxServiceVerbose(3, "Control: Host asked us to quit ...\n"); + break; + case GETHOSTMSG_EXEC_START_PROCESS: rc = VBoxServiceControlHandleCmdStartProcess(g_GuestControlSvcClientID, uNumParms); break; @@ -282,9 +277,10 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown) } /* Do we need to shutdown? */ - if (*pfShutdown) + if ( *pfShutdown + || uMsg == GETHOSTMSG_EXEC_HOST_CANCEL_WAIT) { - rc = 0; + rc = VINF_SUCCESS; break; } @@ -301,15 +297,30 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown) /** @copydoc VBOXSERVICE::pfnStop */ static DECLCALLBACK(void) VBoxServiceControlStop(void) { + VBoxServiceVerbose(3, "Control: Stopping ...\n"); + /** @todo Later, figure what to do if we're in RTProcWait(). it's a very * annoying call since doesn't support timeouts in the posix world. */ RTSemEventMultiSignal(g_hControlEvent); + + /* + * Ask the host service to cancel all pending requests so that we can + * shutdown properly here. + */ + if (g_GuestControlSvcClientID) + { + int rc = VbglR3GuestCtrlCancelPendingWaits(g_GuestControlSvcClientID); + if (RT_FAILURE(rc)) + VBoxServiceError("Control: Cancelling pending waits failed; rc=%Rrc\n", rc); + } } /** @copydoc VBOXSERVICE::pfnTerm */ static DECLCALLBACK(void) VBoxServiceControlTerm(void) { + VBoxServiceVerbose(3, "Control: Terminating ...\n"); + /* Signal all threads that we want to shutdown. */ PVBOXSERVICECTRLTHREAD pNode; RTListForEach(&g_GuestControlExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node) @@ -320,6 +331,7 @@ static DECLCALLBACK(void) VBoxServiceControlTerm(void) { if (pNode->Thread != NIL_RTTHREAD) { + /* Wait a bit ... */ int rc2 = RTThreadWait(pNode->Thread, 30 * 1000 /* Wait 30 seconds max. */, NULL); if (RT_FAILURE(rc2)) VBoxServiceError("Control: Thread failed to stop; rc2=%Rrc\n", rc2); @@ -373,11 +385,11 @@ VBOXSERVICE g_Control = /* pszDescription. */ "Host-driven Guest Control", /* pszUsage. */ - "[--control-interval <ms>]" + " [--control-interval <ms>]" , /* pszOptions. */ - " --control-interval Specifies the interval at which to check for\n" - " new control commands. The default is 1000 ms.\n" + " --control-interval Specifies the interval at which to check for\n" + " new control commands. The default is 1000 ms.\n" , /* methods */ VBoxServiceControlPreInit, diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp index a17974090..9e62421d1 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp @@ -1,5 +1,5 @@ -/* $Id: VBoxServiceControlExec.cpp 29315 2010-05-11 07:53:29Z vboxsync $ */ +/* $Id: VBoxServiceControlExec.cpp 29627 2010-05-18 12:47:35Z vboxsync $ */ /** @file * VBoxServiceControlExec - Utility functions for process execution. */ @@ -578,14 +578,14 @@ int VBoxServiceControlExecReadPipeBufferContent(PVBOXSERVICECTRLEXECPIPEBUF pBuf int rc = RTCritSectEnter(&pBuf->CritSect); if (RT_SUCCESS(rc)) - { + { Assert(pBuf->cbOffset >= pBuf->cbRead); if (*pcbToRead > pBuf->cbOffset - pBuf->cbRead) *pcbToRead = pBuf->cbOffset - pBuf->cbRead; - + if (*pcbToRead > cbBuffer) *pcbToRead = cbBuffer; - + if (*pcbToRead > 0) { memcpy(pbBuffer, pBuf->pbData + pBuf->cbRead, *pcbToRead); @@ -608,7 +608,7 @@ int VBoxServiceControlExecWritePipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf, int rc = RTCritSectEnter(&pBuf->CritSect); if (RT_SUCCESS(rc)) - { + { /** @todo Use RTMemCache or RTMemObj here? */ uint8_t *pNewBuf; while (pBuf->cbSize - pBuf->cbOffset < cbData) @@ -619,7 +619,7 @@ int VBoxServiceControlExecWritePipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf, pBuf->cbSize += _4K; pBuf->pbData = pNewBuf; } - + rc = VINF_SUCCESS; if (pBuf->pbData) { @@ -642,12 +642,11 @@ int VBoxServiceControlExecAllocateThreadData(PVBOXSERVICECTRLTHREAD pThread, const char *pszCmd, uint32_t uFlags, const char *pszArgs, uint32_t uNumArgs, const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars, - const char *pszStdIn, const char *pszStdOut, const char *pszStdErr, const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS) { AssertPtr(pThread); - /* General stuff. */ + /* General stuff. */ pThread->Node.pPrev = NULL; pThread->Node.pNext = NULL; @@ -699,9 +698,6 @@ int VBoxServiceControlExecAllocateThreadData(PVBOXSERVICECTRLTHREAD pThread, } } - pData->pszStdIn = RTStrDup(pszStdIn); - pData->pszStdOut = RTStrDup(pszStdOut); - pData->pszStdErr = RTStrDup(pszStdErr); pData->pszUser = RTStrDup(pszUser); pData->pszPassword = RTStrDup(pszPassword); pData->uTimeLimitMS = uTimeLimitMS; @@ -733,7 +729,7 @@ int VBoxServiceControlExecAllocateThreadData(PVBOXSERVICECTRLTHREAD pThread, void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREADDATAEXEC pData) { if (pData) - { + { RTStrFree(pData->pszCmd); if (pData->uNumEnvVars) { @@ -742,12 +738,9 @@ void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREADDATAEXEC pDat RTMemFree(pData->papszEnv); } RTGetOptArgvFree(pData->papszArgs); - RTStrFree(pData->pszStdIn); - RTStrFree(pData->pszStdOut); - RTStrFree(pData->pszStdErr); RTStrFree(pData->pszUser); RTStrFree(pData->pszPassword); - + VBoxServiceControlExecDestroyPipeBuffer(&pData->stdOut); VBoxServiceControlExecDestroyPipeBuffer(&pData->stdErr); @@ -908,7 +901,6 @@ static DECLCALLBACK(int) VBoxServiceControlExecThread(RTTHREAD ThreadSelf, void int VBoxServiceControlExecProcess(uint32_t uContextID, const char *pszCmd, uint32_t uFlags, const char *pszArgs, uint32_t uNumArgs, const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars, - const char *pszStdIn, const char *pszStdOut, const char *pszStdErr, const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS) { PVBOXSERVICECTRLTHREAD pThread = (PVBOXSERVICECTRLTHREAD)RTMemAlloc(sizeof(VBOXSERVICECTRLTHREAD)); @@ -921,7 +913,6 @@ int VBoxServiceControlExecProcess(uint32_t uContextID, const char *pszCmd, uint3 pszCmd, uFlags, pszArgs, uNumArgs, pszEnv, cbEnv, uNumEnvVars, - pszStdIn, pszStdOut, pszStdErr, pszUser, pszPassword, uTimeLimitMS); if (RT_SUCCESS(rc)) diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp index 24cdf78f1..2dfd11efe 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxServiceCpuHotPlug.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */ +/* $Id: VBoxServiceCpuHotPlug.cpp 29503 2010-05-16 13:20:10Z vboxsync $ */ /** @file * VBoxService - Guest Additions CPU Hot Plugging Service. */ @@ -40,14 +40,175 @@ /** @name Paths to access the CPU device * @{ */ -# define SYSFS_ACPI_CPU_PATH "/sys/devices/LNXSYSTM:00/device:00" +# define SYSFS_ACPI_CPU_PATH "/sys/devices" # define SYSFS_CPU_PATH "/sys/devices/system/cpu" /** @} */ -#endif +/** Path component for the ACPI CPU path. */ +typedef struct SYSFSCPUPATHCOMP +{ + /** Flag whether the name is suffixed with a number */ + bool fNumberedSuffix; + /** Name of the component */ + const char *pcszName; +} SYSFSCPUPATHCOMP, *PSYSFSCPUPATHCOMP; +/** Pointer to a const component. */ +typedef const SYSFSCPUPATHCOMP *PCSYSFSCPUPATHCOMP; + +/** + * Structure which defines how the entries are assembled. + */ +typedef struct SYSFSCPUPATH +{ + /** Id when probing for the correct path. */ + uint32_t uId; + /** Array holding the possible components. */ + PCSYSFSCPUPATHCOMP aComponentsPossible; + /** Number of entries in the array, excluding the terminator. */ + unsigned cComponents; + /** Directory handle */ + PRTDIR pDir; + /** Current directory to try. */ + char *pszPath; +} SYSFSCPUPATH, *PSYSFSCPUPATH; + +/** Content of uId if the path wasn't probed yet. */ +#define ACPI_CPU_PATH_NOT_PROBED UINT32_MAX + +/** Possible combinations of all path components for level 1. */ +const SYSFSCPUPATHCOMP g_aAcpiCpuPathLvl1[] = +{ + /** LNXSYSTEM:<id> */ + {true, "LNXSYSTM:"} +}; + +/** Possible combinations of all path components for level 2. */ +const SYSFSCPUPATHCOMP g_aAcpiCpuPathLvl2[] = +{ + /** device:<id> */ + {true, "device:"}, + /** LNXSYBUS:<id> */ + {true, "LNXSYBUS:"} +}; + +/** Possible combinations of all path components for level 3 */ +const SYSFSCPUPATHCOMP g_aAcpiCpuPathLvl3[] = +{ + /** ACPI0004:<id> */ + {true, "ACPI0004:"} +}; + +/** Possible combinations of all path components for level 4 */ +const SYSFSCPUPATHCOMP g_aAcpiCpuPathLvl4[] = +{ + /** LNXCPU:<id> */ + {true, "LNXCPU:"}, + /** ACPI_CPU:<id> */ + {true, "ACPI_CPU:"} +}; + +/** All possible combinations. */ +SYSFSCPUPATH g_aAcpiCpuPath[] = +{ + /** Level 1 */ + {ACPI_CPU_PATH_NOT_PROBED, g_aAcpiCpuPathLvl1, RT_ELEMENTS(g_aAcpiCpuPathLvl1), NULL, NULL}, + /** Level 2 */ + {ACPI_CPU_PATH_NOT_PROBED, g_aAcpiCpuPathLvl2, RT_ELEMENTS(g_aAcpiCpuPathLvl2), NULL, NULL}, + /** Level 3 */ + {ACPI_CPU_PATH_NOT_PROBED, g_aAcpiCpuPathLvl3, RT_ELEMENTS(g_aAcpiCpuPathLvl3), NULL, NULL}, + /** Level 4 */ + {ACPI_CPU_PATH_NOT_PROBED, g_aAcpiCpuPathLvl4, RT_ELEMENTS(g_aAcpiCpuPathLvl4), NULL, NULL}, +}; +#endif #ifdef RT_OS_LINUX /** + * Probes for the correct path to the ACPI CPU object in sysfs for the + * various different kernel versions and distro's. + * + * @returns VBox status code. + */ +static int VBoxServiceCpuHotPlugProbePath(void) +{ + int rc = VINF_SUCCESS; + + /* Probe for the correct path if we didn't already. */ + if (RT_UNLIKELY(g_aAcpiCpuPath[0].uId == ACPI_CPU_PATH_NOT_PROBED)) + { + char *pszPath = NULL; /** < Current path, increasing while we dig deeper. */ + + pszPath = RTStrDup(SYSFS_ACPI_CPU_PATH); + if (!pszPath) + return VERR_NO_MEMORY; + + /* + * Simple algorithm to find the path. + * Performance is not a real problem because it is + * only executed once. + */ + for (unsigned iLvlCurr = 0; iLvlCurr < RT_ELEMENTS(g_aAcpiCpuPath); iLvlCurr++) + { + PSYSFSCPUPATH pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr]; + + for (unsigned iCompCurr = 0; iCompCurr < pAcpiCpuPathLvl->cComponents; iCompCurr++) + { + PCSYSFSCPUPATHCOMP pPathComponent = &pAcpiCpuPathLvl->aComponentsPossible[iCompCurr]; + PRTDIR pDirCurr = NULL; + char *pszPathTmp = NULL; + bool fFound = false; + + rc = RTStrAPrintf(&pszPathTmp, "%s/%s*", pszPath, pPathComponent->pcszName); + if (RT_FAILURE(rc)) + break; + + /* Open the directory */ + rc = RTDirOpenFiltered(&pDirCurr, pszPathTmp, RTDIRFILTER_WINNT); + if (RT_FAILURE(rc)) + { + RTStrFree(pszPathTmp); + break; + } + + /* Search if the current directory contains one of the possible parts. */ + RTDIRENTRY DirFolderContent; + while (RT_SUCCESS(RTDirRead(pDirCurr, &DirFolderContent, NULL))) /* Assumption that szName has always enough space */ + { + if (!strncmp(DirFolderContent.szName, pPathComponent->pcszName, strlen(pPathComponent->pcszName))) + { + char *pszPathLvl = NULL; + + /* Found, use the complete name to dig deeper. */ + fFound = true; + pAcpiCpuPathLvl->uId = iCompCurr; + rc = RTStrAPrintf(&pszPathLvl, "%s/%s", pszPath, DirFolderContent.szName); + + if (RT_SUCCESS(rc)) + { + RTStrFree(pszPath); + pszPath = pszPathLvl; + } + break; + } + } + RTDirClose(pDirCurr); + + if (fFound) + break; + } /* For every possible component. */ + + /* No matching component for this part, no need to continue */ + if (RT_FAILURE(rc)) + break; + } /* For every level */ + + VBoxServiceVerbose(1, "Final path after probing %s rc=%Rrc\n", pszPath, rc); + RTStrFree(pszPath); + } + + return rc; +} + +/** * Returns the path of the ACPI CPU device with the given core and package ID. * * @returns VBox status code. @@ -57,61 +218,139 @@ */ static int VBoxServiceCpuHotPlugGetACPIDevicePath(char **ppszPath, uint32_t idCpuCore, uint32_t idCpuPackage) { - AssertPtr(ppszPath); + int rc = VINF_SUCCESS; + + AssertPtrReturn(ppszPath, VERR_INVALID_PARAMETER); - PRTDIR pDirDevices = NULL; - int rc = RTDirOpen(&pDirDevices, SYSFS_ACPI_CPU_PATH); /* could use RTDirOpenFiltered */ + rc = VBoxServiceCpuHotPlugProbePath(); if (RT_SUCCESS(rc)) { - /* Search every ACPI0004 container device for LNXCPU devices. */ - RTDIRENTRY DirFolderAcpiContainer; + /* Build the path from all components. */ bool fFound = false; - - while ( RT_SUCCESS(RTDirRead(pDirDevices, &DirFolderAcpiContainer, NULL)) - && !fFound) /* Assumption that szName has always enough space */ + unsigned iLvlCurr = 0; + char *pszPath = NULL; + char *pszPathDir = NULL; + PSYSFSCPUPATH pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr]; + + /* Init everything. */ + Assert(pAcpiCpuPathLvl->uId != ACPI_CPU_PATH_NOT_PROBED); + rc = RTStrAPrintf(&pszPath, + "%s/%s*", SYSFS_ACPI_CPU_PATH, + pAcpiCpuPathLvl->aComponentsPossible[pAcpiCpuPathLvl->uId].pcszName); + if (RT_FAILURE(rc)) + return rc; + + pAcpiCpuPathLvl->pszPath = RTStrDup(SYSFS_ACPI_CPU_PATH); + if (!pAcpiCpuPathLvl->pszPath) + return VERR_NO_MEMORY; + + /* Open the directory */ + rc = RTDirOpenFiltered(&pAcpiCpuPathLvl->pDir, pszPath, RTDIRFILTER_WINNT); + if (RT_SUCCESS(rc)) { - if (!strncmp(DirFolderAcpiContainer.szName, "ACPI0004", 8)) - { - char *pszAcpiContainerPath = NULL; - PRTDIR pDirAcpiContainer = NULL; + RTStrFree(pszPath); - rc = RTStrAPrintf(&pszAcpiContainerPath, "%s/%s", SYSFS_ACPI_CPU_PATH, DirFolderAcpiContainer.szName); - if (RT_FAILURE(rc)) - break; - - rc = RTDirOpen(&pDirAcpiContainer, pszAcpiContainerPath); + /* Search for CPU */ + while (!fFound) + { + /* Get the next directory. */ + RTDIRENTRY DirFolderContent; + rc = RTDirRead(pAcpiCpuPathLvl->pDir, &DirFolderContent, NULL); if (RT_SUCCESS(rc)) { - RTDIRENTRY DirFolderContent; - while (RT_SUCCESS(RTDirRead(pDirAcpiContainer, &DirFolderContent, NULL))) /* Assumption that szName has always enough space */ + char *pszPathCurr; + + /* Create the new path. */ + rc = RTStrAPrintf(&pszPathCurr, "%s/%s", pAcpiCpuPathLvl->pszPath, DirFolderContent.szName); + if (RT_FAILURE(rc)) + break; + + /* If this is the last level check for the given core and package id. */ + if (iLvlCurr == RT_ELEMENTS(g_aAcpiCpuPath) - 1) { - if ( !strncmp(DirFolderContent.szName, "LNXCPU", 6) - || !strncmp(DirFolderContent.szName, "ACPI_CPU", 8)) + /* Get the sysdev */ + uint32_t idCore = RTLinuxSysFsReadIntFile(10, "%s/sysdev/topology/core_id", + pszPathCurr); + uint32_t idPackage = RTLinuxSysFsReadIntFile(10, "%s/sysdev/topology/physical_package_id", + pszPathCurr); + if ( idCore == idCpuCore + && idPackage == idCpuPackage) + { + /* Return the path */ + pszPath = pszPathCurr; + fFound = true; + VBoxServiceVerbose(3, "CPU found\n"); + break; + } + else { - /* Get the sysdev */ - uint32_t idCore = RTLinuxSysFsReadIntFile(10, "%s/%s/sysdev/topology/core_id", - pszAcpiContainerPath, DirFolderContent.szName); - uint32_t idPackage = RTLinuxSysFsReadIntFile(10, "%s/%s/sysdev/topology/physical_package_id", - pszAcpiContainerPath, DirFolderContent.szName); - if ( idCore == idCpuCore - && idPackage == idCpuPackage) - { - /* Return the path */ - rc = RTStrAPrintf(ppszPath, "%s/%s", pszAcpiContainerPath, DirFolderContent.szName); - fFound = true; - break; - } + /* Get the next directory. */ + RTStrFree(pszPathCurr); + VBoxServiceVerbose(3, "CPU doesn't match, next directory\n"); } } + else + { + /* Go deeper */ + iLvlCurr++; + + VBoxServiceVerbose(3, "Going deeper (iLvlCurr=%u)\n", iLvlCurr); + + pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr]; + + Assert(!pAcpiCpuPathLvl->pDir); + Assert(!pAcpiCpuPathLvl->pszPath); + pAcpiCpuPathLvl->pszPath = pszPathCurr; + PCSYSFSCPUPATHCOMP pPathComponent = &pAcpiCpuPathLvl->aComponentsPossible[pAcpiCpuPathLvl->uId]; + + Assert(pAcpiCpuPathLvl->uId != ACPI_CPU_PATH_NOT_PROBED); + + rc = RTStrAPrintf(&pszPathDir, "%s/%s*", pszPathCurr, pPathComponent->pcszName); + if (RT_FAILURE(rc)) + break; + + VBoxServiceVerbose(3, "New path %s\n", pszPathDir); + + /* Open the directory */ + rc = RTDirOpenFiltered(&pAcpiCpuPathLvl->pDir, pszPathDir, RTDIRFILTER_WINNT); + if (RT_FAILURE(rc)) + break; + } + } + else + { + /* Go back one level and try to get the next entry. */ + Assert(iLvlCurr > 0); + + RTDirClose(pAcpiCpuPathLvl->pDir); + RTStrFree(pAcpiCpuPathLvl->pszPath); + pAcpiCpuPathLvl->pDir = NULL; + pAcpiCpuPathLvl->pszPath = NULL; - RTDirClose(pDirAcpiContainer); + iLvlCurr--; + pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr]; + VBoxServiceVerbose(3, "Directory not found, going back (iLvlCurr=%u)\n", iLvlCurr); } + } /* while not found */ + } /* Successful init */ - RTStrFree(pszAcpiContainerPath); - } + /* Cleanup */ + for (unsigned i = 0; i < RT_ELEMENTS(g_aAcpiCpuPath); i++) + { + if (g_aAcpiCpuPath[i].pDir) + RTDirClose(g_aAcpiCpuPath[i].pDir); + if (g_aAcpiCpuPath[i].pszPath) + RTStrFree(g_aAcpiCpuPath[i].pszPath); + g_aAcpiCpuPath[i].pDir = NULL; + g_aAcpiCpuPath[i].pszPath = NULL; } + if (pszPathDir) + RTStrFree(pszPathDir); + if (RT_FAILURE(rc) && pszPath) + RTStrFree(pszPath); - RTDirClose(pDirDevices); + if (RT_SUCCESS(rc)) + *ppszPath = pszPath; } return rc; diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h b/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h index 6c56ab873..4a4e686f2 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h @@ -1,4 +1,4 @@ -/* $Id: VBoxServiceInternal.h 29313 2010-05-11 07:08:01Z vboxsync $ */ +/* $Id: VBoxServiceInternal.h 29516 2010-05-17 09:55:17Z vboxsync $ */ /** @file * VBoxService - Guest Additions Services. */ @@ -153,9 +153,6 @@ typedef struct uint32_t uNumArgs; char **papszEnv; uint32_t uNumEnvVars; - char *pszStdIn; - char *pszStdOut; - char *pszStdErr; char *pszUser; char *pszPassword; uint32_t uTimeLimitMS; @@ -301,7 +298,6 @@ extern int VBoxServiceWinGetComponentVersions(uint32_t uiClientID); extern int VBoxServiceControlExecProcess(uint32_t uContext, const char *pszCmd, uint32_t uFlags, const char *pszArgs, uint32_t uNumArgs, const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars, - const char *pszStdIn, const char *pszStdOut, const char *pszStdErr, const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS); extern void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREADDATAEXEC pThread); extern int VBoxServiceControlExecReadPipeBufferContent(PVBOXSERVICECTRLEXECPIPEBUF pBuf, diff --git a/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp b/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp index 33f631091..d34b92320 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxServicePageSharing.cpp 29424 2010-05-12 15:11:09Z vboxsync $ */ +/* $Id: VBoxServicePageSharing.cpp 29640 2010-05-18 14:30:50Z vboxsync $ */ /** @file * VBoxService - Guest page sharing. */ @@ -21,6 +21,7 @@ *******************************************************************************/ #include <iprt/assert.h> #include <iprt/avl.h> +#include <iprt/asm.h> #include <iprt/mem.h> #include <iprt/stream.h> #include <iprt/string.h> @@ -58,9 +59,9 @@ static PAVLPVNODECORE pKnownModuleTree = NULL; /** * Registers a new module with the VMM - * @param dwProcessId Process id + * @param pModule Module ptr */ -void VBoxServicePageSharingRegisterModule(HANDLE hProcess, PKNOWN_MODULE pModule) +void VBoxServicePageSharingRegisterModule(PKNOWN_MODULE pModule) { VMMDEVSHAREDREGIONDESC aRegions[VMMDEVSHAREDREGIONDESC_MAX]; DWORD dwModuleSize = pModule->Info.modBaseSize; @@ -128,9 +129,9 @@ void VBoxServicePageSharingRegisterModule(HANDLE hProcess, PKNOWN_MODULE pModule unsigned idxRegion = 0; do { - MEMORY_BASIC_INFORMATION MemInfo[16]; + MEMORY_BASIC_INFORMATION MemInfo; - SIZE_T ret = VirtualQueryEx(hProcess, pBaseAddress, &MemInfo[0], sizeof(MemInfo)); + SIZE_T ret = VirtualQuery(pBaseAddress, &MemInfo, sizeof(MemInfo)); Assert(ret); if (!ret) { @@ -138,42 +139,51 @@ void VBoxServicePageSharingRegisterModule(HANDLE hProcess, PKNOWN_MODULE pModule break; } - unsigned cMemInfoBlocks = ret / sizeof(MemInfo[0]); - - for (unsigned i = 0; i < cMemInfoBlocks; i++) + if ( MemInfo.State == MEM_COMMIT + && MemInfo.Type == MEM_IMAGE) { - if ( MemInfo[i].State == MEM_COMMIT - && MemInfo[i].Type == MEM_IMAGE) + switch (MemInfo.Protect) { - switch (MemInfo[i].Protect) - { - case PAGE_EXECUTE: - case PAGE_EXECUTE_READ: - case PAGE_READONLY: - aRegions[idxRegion].GCRegionAddr = (RTGCPTR64)MemInfo[i].BaseAddress; - aRegions[idxRegion].cbRegion = MemInfo[i].RegionSize; - idxRegion++; - break; + case PAGE_EXECUTE: + case PAGE_EXECUTE_READ: + case PAGE_READONLY: + { + char *pRegion = (char *)MemInfo.BaseAddress; - default: - break; /* ignore */ + /* Skip the first region as it only contains the image file header. */ + if (pRegion != (char *)pModule->Info.modBaseAddr) + { + /* Touch all pages. */ + while (pRegion < (char *)MemInfo.BaseAddress + MemInfo.RegionSize) + { + /* Try to trick the optimizer to leave the page touching code in place. */ + ASMProbeReadByte(pRegion); + pRegion += PAGE_SIZE; + } } - } + aRegions[idxRegion].GCRegionAddr = (RTGCPTR64)MemInfo.BaseAddress; + aRegions[idxRegion].cbRegion = MemInfo.RegionSize; + idxRegion++; - pBaseAddress = (BYTE *)MemInfo[i].BaseAddress + MemInfo[i].RegionSize; - if (dwModuleSize > MemInfo[i].RegionSize) - { - dwModuleSize -= MemInfo[i].RegionSize; - } - else - { - dwModuleSize = 0; break; } - if (idxRegion >= RT_ELEMENTS(aRegions)) - break; /* out of room */ + default: + break; /* ignore */ + } + } + + pBaseAddress = (BYTE *)MemInfo.BaseAddress + MemInfo.RegionSize; + if (dwModuleSize > MemInfo.RegionSize) + { + dwModuleSize -= MemInfo.RegionSize; + } + else + { + dwModuleSize = 0; + break; } + if (idxRegion >= RT_ELEMENTS(aRegions)) break; /* out of room */ } @@ -186,7 +196,6 @@ void VBoxServicePageSharingRegisterModule(HANDLE hProcess, PKNOWN_MODULE pModule if (RT_FAILURE(rc)) VBoxServiceVerbose(3, "VbglR3RegisterSharedModule failed with %d\n", rc); - end: RTMemFree(pVersionInfo); return; @@ -226,6 +235,12 @@ void VBoxServicePageSharingInspectModules(DWORD dwProcessId, PAVLPVNODECORE *ppN bRet = Module32First(hSnapshot, &ModuleInfo); do { + /** todo when changing this make sure VBoxService.exe is excluded! */ + char *pszDot = strrchr(ModuleInfo.szModule, '.'); + if ( pszDot + && (pszDot[1] == 'e' || pszDot[1] == 'E')) + continue; /* ignore executables for now. */ + /* Found it before? */ PAVLPVNODECORE pRec = RTAvlPVGet(ppNewTree, ModuleInfo.modBaseAddr); if (!pRec) @@ -243,7 +258,7 @@ void VBoxServicePageSharingInspectModules(DWORD dwProcessId, PAVLPVNODECORE *ppN pModule->Core.Key = ModuleInfo.modBaseAddr; pModule->hModule = LoadLibraryEx(ModuleInfo.szExePath, 0, DONT_RESOLVE_DLL_REFERENCES); if (pModule->hModule) - VBoxServicePageSharingRegisterModule(hProcess, pModule); + VBoxServicePageSharingRegisterModule(pModule); pRec = &pModule->Core; } @@ -272,6 +287,7 @@ void VBoxServicePageSharingInspectGuest() { HANDLE hSnapshot; PAVLPVNODECORE pNewTree = NULL; + DWORD dwProcessId = GetCurrentProcessId(); VBoxServiceVerbose(3, "VBoxServicePageSharingInspectGuest\n"); @@ -290,7 +306,9 @@ void VBoxServicePageSharingInspectGuest() do { - VBoxServicePageSharingInspectModules(ProcessInfo.th32ProcessID, &pNewTree); + /* Skip our own process. */ + if (ProcessInfo.th32ProcessID != dwProcessId) + VBoxServicePageSharingInspectModules(ProcessInfo.th32ProcessID, &pNewTree); } while (Process32Next(hSnapshot, &ProcessInfo)); diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp index 23288cda3..f9fa4d78e 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxServiceTimeSync.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */ +/* $Id: VBoxServiceTimeSync.cpp 29594 2010-05-18 07:45:58Z vboxsync $ */ /** @file * VBoxService - Guest Additions TimeSync Service. */ @@ -623,30 +623,27 @@ VBOXSERVICE g_TimeSync = /* pszDescription. */ "Time synchronization", /* pszUsage. */ - "[--timesync-interval <ms>] [--timesync-min-adjust <ms>] " - "[--timesync-latency-factor <x>] [--timesync-max-latency <ms>]" - "[--timesync-set-threshold <ms>] [--timesync-set-start]" + " [--timesync-interval <ms>] [--timesync-min-adjust <ms>]\n" + " [--timesync-latency-factor <x>] [--timesync-max-latency <ms>]\n" + " [--timesync-set-threshold <ms>] [--timesync-set-start]" , /* pszOptions. */ - " --timesync-interval Specifies the interval at which to synchronize the\n" - " time with the host. The default is 10000 ms.\n" - " --timesync-min-adjust\n" - " The minimum absolute drift value measured in\n" - " milliseconds to make adjustments for.\n" - " The default is 1000 ms on OS/2 and 100 ms elsewhere.\n" + " --timesync-interval Specifies the interval at which to synchronize the\n" + " time with the host. The default is 10000 ms.\n" + " --timesync-min-adjust The minimum absolute drift value measured in\n" + " milliseconds to make adjustments for.\n" + " The default is 1000 ms on OS/2 and 100 ms elsewhere.\n" " --timesync-latency-factor\n" - " The factor to multiply the time query latency with to\n" - " calculate the dynamic minimum adjust time.\n" - " The default is 8 times.\n" - " --timesync-max-latency\n" - " The max host timer query latency to accept.\n" - " The default is 250 ms.\n" + " The factor to multiply the time query latency with\n" + " to calculate the dynamic minimum adjust time.\n" + " The default is 8 times.\n" + " --timesync-max-latency The max host timer query latency to accept.\n" + " The default is 250 ms.\n" " --timesync-set-threshold\n" - " The absolute drift threshold, given as milliseconds,\n" - " where to start setting the time instead of trying to\n" - " adjust it. The default is 20 min.\n" - " --timesync-set-start\n" - " Set the time when starting the time sync service.\n" + " The absolute drift threshold, given as milliseconds,\n" + " where to start setting the time instead of trying to\n" + " adjust it. The default is 20 min.\n" + " --timesync-set-start Set the time when starting the time sync service.\n" , /* methods */ VBoxServiceTimeSyncPreInit, diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp index 5a26038a0..3c90bc916 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxServiceVMInfo.cpp 29398 2010-05-12 09:45:06Z vboxsync $ */ +/* $Id: VBoxServiceVMInfo.cpp 29594 2010-05-18 07:45:58Z vboxsync $ */ /** @file * VBoxService - Virtual Machine Information for the Host. */ @@ -620,11 +620,11 @@ VBOXSERVICE g_VMInfo = /* pszDescription. */ "Virtual Machine Information", /* pszUsage. */ - "[--vminfo-interval <ms>]" + " [--vminfo-interval <ms>]" , /* pszOptions. */ - " --vminfo-interval Specifies the interval at which to retrieve the\n" - " VM information. The default is 10000 ms.\n" + " --vminfo-interval Specifies the interval at which to retrieve the\n" + " VM information. The default is 10000 ms.\n" , /* methods */ VBoxServiceVMInfoPreInit, diff --git a/src/VBox/Additions/common/crOpenGL/context.c b/src/VBox/Additions/common/crOpenGL/context.c index 98b427325..c4bf2af6f 100644 --- a/src/VBox/Additions/common/crOpenGL/context.c +++ b/src/VBox/Additions/common/crOpenGL/context.c @@ -190,7 +190,7 @@ stubGetWindowInfo( Display *dpy, GLXDrawable drawable ) if (!hwnd) { - crError("Can't get HWND for given HDC(%x)", drawable); + return NULL; } winInfo = (WindowInfo *) crHashtableSearch(stub.windowTable, (unsigned int) hwnd); diff --git a/src/VBox/Additions/linux/installer/vboxadd-x11.sh b/src/VBox/Additions/linux/installer/vboxadd-x11.sh index fca4713bd..2916f1cb9 100644 --- a/src/VBox/Additions/linux/installer/vboxadd-x11.sh +++ b/src/VBox/Additions/linux/installer/vboxadd-x11.sh @@ -1,6 +1,6 @@ #! /bin/sh # Sun VirtualBox -# Linux Additions X11 setup init script ($Revision: 29406 $) +# Linux Additions X11 setup init script ($Revision: 29612 $) # # @@ -322,7 +322,8 @@ setup() vboxvideo_src=vboxvideo_drv_18.so vboxmouse_src=vboxmouse_drv_18.so doxorgconfd="true" - setupxorgconf="" + # Fedora 13 looks likely to ship without vboxvideo detection + test "$system" = "redhat" || setupxorgconf="" ;; 1.6.99.* | 1.7.* ) begin "Installing X.Org Server 1.7 modules" diff --git a/src/VBox/Additions/linux/sharedfolders/files_vboxsf b/src/VBox/Additions/linux/sharedfolders/files_vboxsf index 9c9b83dde..a33307992 100755..100644 --- a/src/VBox/Additions/linux/sharedfolders/files_vboxsf +++ b/src/VBox/Additions/linux/sharedfolders/files_vboxsf @@ -1,10 +1,11 @@ #!/bin/sh +# $Id: $ ## @file # Shared file between Makefile.kmk and export_modules # # -# Copyright (C) 2007 Oracle Corporation +# Copyright (C) 2007-2010 Oracle Corporation # # This file is part of VirtualBox Open Source Edition (OSE), as # available from http://www.virtualbox.org. This file is free software; @@ -19,6 +20,8 @@ FILES_VBOXSF_NOBIN=" \ ${PATH_ROOT}/include/iprt/nocrt/limits.h=>include/iprt/nocrt/limits.h \ ${PATH_ROOT}/include/iprt/alloc.h=>include/iprt/alloc.h \ ${PATH_ROOT}/include/iprt/asm.h=>include/iprt/asm.h \ + ${PATH_ROOT}/include/iprt/asm-amd64-x86.h=>include/iprt/asm-amd64-x86.h \ + ${PATH_ROOT}/include/iprt/asm-math.h=>include/iprt/asm-math.h \ ${PATH_ROOT}/include/iprt/assert.h=>include/iprt/assert.h \ ${PATH_ROOT}/include/iprt/cdefs.h=>include/iprt/cdefs.h \ ${PATH_ROOT}/include/iprt/err.h=>include/iprt/err.h \ diff --git a/src/VBox/Additions/x11/Installer/x11config-new.pl b/src/VBox/Additions/x11/Installer/x11config-new.pl index d9989a22c..92fbee7dc 100644 --- a/src/VBox/Additions/x11/Installer/x11config-new.pl +++ b/src/VBox/Additions/x11/Installer/x11config-new.pl @@ -22,7 +22,7 @@ my $old_mouse_dev = "/dev/psaux"; foreach $arg (@ARGV) { - if (lc($arg) eq "--autoMouse") + if (lc($arg) eq "--automouse") { $auto_mouse = 1; } |