]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Make Backdoor fallback temporary.
authorOliver Kurth <okurth@vmware.com>
Tue, 21 Apr 2020 21:52:10 +0000 (14:52 -0700)
committerOliver Kurth <okurth@vmware.com>
Tue, 21 Apr 2020 21:52:10 +0000 (14:52 -0700)
When RpcOut falls to Backdoor, it stays with Backdoor
permanently for the life of vmtoolsd service.  It is a
long standing bug in the reset handling code.  Typically,
channel type is not changed during reset.  Our reset
handling code can either keep the channel type same or
switch it from vsocket to Backdoor, but it can't do other
way.  Though it is supposed to switch to vsocket on reset
caused by events like vmtoolsd being restarted or VMX
breaking the channel for some VM management operation.
With this change when we start the channel, we always
try vsocket first unless Backdoor is enforced by the
caller.

Using Backdoor for too long is not desirable because
privileged RPCs can't be used on such channel.  So, we
need to retry switching the channel back to vsocket
periodically.  We don't want to try vsocket on every
RpcChannel_Send call because that adds to overhead and
increases the latency of RpcChannel_Send due to connection
timeouts.  So, we retry vsocket with a backoff delay
between 2sec-5min.

As some RpcChannel callers intend to use Backdoor channel
we need to differentiate between such usage from the
callers that create vsocket channel and fallback to
Backdoor.  Therefore, introduced a concept of mutable
channel.  The vsocket channel is mutable as it can fallback
to Backdoor and restore vsocket.  However, if a caller
creates Backdoor channel, it will not be mutable and
stay with Backdoor for its lifetime.

As vmxLogger frequently connects and disconnects the
channel for every log message and does not use any
privileged RPC, so make it use Backdoor channel
permanently to avoid frequent vsocket connections.

Additionally, removed the redundant 'stopRpcOut' interface
and renamed 'onStartErr' to 'destroy'.

open-vm-tools/lib/rpcChannel/bdoorChannel.c
open-vm-tools/lib/rpcChannel/rpcChannel.c
open-vm-tools/lib/rpcChannel/rpcChannelInt.h
open-vm-tools/lib/rpcChannel/vsockChannel.c
open-vm-tools/libvmtools/vmxLogger.c
open-vm-tools/tests/vmrpcdbg/debugChannel.c

index d3572a8d2084fd57c0521e8f6f9801dd4dea894d..b153d52b21802227581cceeb02815ce32d143868 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2008-2016,2018-2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2008-2016,2018-2020 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
@@ -38,9 +38,13 @@ typedef struct BackdoorChannel {
 
 
 /**
- * Starts the RpcIn loop and the RpcOut channel.
+ * Starts the RpcOut channel.
  *
- * No-op if channels are already started.
+ * No-op if channels are already started. If RpcIn
+ * channel is needed, it must have been started
+ * before calling this function.
+ *
+ * In case of error, stops RpcIn.
  *
  * @param[in]  chan     The RPC channel instance.
  *
@@ -99,25 +103,6 @@ BkdoorChannelStop(RpcChannel *chan)
 }
 
 
-/**
- * Shuts down the RpcIn channel. Due to the "split brain" nature of the backdoor,
- * if this function fails, it's possible that while the "out" channel was shut
- * down the "in" one wasn't, for example, although that's unlikely.
- *
- * @param[in]  chan     The RPC channel instance.
- */
-
-static void
-BkdoorChannelShutdown(RpcChannel *chan)
-{
-   BackdoorChannel *bdoor = chan->_private;
-   BkdoorChannelStop(chan);
-   RpcOut_Destruct(bdoor->out);
-   g_free(bdoor);
-   chan->_private = NULL;
-}
-
-
 /**
  * Sends the data using the RpcOut library.
  *
@@ -206,12 +191,52 @@ exit:
 }
 
 
+/**
+ * Callback function to destroy the Backdoor channel after
+ * it fails to start or it has been stopped.
+ *
+ * @param[in]  chan     The RPC channel instance.
+ */
+
+static void
+BkdoorChannelDestroy(RpcChannel *chan)
+{
+   BackdoorChannel *bdoor = chan->_private;
+
+   /*
+    * Channel should be stopped before destroying it.
+    */
+   ASSERT(!chan->outStarted);
+   RpcOut_Destruct(bdoor->out);
+   g_free(bdoor);
+   chan->_private = NULL;
+}
+
+
+/**
+ * Shuts down the Backdoor RpcOut channel.
+ *
+ * Due to the "split brain" nature of the backdoor, if this function
+ * fails, it's possible that while the "out" channel was shut down
+ * the "in" one wasn't, for example, although that's unlikely.
+ *
+ * @param[in]  chan     The RPC channel instance.
+ */
+
+static void
+BkdoorChannelShutdown(RpcChannel *chan)
+{
+   BkdoorChannelStop(chan);
+   BkdoorChannelDestroy(chan);
+}
+
+
 /**
  * Return the channel type.
  *
  * @param[in]  chan     RpcChannel
  *
- * @return backdoor channel type.
+ * @return RpcChannelType.
  */
 
 static RpcChannelType
@@ -237,8 +262,7 @@ BackdoorChannelSetCallbacks(RpcChannel *chan)
       NULL,
       BkdoorChannelShutdown,
       BkdoorChannelGetType,
-      NULL,
-      NULL
+      BkdoorChannelDestroy
    };
 
    ASSERT(chan);
