示例#1
0
static void
RpcInCloseChannel(RpcIn *in,               // IN
                  char const *errmsg)      // IN
{
   /* Call the error routine */
   (*in->errorFunc)(in->errorData, errmsg);
   RpcInStop(in);
   in->shouldStop = FALSE;
}
示例#2
0
void
RpcIn_stop(RpcIn *in) // IN
{
   if (in->inLoop) {
      in->shouldStop = TRUE;
   } else {
      RpcInStop(in);
   }
}
示例#3
0
static void
RpcInShutdown(RpcChannel *chan)
{
   BackdoorChannel *bdoor = chan->_private;
   RpcInStop(chan);
   if (bdoor->in != NULL) {
      RpcIn_Destruct(bdoor->in);
   }
   RpcOut_Destruct(bdoor->out);
   g_static_mutex_free(&bdoor->outLock);
   if (bdoor->mainCtx != NULL) {
      g_main_context_unref(bdoor->mainCtx);
   }
   g_free(bdoor);
}
示例#4
0
static Bool
RpcInOpenChannel(RpcIn *in,                 // IN
                 Bool useBackdoorOnly)      // IN
{
#if defined(VMTOOLS_USE_VSOCKET)
   static Bool first = TRUE;
   static Bool initOk = TRUE;
   AsyncSocket *asock;
   int res;

   ASSERT(in->conn == NULL);

   while (TRUE) {  /* one pass loop */
      if (useBackdoorOnly) {
         break;
      }

      if (first) {
         first = FALSE;
         res = AsyncSocket_Init();
         initOk = (res == ASOCKERR_SUCCESS);
         if (!initOk) {
            Debug("RpcIn: Error in socket initialization: %s\n",
                  AsyncSocket_Err2String(res));
            break;
         }
      }

      if (!initOk) {
         break;
      }

      in->conn = calloc(1, sizeof *(in->conn));
      if (in->conn == NULL) {
         Debug("RpcIn: Error in allocating memory for vsocket connection.\n");
         break;
      }
      in->conn->in = in;
      asock = AsyncSocket_ConnectVMCI(VMCI_HYPERVISOR_CONTEXT_ID,
                                      GUESTRPC_TCLO_VSOCK_LISTEN_PORT,
                                      RpcInConnectDone,
                                      in->conn, 0, NULL, &res);
      if (asock == NULL) {
         Debug("RpcIn: Error in creating vsocket connection: %s\n",
               AsyncSocket_Err2String(res));
      } else {
         res = AsyncSocket_SetErrorFn(asock, RpcInConnErrorHandler, in->conn);
         if (res != ASOCKERR_SUCCESS) {
            Debug("RpcIn: Error in setting error handler for vsocket %d\n",
                  AsyncSocket_GetFd(asock));
            AsyncSocket_Close(asock);
         } else {
            Debug("RpcIn: successfully created vsocket connection %d.\n",
                  AsyncSocket_GetFd(asock));
            in->conn->asock = asock;
            return TRUE;
         }
      }
      break;
   }

   if (in->conn != NULL) {
      free(in->conn);
      in->conn = NULL;
   }

#endif

   ASSERT(in->channel == NULL);
   in->channel = Message_Open(0x4f4c4354);
   if (in->channel == NULL) {
      Debug("RpcIn: couldn't open channel with TCLO protocol\n");
      goto error;
   }

   if (!RpcInScheduleRecvEvent(in)) {
      Debug("RpcIn_start: couldn't start the loop\n");
      goto error;
   }

   in->mustSend = TRUE;
   return TRUE;

error:
   RpcInStop(in);
   return FALSE;
}
示例#5
0
static gboolean
#else
static Bool
#endif
RpcInLoop(void *clientData) // IN
{
   RpcIn *in;
   char const *errmsg = NULL;
   char const *reply;
   size_t repLen;
   Bool resched = FALSE;

#if defined(VMTOOLS_USE_GLIB)
   unsigned int current;
#endif

   in = (RpcIn *)clientData;
   ASSERT(in);
   ASSERT(in->nextEvent);
   ASSERT(in->channel);
   ASSERT(in->mustSend);

#if defined(VMTOOLS_USE_GLIB)
   current = in->delay;
#else
   /*
    * The event has fired: it is no longer valid. Note that this is
    * not true in the glib case!
    */
   in->nextEvent = NULL;
#endif

   in->inLoop = TRUE;

   /*
    * Workaround for bug 780404. Remove if we ever figure out the root cause.
    * Note that the ASSERT above catches this on non-release builds.
    */
   if (in->channel == NULL) {
      errmsg = "RpcIn: Channel is not active";
      goto error;
   }

   /*
    * This is very important: this is the only way to signal the existence of
    * this guest application to VMware.
    */
   if (RpcInSend(in, 0) == FALSE) {
      errmsg = "RpcIn: Unable to send";
      goto error;
   }

   if (Message_Receive(in->channel, (unsigned char **)&reply, &repLen) == FALSE) {
      errmsg = "RpcIn: Unable to receive";
      goto error;
   }

   if (repLen) {
      if (!RpcInExecRpc(in, reply, repLen, &errmsg)) {
         goto error;
      }
   } else {
      /*
       * Nothing to execute
       */

      /* No request -> No result */
      ASSERT(in->last_result == NULL);
      ASSERT(in->last_resultLen == 0);

      RpcInUpdateDelayTime(in);
   }

   ASSERT(in->mustSend == FALSE);
   in->mustSend = TRUE;

   if (!in->shouldStop) {
      Bool needResched = TRUE;
#if defined(VMTOOLS_USE_GLIB)
      resched = in->delay != current;
      needResched = resched;
#endif
      if (needResched && !RpcInScheduleRecvEvent(in)) {
         errmsg = "RpcIn: Unable to run the loop";
         goto error;
      }
   }

exit:
   if (in->shouldStop) {
      RpcInStop(in);
      in->shouldStop = FALSE;
#if defined(VMTOOLS_USE_GLIB)
      /* Force the GMainContext to unref the GSource that runs the RpcIn loop. */
      resched = TRUE;
#endif
   }

   in->inLoop = FALSE;

   return !resched;

error:
   /* Call the error routine */
   (*in->errorFunc)(in->errorData, errmsg);
   in->shouldStop = TRUE;
   goto exit;
}