]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Clear channel restart timer when RPC channel is destroyed.
authorOliver Kurth <okurth@vmware.com>
Fri, 26 Oct 2018 17:44:59 +0000 (10:44 -0700)
committerOliver Kurth <okurth@vmware.com>
Fri, 26 Oct 2018 17:44:59 +0000 (10:44 -0700)
Vmusr main loop destroys the RPC channel when it receives SIGUSR1.
However, it may have left the restart timer around that would end
up accessing the destroyed channel structure. So, we destroy the
timer along with the RPC channel to be safe.

open-vm-tools/lib/rpcChannel/rpcChannel.c
open-vm-tools/services/vmtoolsd/mainPosix.c

index 5e7eb568023cee76a9b7ae7aabaa8016bec7378a..5e9548ab92728bd2ffcf5f3657a3387bb4f860af 100644 (file)
@@ -63,6 +63,7 @@ typedef struct RpcChannelInt {
    RpcChannelFailureCb     rpcFailureCb;
    guint                   rpcMaxFailures;
    gboolean                rpcInInitialized;
+   GSource                *restartTimer; /* Channel restart timer */
 #endif
 } RpcChannelInt;
 
@@ -122,6 +123,8 @@ RpcChannelRestart(gpointer _chan)
 
    /* Synchronize with any RpcChannel_Send calls by other threads. */
    g_static_mutex_lock(&chan->impl.outLock);
+   g_source_unref(chan->restartTimer);
+   chan->restartTimer = NULL;
 
    RpcChannelStopNoLock(&chan->impl);
 
@@ -161,7 +164,6 @@ RpcChannelCheckReset(gpointer _chan)
 
    /* Check the channel state. */
    if (chan->rpcError) {
-      GSource *src;
 
       if (++(chan->rpcResetErrorCount) > channelTimeoutAttempts) {
          Warning("Failed to reset channel after %u attempts\n",
@@ -174,10 +176,10 @@ RpcChannelCheckReset(gpointer _chan)
 
       /* Schedule the channel restart for 1 sec in the future. */
       Debug(LGPFX "Resetting channel [%u]\n", chan->rpcResetErrorCount);
-      src = g_timeout_source_new(1000);
-      g_source_set_callback(src, RpcChannelRestart, chan, NULL);
-      g_source_attach(src, chan->mainCtx);
-      g_source_unref(src);
+      ASSERT(chan->restartTimer == NULL);
+      chan->restartTimer = g_timeout_source_new(1000);
+      g_source_set_callback(chan->restartTimer, RpcChannelRestart, chan, NULL);
+      g_source_attach(chan->restartTimer, chan->mainCtx);
       goto exit;
    }
 
@@ -507,6 +509,15 @@ RpcChannelTeardown(RpcChannel *chan)
       return;
    }
 
+   /*
+    * Stop the restartTimer.
+    */
+   if (cdata->restartTimer) {
+      g_source_destroy(cdata->restartTimer);
+      g_source_unref(cdata->restartTimer);
+      cdata->restartTimer = NULL;
+   }
+
    RpcChannel_UnregisterCallback(chan, &cdata->resetReg);
    for (i = 0; i < ARRAYSIZE(gRpcHandlers); i++) {
       RpcChannel_UnregisterCallback(chan, &gRpcHandlers[i]);
index c60f0690ee7f7899cae56c6352edb33b32d9135b..28293c4f5894fb9fcf131ee5ef8eb6a4d506989e 100644 (file)
@@ -103,8 +103,8 @@ ToolsCoreSigUsrHandler(const siginfo_t *info,
 {
    ToolsCore_DumpState(&gState);
 
-   g_info("Shutting down guestrpc on signal USR1 ...\n");
    if (TOOLS_IS_USER_SERVICE(&gState.ctx)) {
+      g_info("Shutting down guestrpc on signal USR1 ...\n");
       RpcChannel_Destroy(gState.ctx.rpc);
       gState.ctx.rpc = NULL;
    }