@@ -268,6 +292,11 @@ BackdoorChannel_New(void)
    ret->inStarted = FALSE;
 #endif
    ret->outStarted = FALSE;
+   /*
+    * Backdoor channel is not mutable as it has no
+    * fallback option available.
+    */
+   ret->isMutable = FALSE;
 
    BackdoorChannelSetCallbacks(ret);
    ret->_private = bdoor;
@@ -281,11 +310,9 @@ BackdoorChannel_New(void)
  * Fall back to backdoor when another type of RpcChannel fails to start.
  *
  * @param[in]  chan     RpcChannel
- *
- * @return TRUE on success.
  */
 
-gboolean
+void
 BackdoorChannel_Fallback(RpcChannel *chan)
 {
    BackdoorChannel *bdoor;
@@ -299,7 +326,4 @@ BackdoorChannel_Fallback(RpcChannel *chan)
 
    BackdoorChannelSetCallbacks(chan);
    chan->_private = bdoor;
-
-   return chan->funcs->start(chan);
 }
-
index c1cc9e8479e63176a0a62cb717482d80744c4e4a..1631fee0e15faadc513ca89682c853404bcff65b 100644 (file)
@@ -72,11 +72,17 @@ typedef struct RpcChannelInt {
 static gboolean gUseBackdoorOnly = FALSE;
 
 /*
- * Track the vSocket connection failure, so that we can
- * avoid using vSockets until a channel reset/restart or
- * the service itself gets restarted.
+ * Delay in seconds before retrying vSocket after
+ * falling back to Backdoor (min=2sec, max=5min).
+ *
+ * Trying vSocket when it is not working can lead to
+ * futile attempts with almost each attempt taking 2s
+ * to timeout. To avoid this delay, don't attempt to use
+ * vSocket for a while.
  */
-static gboolean gVSocketFailed = FALSE;
+#define RPCCHANNEL_VSOCKET_RETRY_MIN_DELAY    (2)
+#define RPCCHANNEL_VSOCKET_RETRY_MAX_DELAY    (5 * 60)
+
 
 static void RpcChannelStopNoLock(RpcChannel *chan);
 
@@ -128,9 +134,12 @@ RpcChannelRestart(gpointer _chan)
 
    RpcChannelStopNoLock(&chan->impl);
 
-   /* Clear vSocket channel failure */
-   Log(LGPFX "Clearing backdoor behavior ...\n");
-   gVSocketFailed = FALSE;
+   if (chan->impl.vsockFailureTS != 0) {
+      /* Clear vSocket channel failure */
+      Log(LGPFX "Clearing backdoor behavior ...\n");
+      chan->impl.vsockFailureTS = 0;
+      chan->impl.vsockRetryDelay = RPCCHANNEL_VSOCKET_RETRY_MIN_DELAY;
+   }
 
    chanStarted = RpcChannel_Start(&chan->impl);
    g_mutex_unlock(&chan->impl.outLock);
@@ -186,8 +195,12 @@ RpcChannelCheckReset(gpointer _chan)
    /* Reset was successful. */
    Log(LGPFX "Channel was reset successfully.\n");
    chan->rpcResetErrorCount = 0;
-   Log(LGPFX "Clearing backdoor behavior ...\n");
-   gVSocketFailed = FALSE;
+
+   if (chan->impl.vsockFailureTS != 0) {
+      Log(LGPFX "Clearing backdoor behavior ...\n");
+      chan->impl.vsockFailureTS = 0;
+      chan->impl.vsockRetryDelay = RPCCHANNEL_VSOCKET_RETRY_MIN_DELAY;
+   }
 
    if (chan->resetCb != NULL) {
       chan->resetCb(&chan->impl, TRUE, chan->resetData);
@@ -630,8 +643,8 @@ RpcChannelClearError(void *_chan)
 {
    RpcChannelInt *chan = _chan;
 
-   Debug(LGPFX " %s: Clearing cumulative RpcChannel error count; was %d\n",
-         __FUNCTION__, chan->rpcFailureCount);
+   Debug(LGPFX "Clearing cumulative RpcChannel error count; was %d\n",
+         chan->rpcFailureCount);
    chan->rpcFailureCount = 0;
 }
 
@@ -697,6 +710,7 @@ RpcChannel *
 RpcChannel_Create(void)
 {
    RpcChannelInt *chan = g_new0(RpcChannelInt, 1);
+   chan->impl.vsockRetryDelay = RPCCHANNEL_VSOCKET_RETRY_MIN_DELAY;
    return &chan->impl;
 }
 
@@ -819,8 +833,7 @@ RpcChannel_NewOne(int flags)
 {
    RpcChannel *chan;
 #if (defined(__linux__) && !defined(USERWORLD)) || defined(_WIN32)
-   chan = (gUseBackdoorOnly || gVSocketFailed) ?
-          BackdoorChannel_New() : VSockChannel_New(flags);
+   chan = gUseBackdoorOnly ? BackdoorChannel_New() : VSockChannel_New(flags);
 #else
    chan = BackdoorChannel_New();
 #endif
@@ -878,18 +891,50 @@ RpcChannel_Start(RpcChannel *chan)
 #endif
 
    funcs = chan->funcs;
+
+#if (defined(__linux__) && !defined(USERWORLD)) || defined(_WIN32)
+   if (!gUseBackdoorOnly && chan->isMutable &&
+       funcs->getType(chan) == RPCCHANNEL_TYPE_BKDOOR) {
+      /*
+       * Try vsocket first for mutable channel.
+       * Existing channel needs to be destroyed before switching.
+       */
+      Log(LGPFX "Restore vsocket RpcOut channel ...\n");
+      funcs->destroy(chan);
+      VSockChannel_Restore(chan, chan->vsockChannelFlags);
+      funcs = chan->funcs;
+   }
+#endif
+
    ok = funcs->start(chan);
 
-   if (!ok && funcs->onStartErr != NULL) {
-      Log(LGPFX "Fallback to backdoor ...\n");
-      funcs->onStartErr(chan);
-      ok = BackdoorChannel_Fallback(chan);
+   /*
+    * Try to fallback to Backdoor channel if the failed
+    * channel is mutable and is not a Backdoor channel.
+    */
+   if (!ok && chan->isMutable &&
+       funcs->getType(chan) != RPCCHANNEL_TYPE_BKDOOR) {
+      Log(LGPFX "Fallback to backdoor RpcOut channel ...\n");
+      funcs->destroy(chan);
+      BackdoorChannel_Fallback(chan);
+      funcs = chan->funcs;
+      ok = funcs->start(chan);
+
       /*
        * As vSocket is not available, we stick the backdoor
-       * behavior until the channel is reset/restarted.
+       * behavior until the channel is reset/restarted or
+       * retry delay has passed.
+       */
+      chan->vsockFailureTS = time(NULL);
+      /*
+       * Backoff retry attempts. Cap the delay at max value.
        */
-      Log(LGPFX "Sticking backdoor behavior ...\n");
-      gVSocketFailed = TRUE;
+      chan->vsockRetryDelay *= 2;
+      if (chan->vsockRetryDelay > RPCCHANNEL_VSOCKET_RETRY_MAX_DELAY) {
+         chan->vsockRetryDelay = RPCCHANNEL_VSOCKET_RETRY_MAX_DELAY;
+      }
+      Log(LGPFX "Sticking backdoor RpcOut channel for %u seconds.\n",
+          chan->vsockRetryDelay);
    }
 
    return ok;
@@ -1015,18 +1060,55 @@ RpcChannel_Send(RpcChannel *chan,
       *resultLen = 0;
    }
 
+#if (defined(__linux__) && !defined(USERWORLD)) || defined(_WIN32)
+   if (chan->isMutable &&
+       funcs->getType(chan) == RPCCHANNEL_TYPE_BKDOOR) {
+      /*
+       * Switch the channel type if it has been long enough
+       * time since last vsocket failure.
+       */
+      gboolean tryVSocket = (chan->vsockFailureTS == 0 ||
+                             (time(NULL) - chan->vsockFailureTS) >=
+                             chan->vsockRetryDelay);
+      if (tryVSocket && funcs->stop != NULL) {
+         Log(LGPFX "Stop backdoor RpcOut channel and try vsock again ...\n");
+         /*
+          * Stop existing RpcOut channel and start it again.
+          * RpcChannel_Start will switch it to vsocket when
+          * possible or fallback to Backdoor again.
+          */
+         funcs->stop(chan);
+         if (!RpcChannel_Start(chan)) {
+            ok = FALSE;
+            goto exit;
+         }
+         funcs = chan->funcs;
+         ASSERT(funcs->send);
+      }
+   }
+#endif
+
    ok = funcs->send(chan, data, dataLen, &rpcStatus, &res, &resLen);
 
    if (!ok && (funcs->getType(chan) != RPCCHANNEL_TYPE_BKDOOR) &&
-       (funcs->stopRpcOut != NULL)) {
+       (funcs->stop != NULL)) {
 
       free(res);
       res = NULL;
       resLen = 0;
 
       /* retry once */
-      Log(LGPFX "Stop RpcOut channel and try to send again ...\n");
-      funcs->stopRpcOut(chan);
+      Log(LGPFX "Stop vsock RpcOut channel and try to send again ...\n");
+      funcs->stop(chan);
+      /*
+       * This is first send failure on vsocket RpcOut channel.
+       * So, we re-init the failure timestamp and retry delay
+       * because RpcChannel_Start tries vsocket first. In case
+       * RpcChannel_Start falls back to Backdoor these will be
+       * set appropriately.
+       */
+      chan->vsockFailureTS = 0;
+      chan->vsockRetryDelay = RPCCHANNEL_VSOCKET_RETRY_MIN_DELAY;
       if (RpcChannel_Start(chan)) {
          /* The channel may get switched from vsocket to backdoor */
          funcs = chan->funcs;
index 00b2e24d927357b97fcf99536ec6003cd9b79a8d..e0993e3d4cc591e2197ffc14d18011a2389897a8 100644 (file)
@@ -60,8 +60,7 @@ typedef struct _RpcChannelFuncs{
                  const char *appName, gpointer appCtx);
    void (*shutdown)(RpcChannel *);
    RpcChannelType (*getType)(RpcChannel *chan);
-   void (*onStartErr)(RpcChannel *);
-   gboolean (*stopRpcOut)(RpcChannel *);
+   void (*destroy)(RpcChannel *);
 } RpcChannelFuncs;
 
 /**
@@ -71,23 +70,39 @@ typedef struct _RpcChannelFuncs{
  * channels, their state (inStarted/outStarted) and _private data.
  */
 struct _RpcChannel {
-   const RpcChannelFuncs     *funcs;
-   gpointer                  _private;
+   const RpcChannelFuncs *funcs;
+   gpointer _private;
 #if defined(NEED_RPCIN)
-   GMainContext              *mainCtx;
-   const char                *appName;
-   gpointer                  appCtx;
+   GMainContext *mainCtx;
+   const char *appName;
+   gpointer appCtx;
+   struct RpcIn *in;
+   gboolean inStarted;
 #endif
-   GMutex                    outLock;
-#if defined(NEED_RPCIN)
-   struct RpcIn              *in;
-   gboolean                  inStarted;
-#endif
-   gboolean                  outStarted;
+   GMutex outLock;
+   gboolean outStarted;
+   int vsockChannelFlags;
+   /*
+    * Only vsocket channel is mutable as it can fallback to Backdoor.
+    * If a channel is created as Backdoor, it will not be mutable.
+    */
+   gboolean isMutable;
+   /*
+    * Track the last vsocket connection failure timestamp.
+    * Avoid using vsocket until a channel reset/restart
+    * occurs, the service restarts or retry delay has passed
+    * since the last failure.
+    */
+   uint64 vsockFailureTS;
+   /*
+    * Amount of time to delay next vsocket retry attempt.
+    * It varies between RPCCHANNEL_VSOCKET_RETRY_MIN_DELAY
+    * and RPCCHANNEL_VSOCKET_RETRY_MAX_DELAY.
+    */
+   uint32 vsockRetryDelay;
 };
 
-gboolean
-BackdoorChannel_Fallback(RpcChannel *chan);
+void BackdoorChannel_Fallback(RpcChannel *chan);
+void VSockChannel_Restore(RpcChannel *chan, int flags);
 
 #endif /* _RPCCHANNELINT_H_ */
-
index 66997c1b235f5cefdf1e3cd8e5fdc62af1bc555b..200781a0679eb780d88b4bdabc00c2bec3fa962f 100644 (file)
@@ -171,7 +171,7 @@ VSockOutDestruct(VSockOut *out)        // IN
  *
  * VSockOutStart --
  *
- *      Open the channel
+ *      Start the VSockOut channel by creating a vsocket connection.
  *
  * Result:
  *      TRUE on success
@@ -205,7 +205,7 @@ VSockOutStart(VSockOut *out)      // IN
  *
  * VSockOutStop --
  *
- *    Close the channel
+ *    Close the underlying vsocket for the VSockOut channel
  *
  * Result
  *    None
@@ -309,9 +309,10 @@ error:
 /*
  *-----------------------------------------------------------------------------
  *
- * VSockChannelOnStartErr --
+ * VSockChannelDestroy --
  *
- *      Callback function to cleanup after channel start failure.
+ *      Callback function to destroy the VSockChannel after it fails to start
+ *      or it has been stopped.
  *
  * Results:
  *      None.
@@ -323,10 +324,14 @@ error:
  */
 
 static void
-VSockChannelOnStartErr(RpcChannel *chan)    // IN
+VSockChannelDestroy(RpcChannel *chan)    // IN
 {
    VSockChannel *vsock = chan->_private;
 
+   /*
+    * Channel should be stopped before destroying it.
+    */
+   ASSERT(!chan->outStarted);
    VSockOutDestruct(vsock->out);
    g_free(vsock);
    chan->_private = NULL;
@@ -338,7 +343,7 @@ VSockChannelOnStartErr(RpcChannel *chan)    // IN
  *
  * VSockChannelStart --
  *
- *      Starts the RpcIn loop and the VSockOut channel.
+ *      Starts the VSockOut channel.
  *
  * Results:
  *      TRUE on success.
@@ -424,7 +429,7 @@ VSockChannelStop(RpcChannel *chan)   // IN
  *
  * VSockChannelShutdown --
  *
- *      Shuts down the Rpc channel.
+ *      Shuts down the VSockChannel.
  *
  * Results:
  *      None.
@@ -438,12 +443,8 @@ VSockChannelStop(RpcChannel *chan)   // IN
 static void
 VSockChannelShutdown(RpcChannel *chan)    // IN
 {
-   VSockChannel *vsock = chan->_private;
-
    VSockChannelStop(chan);
-   VSockOutDestruct(vsock->out);
-   g_free(vsock);
-   chan->_private = NULL;
+   VSockChannelDestroy(chan);
 }
 
 
@@ -515,12 +516,12 @@ exit:
 /*
  *-----------------------------------------------------------------------------
  *
- * VSockChannel_GetType --
+ * VSockChannelGetType --
  *
- *      Return the channel type that being used.
+ *      Return the channel type that is being used.
  *
  * Result:
- *      return the channel type.
+ *      return RpcChannelType
  *
  * Side-effects:
  *      None
@@ -529,7 +530,7 @@ exit:
  */
 
 static RpcChannelType
-VSockChannelGetType(RpcChannel *chan)
+VSockChannelGetType(RpcChannel *chan)     // IN
 {
    VSockChannel *vsock = chan->_private;
 
@@ -544,12 +545,12 @@ VSockChannelGetType(RpcChannel *chan)
 /*
  *-----------------------------------------------------------------------------
  *
- * VSockChannelStopRpcOut --
+ * VSockChannelSetCallbacks --
  *
- *      Stop the RpcOut channel
+ *      Helper function to setup RpcChannel callbacks.
  *
  * Result:
- *      return TRUE on success.
+ *      None
  *
  * Side-effects:
  *      None
@@ -557,25 +558,30 @@ VSockChannelGetType(RpcChannel *chan)
  *-----------------------------------------------------------------------------
  */
 
-static gboolean
-VSockChannelStopRpcOut(RpcChannel *chan)
+static void
+VSockChannelSetCallbacks(RpcChannel *chan)      // IN
 {
-   VSockChannel *vsock = chan->_private;
-   VSockOutStop(vsock->out);
-   chan->outStarted = FALSE;
+   static RpcChannelFuncs funcs = {
+      VSockChannelStart,
+      VSockChannelStop,
+      VSockChannelSend,
+      NULL,
+      VSockChannelShutdown,
+      VSockChannelGetType,
+      VSockChannelDestroy
+   };
 
-   return TRUE;
+   ASSERT(chan);
+   chan->funcs = &funcs;
 }
 
 
-
-
 /*
  *-----------------------------------------------------------------------------
  *
  * VSockChannel_New --
  *
- *      Creates a new RpcChannel channel that uses the vsocket for
+ *      Creates a new RpcChannel that uses the vsocket for
  *      communication.
  *
  * Result:
@@ -588,22 +594,11 @@ VSockChannelStopRpcOut(RpcChannel *chan)
  */
 
 RpcChannel *
-VSockChannel_New(int flags)
+VSockChannel_New(int flags)   // IN
 {
    RpcChannel *chan;
    VSockChannel *vsock;
 
-   static RpcChannelFuncs funcs = {
-      VSockChannelStart,
-      VSockChannelStop,
-      VSockChannelSend,
-      NULL,
-      VSockChannelShutdown,
-      VSockChannelGetType,
-      VSockChannelOnStartErr,
-      VSockChannelStopRpcOut
-   };
-
    chan = RpcChannel_Create();
    vsock = g_malloc0(sizeof *vsock);
 
@@ -614,10 +609,49 @@ VSockChannel_New(int flags)
    chan->inStarted = FALSE;
 #endif
    chan->outStarted = FALSE;
+   chan->vsockChannelFlags = flags;
+   /*
+    * VSock channel is mutable, it can fallback/change to Backdoor.
+    */
+   chan->isMutable = TRUE;
 
+   VSockChannelSetCallbacks(chan);
    chan->_private = vsock;
-   chan->funcs = &funcs;
    g_mutex_init(&chan->outLock);
 
    return chan;
 }
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VSockChannel_Restore --
+ *
+ *      Restores RpcChannel as VSockChannel.
+ *
+ * Result:
+ *      None
+ *
+ * Side-effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+VSockChannel_Restore(RpcChannel *chan,    // IN
+                     int flags)           // IN
+{
+   VSockChannel *vsock;
+
+   ASSERT(chan);
+   ASSERT(chan->_private == NULL);
+
+   vsock = g_malloc0(sizeof *vsock);
+   vsock->out = VSockOutConstruct(flags);
+   ASSERT(vsock->out != NULL);
+
+   VSockChannelSetCallbacks(chan);
+   chan->_private = vsock;
+}
index bfc6e86918eef27249e8b9af5c711c403f3d75f4..cc53193dfab3f73695c02611f0edf9a1d96cad2a 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2010-2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2010-2020 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
@@ -110,7 +110,7 @@ VMToolsCreateVMXLogger(void)
    data->handler.addsTimestamp = TRUE;
    data->handler.shared = TRUE;
    data->handler.dtor = VMXLoggerDestroy;
-   data->chan = RpcChannel_New();
+   data->chan = BackdoorChannel_New();
    return &data->handler;
 }
 
index 604da5e09eff212a27ac46602af07b46793546a1..399dedd2d0a966d78900ff1e2177e3210cc1e82f 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2008-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2008-2016,2020 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
@@ -325,7 +325,6 @@ RpcDebug_NewDebugChannel(ToolsAppCtx *ctx,
       RpcDebugSetup,
       RpcDebugShutdown,
       NULL,
-      NULL,
       NULL
    };