From: Oliver Kurth Date: Fri, 26 Oct 2018 17:45:00 +0000 (-0700) Subject: Clear DnDPluginResetTimer on receiving SIGUSR1. X-Git-Tag: stable-11.0.0~351 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03ec43287b1bf2dd8ad0a2c10a272ba317cf3fc3;p=thirdparty%2Fopen-vm-tools.git Clear DnDPluginResetTimer on receiving SIGUSR1. DnDPluginResetTimer callback handler DnDPluginResetSent() accesses the RPC channel managed by the main loop. However, mainloop destroys this channel on receiving SIGUSR1. So, we need to destroy this timer as well when SIGUSR1 is received. There are at least 2 ways to do it: 1. Add Linux specific code in vmCopyPasteDnDWrapper.cpp and any other places where we need to do similar cleanup. 2. Have main loop generate a signal and do the necessary cleanup as handling that signal. In order to keep the code clean and also let other places/future changes leverage the same solution, approach #2 is used here to define and generate a new signal TOOLS_CORE_SIG_NO_RPC. Also, implement a handler for the same in the test plugin (for testing) and dndcp for this bug. While there also fixed the log domain for few files that are supposed to logging under "dndcp" domain. --- diff --git a/open-vm-tools/lib/include/vmware/tools/plugin.h b/open-vm-tools/lib/include/vmware/tools/plugin.h index 786b7a7e8..eaf82a575 100644 --- a/open-vm-tools/lib/include/vmware/tools/plugin.h +++ b/open-vm-tools/lib/include/vmware/tools/plugin.h @@ -155,6 +155,15 @@ ToolsCore_LogState(guint level, */ #define TOOLS_CORE_SIG_RESET "tcs_reset" +/** + * Signal sent when RpcChannel is going to be destroyed. + * + * @param[in] src The source object. + * @param[in] ctx ToolsAppCtx *: The application context. + * @param[in] data Client data. + */ +#define TOOLS_CORE_SIG_NO_RPC "tcs_no_rpc" + /** * Signal sent when a "set option" RPC message arrives. * diff --git a/open-vm-tools/services/plugins/dndcp/copyPasteCompatX11.c b/open-vm-tools/services/plugins/dndcp/copyPasteCompatX11.c index d5a0fdf97..20b2cc011 100644 --- a/open-vm-tools/services/plugins/dndcp/copyPasteCompatX11.c +++ b/open-vm-tools/services/plugins/dndcp/copyPasteCompatX11.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2005-2016 VMware, Inc. All rights reserved. + * Copyright (C) 2005-2018 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -37,6 +37,8 @@ * selection text. */ +#define G_LOG_DOMAIN "dndcp" + #include "dndPluginIntX11.h" #include #include diff --git a/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDWrapper.cpp b/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDWrapper.cpp index 1879afd61..a4716d770 100644 --- a/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDWrapper.cpp +++ b/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDWrapper.cpp @@ -452,6 +452,21 @@ CopyPasteDnDWrapper::OnReset() } +/** + * + * Handle no_rpc. + * + * Remove any actions that would need RPC channel. + */ + +void +CopyPasteDnDWrapper::OnNoRpc() +{ + g_debug("%s: enter.\n", __FUNCTION__); + RemoveDnDPluginResetTimer(); +} + + /** * * Handle cap reg. This is cross-platform so handle here instead of the diff --git a/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDWrapper.h b/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDWrapper.h index ac1884555..a4d0f8fa3 100644 --- a/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDWrapper.h +++ b/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDWrapper.h @@ -53,6 +53,7 @@ public: void SetCPIsEnabled(gboolean isEnabled); gboolean IsCPEnabled(); void OnReset(); + void OnNoRpc(); virtual void OnResetInternal(); virtual void OnCapReg(gboolean set); virtual gboolean OnSetOption(const char *option, const char *value); @@ -60,6 +61,7 @@ public: void PointerInit(void); virtual ToolsAppCtx *GetToolsAppCtx() {return NULL;}; uint32 GetCaps(); + virtual void RemoveDnDPluginResetTimer(void) { } protected: /* diff --git a/open-vm-tools/services/plugins/dndcp/dndcp.cpp b/open-vm-tools/services/plugins/dndcp/dndcp.cpp index 82fe38150..292fd19b1 100644 --- a/open-vm-tools/services/plugins/dndcp/dndcp.cpp +++ b/open-vm-tools/services/plugins/dndcp/dndcp.cpp @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2010-2017 VMware, Inc. All rights reserved. + * Copyright (C) 2010-2018 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -29,6 +29,8 @@ #include "vmware.h" +#define G_LOG_DOMAIN "dndcp" + extern "C" { #include "vmware/guestrpc/tclodefs.h" #include "vmware/tools/plugin.h" @@ -84,6 +86,27 @@ DnDCPReset(gpointer src, } +/** + * Handle a no_rpc signal. + * + * @param[in] src Unused. + * @param[in] ctx Unused. + * @param[in] data Unused. + */ + +static void +DnDCPNoRpc(gpointer src, + ToolsAppCtx *ctx, + gpointer data) +{ + g_debug("%s: enter\n", __FUNCTION__); + CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance(); + if (p) { + p->OnNoRpc(); + } +} + + /** * Returns the list of the plugin's capabilities. * @@ -179,6 +202,7 @@ ToolsOnLoad(ToolsAppCtx *ctx) ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_CAPABILITIES, (void *) DnDCPCapabilities, NULL }, { TOOLS_CORE_SIG_RESET, (void *) DnDCPReset, NULL }, + { TOOLS_CORE_SIG_NO_RPC, (void *) DnDCPNoRpc, NULL }, { TOOLS_CORE_SIG_SET_OPTION, (void *) DnDCPSetOption, NULL }, { TOOLS_CORE_SIG_SHUTDOWN, (void *) DnDCPShutdown, NULL } }; diff --git a/open-vm-tools/services/plugins/dndcp/vmCopyPasteDnDWrapper.cpp b/open-vm-tools/services/plugins/dndcp/vmCopyPasteDnDWrapper.cpp index aa58faed2..b7cbb0e4e 100644 --- a/open-vm-tools/services/plugins/dndcp/vmCopyPasteDnDWrapper.cpp +++ b/open-vm-tools/services/plugins/dndcp/vmCopyPasteDnDWrapper.cpp @@ -22,6 +22,8 @@ * The inherited implementation of common class CopyPasteDnDWrapper in VM side. */ +#define G_LOG_DOMAIN "dndcp" + #include "guestDnDCPMgr.hh" #include "vmCopyPasteDnDWrapper.h" #include "vmware.h" @@ -40,7 +42,7 @@ extern "C" { * Timer callback for reset. Handle it by calling the member function * that handles reset. * - * @param[in] clientData pointer to the CopyPasteDnDWrapper instance that + * @param[in] clientData pointer to the VMCopyPasteDnDWrapper instance that * issued the timer. * * @return FALSE always. @@ -49,10 +51,12 @@ extern "C" { static gboolean DnDPluginResetSent(void *clientData) { - CopyPasteDnDWrapper *p = reinterpret_cast(clientData); + VMCopyPasteDnDWrapper *p = reinterpret_cast(clientData); + g_debug("%s: enter\n", __FUNCTION__); ASSERT(p); p->OnResetInternal(); + p->RemoveDnDPluginResetTimer(); return FALSE; } @@ -96,13 +100,31 @@ VMCopyPasteDnDWrapper::Init(ToolsAppCtx *ctx) void VMCopyPasteDnDWrapper::AddDnDPluginResetTimer(void) { - GSource *src; + g_debug("%s: enter\n", __FUNCTION__); + + ASSERT(m_resetTimer == NULL); + + m_resetTimer = VMTools_CreateTimer(RPC_POLL_TIME * 30); + if (m_resetTimer) { + VMTOOLSAPP_ATTACH_SOURCE(m_ctx, m_resetTimer, + DnDPluginResetSent, this, NULL); + } +} + +/** + * + * Remove the DnD plugin reset timer. + */ + +void +VMCopyPasteDnDWrapper::RemoveDnDPluginResetTimer(void) +{ g_debug("%s: enter\n", __FUNCTION__); - src = VMTools_CreateTimer(RPC_POLL_TIME * 30); - if (src) { - VMTOOLSAPP_ATTACH_SOURCE(m_ctx, src, DnDPluginResetSent, this, NULL); - g_source_unref(src); + if (m_resetTimer) { + g_source_destroy(m_resetTimer); + g_source_unref(m_resetTimer); + m_resetTimer = NULL; } } diff --git a/open-vm-tools/services/plugins/dndcp/vmCopyPasteDnDWrapper.h b/open-vm-tools/services/plugins/dndcp/vmCopyPasteDnDWrapper.h index eebcaff25..4de6dfb18 100644 --- a/open-vm-tools/services/plugins/dndcp/vmCopyPasteDnDWrapper.h +++ b/open-vm-tools/services/plugins/dndcp/vmCopyPasteDnDWrapper.h @@ -41,17 +41,19 @@ public: virtual int GetDnDVersion(); virtual void OnResetInternal(); virtual gboolean OnSetOption(const char *option, const char *value); + void RemoveDnDPluginResetTimer(void); protected: void AddDnDPluginResetTimer(void); private: - VMCopyPasteDnDWrapper() : m_ctx(NULL) { } + VMCopyPasteDnDWrapper() : m_ctx(NULL), m_resetTimer(NULL) { } VMCopyPasteDnDWrapper(const VMCopyPasteDnDWrapper &wrapper); VMCopyPasteDnDWrapper& operator=(const VMCopyPasteDnDWrapper &wrapper); private: ToolsAppCtx *m_ctx; + GSource *m_resetTimer; }; #endif // __VM_COPYPASTEDNDWRAPPER_H__ diff --git a/open-vm-tools/services/vmtoolsd/mainPosix.c b/open-vm-tools/services/vmtoolsd/mainPosix.c index 28293c4f5..32f7b1251 100644 --- a/open-vm-tools/services/vmtoolsd/mainPosix.c +++ b/open-vm-tools/services/vmtoolsd/mainPosix.c @@ -105,6 +105,9 @@ ToolsCoreSigUsrHandler(const siginfo_t *info, if (TOOLS_IS_USER_SERVICE(&gState.ctx)) { g_info("Shutting down guestrpc on signal USR1 ...\n"); + g_signal_emit_by_name(gState.ctx.serviceObj, + TOOLS_CORE_SIG_NO_RPC, + &gState.ctx); RpcChannel_Destroy(gState.ctx.rpc); gState.ctx.rpc = NULL; } diff --git a/open-vm-tools/services/vmtoolsd/serviceObj.c b/open-vm-tools/services/vmtoolsd/serviceObj.c index 1dbd4eda2..6538fc5fe 100644 --- a/open-vm-tools/services/vmtoolsd/serviceObj.c +++ b/open-vm-tools/services/vmtoolsd/serviceObj.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2008-2016 VMware, Inc. All rights reserved. + * Copyright (C) 2008-2018 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -356,6 +356,16 @@ ToolsCore_Service_class_init(gpointer _klass, G_TYPE_NONE, 1, G_TYPE_POINTER); + g_signal_new(TOOLS_CORE_SIG_NO_RPC, + G_OBJECT_CLASS_TYPE(klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); g_signal_new(TOOLS_CORE_SIG_SET_OPTION, G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST,