]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Clear DnDPluginResetTimer on receiving SIGUSR1.
authorOliver Kurth <okurth@vmware.com>
Fri, 26 Oct 2018 17:45:00 +0000 (10:45 -0700)
committerOliver Kurth <okurth@vmware.com>
Fri, 26 Oct 2018 17:45:00 +0000 (10:45 -0700)
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.

open-vm-tools/lib/include/vmware/tools/plugin.h
open-vm-tools/services/plugins/dndcp/copyPasteCompatX11.c
open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDWrapper.cpp
open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDWrapper.h
open-vm-tools/services/plugins/dndcp/dndcp.cpp
open-vm-tools/services/plugins/dndcp/vmCopyPasteDnDWrapper.cpp
open-vm-tools/services/plugins/dndcp/vmCopyPasteDnDWrapper.h
open-vm-tools/services/vmtoolsd/mainPosix.c
open-vm-tools/services/vmtoolsd/serviceObj.c

index 786b7a7e84c8834c6d15804b0a1bf4b688f9927c..eaf82a57572bab2aad1a5bb5445dc51e1e2d749b 100644 (file)
@@ -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.
  *
index d5a0fdf971c25627c7eaec16859de00f36e20699..20b2cc0116c618eb4fca04c56303ebe6c63ebffe 100644 (file)
@@ -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 <stdlib.h>
 #include <string.h>
index 1879afd61b0ad5043c0f975eb30d692b80b4d4e4..a4716d7700a5ebb1d270b80e703e2502920c56b4 100644 (file)
@@ -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
index ac18845551ccc1e44274cab81f7e0be2ac2a0b89..a4d0f8fa3486ec8123e4520bee76bee2f5b61bb7 100644 (file)
@@ -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:
    /*
index 82fe381502db22a920809b96353e662011f535ed..292fd19b190fa65db4db6e18e5fa77554e940b3e 100644 (file)
@@ -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 }
       };
index aa58faed27044a1015acc3747d809d7e3b1a3299..b7cbb0e4ecae1808b2d1e385a0f813e0fa988835 100644 (file)
@@ -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<CopyPasteDnDWrapper *>(clientData);
+   VMCopyPasteDnDWrapper *p = reinterpret_cast<VMCopyPasteDnDWrapper *>(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;
    }
 }
 
index eebcaff2545b5b7ffebb5ab46f052c4d05d4577e..4de6dfb18b8cb257b6dd64fca1a23d86c79c9847 100644 (file)
@@ -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__
index 28293c4f5894fb9fcf131ee5ef8eb6a4d506989e..32f7b12510ad51a6a2046f73c51ce76cd4fb38a8 100644 (file)
@@ -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;
    }
index 1dbd4eda20f3b151090d719314a323d69c77676b..6538fc5fe401a6a470dea41c0c50b47b70b26a84 100644 (file)
@@ -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,