From: Oliver Kurth Date: Tue, 30 Apr 2019 20:24:25 +0000 (-0700) Subject: Add garbage collection for vix process handles. X-Git-Tag: stable-11.0.0~93 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a2c4645a363c705e66cdb81847f579d8ff30e04;p=thirdparty%2Fopen-vm-tools.git Add garbage collection for vix process handles. This closely follows the model used for hgfs session cleanup. --- diff --git a/open-vm-tools/services/plugins/vix/vixTools.c b/open-vm-tools/services/plugins/vix/vixTools.c index 5af754973..98975eec7 100644 --- a/open-vm-tools/services/plugins/vix/vixTools.c +++ b/open-vm-tools/services/plugins/vix/vixTools.c @@ -431,6 +431,7 @@ static HashTable *userEnvironmentTable = NULL; static HgfsServerMgrData gVixHgfsBkdrConn; #define SECONDS_BETWEEN_INVALIDATING_HGFS_SESSIONS 120 +#define SECONDS_BETWEEN_INVALIDATING_PROC_HANDLES 60 static VixError VixToolsGetFileInfo(VixCommandRequestHeader *requestMsg, char **result); @@ -445,6 +446,11 @@ static gboolean VixToolsInvalidateInactiveHGFSSessions(void *clientData); static GSource *gHgfsSessionInvalidatorTimer = NULL; static guint gHgfsSessionInvalidatorTimerId; +static GSource *gProcHandleInvalidatorTimer = NULL; +static guint gProcHandleInvalidatorTimerId; +static void VixToolsRegisterProcHandleInvalidator(void *clientData); +static gboolean VixToolsInvalidateStaleProcHandles(void *clientData); + static void VixToolsPrintFileInfo(const char *filePathName, char *fileName, Bool escapeStrs, @@ -816,6 +822,14 @@ VixTools_Uninitialize(void) // IN g_message("%s: HGFS session Invalidator detached\n", __FUNCTION__); } + if (NULL != gProcHandleInvalidatorTimer) { + g_source_remove(gProcHandleInvalidatorTimerId); + g_source_unref(gProcHandleInvalidatorTimer); + gProcHandleInvalidatorTimer = NULL; + gProcHandleInvalidatorTimerId = 0; + g_debug("%s: Process Handle Invalidator detached\n", __FUNCTION__); + } + HgfsServerManager_Unregister(&gVixHgfsBkdrConn); } @@ -1373,6 +1387,14 @@ VixTools_StartProgram(VixCommandRequestHeader *requestMsg, // IN VixToolsUpdateStartedProgramList(spState); } + if (NULL != eventQueue) { + /* + * Register a timer to periodically invalidate any stale + * process handles. + */ + VixToolsRegisterProcHandleInvalidator(eventQueue); + } + abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); @@ -2013,6 +2035,45 @@ cleanup: } // VixToolsMonitorAsyncProc +/* + *---------------------------------------------------------------------------- + * + * VixToolsInvalidateStaleProcHandles -- + * + * Remove stale proc handles from started programs list. + * + * Return value: + * TRUE if the timer needs to be re-registerd. + * FALSE if the timer needs to be deleted. + * + * Side effects: + * None + * + *---------------------------------------------------------------------------- + */ + +static gboolean +VixToolsInvalidateStaleProcHandles(void *clientData) // IN: +{ + VixToolsUpdateStartedProgramList(NULL); + + if (startedProcessList != NULL) { + /* + * There are still proc handles on the list, so keep the periodic timer + * registered. + */ + return TRUE; + } else { + g_source_unref(gProcHandleInvalidatorTimer); + gProcHandleInvalidatorTimer = NULL; + gProcHandleInvalidatorTimerId = 0; + g_debug("%s: Process Handle Invalidator is successfully detached\n", + __FUNCTION__); + return FALSE; + } +} + + /* *---------------------------------------------------------------------------- * @@ -2053,6 +2114,51 @@ VixToolsInvalidateInactiveHGFSSessions(void *clientData) // IN: } +/* + *---------------------------------------------------------------------------- + * + * VixToolsRegisterProcHandleInvalidator -- + * + * Check bug 2308222 for more details. This function is designed to + * cleanup any garbage proc handles in the Started Process List. + * + * If there is a timer already registered, then this function doesn't + * do anything. + * + * Return value: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------------- + */ + +static void +VixToolsRegisterProcHandleInvalidator(void *clientData) // IN: +{ + ASSERT(clientData); + + if (NULL != gProcHandleInvalidatorTimer) { + return; + } + + gProcHandleInvalidatorTimer = + g_timeout_source_new(SECONDS_BETWEEN_INVALIDATING_PROC_HANDLES * 1000); + + g_source_set_callback(gProcHandleInvalidatorTimer, + VixToolsInvalidateStaleProcHandles, + NULL, + NULL); + + gProcHandleInvalidatorTimerId = + g_source_attach(gProcHandleInvalidatorTimer, + g_main_loop_get_context((GMainLoop *) clientData)); + + g_debug("%s: Process Handle Invalidator registered\n", __FUNCTION__); +} + + /* *---------------------------------------------------------------------------- *