static void
ToolsCoreCleanup(ToolsServiceState *state)
{
   ToolsCorePool_Shutdown(&state->ctx);
   ToolsCore_UnloadPlugins(state);
   if (state->ctx.rpc != NULL) {
      RpcChannel_Stop(state->ctx.rpc);
      RpcChannel_Destroy(state->ctx.rpc);
      state->ctx.rpc = NULL;
   }
   g_key_file_free(state->ctx.config);
   g_main_loop_unref(state->ctx.mainLoop);

#if defined(G_PLATFORM_WIN32)
   if (state->ctx.comInitialized) {
      CoUninitialize();
      state->ctx.comInitialized = FALSE;
   }
#endif

#if !defined(_WIN32)
   if (state->ctx.envp) {
      System_FreeNativeEnviron(state->ctx.envp);
      state->ctx.envp = NULL;
   }
#endif

   g_object_set(state->ctx.serviceObj, TOOLS_CORE_PROP_CTX, NULL, NULL);
   g_object_unref(state->ctx.serviceObj);
   state->ctx.serviceObj = NULL;
   state->ctx.config = NULL;
   state->ctx.mainLoop = NULL;
}
Exemple #2
0
static gboolean
ReloadSelf(const siginfo_t *info,
           gpointer data)
{
   ToolsAppCtx *ctx = data;
   if (ctx->rpc != NULL) {
      RpcChannel_Stop(ctx->rpc);
   }
   Reload_Do();
   return FALSE;
}
static int
DEXIOErrorHandler(Display *dpy)
{
   pid_t my_pid = getpid();

   /*
    * ProcMgr_ExecAsync() needs to fork off a child to handle watching the
    * process being run.  When it dies, it will come through here, so we don't
    * want to let it shut down the RPC channel.
    */
   if (my_pid == gParentPid) {
      g_debug("%s", __func__);

      /*
       * Inform clients capable of/interested in quick'n'dirty cleanup upon an
       * X I/O error.
       */
      g_signal_emit_by_name(gCtx->serviceObj, TOOLS_CORE_SIG_XIOERROR, gCtx);

      /*
       * XXX: the really correct thing to do here would be to properly stop all
       * plugins so that capabilities are unset and all other "clean shutdown"
       * tasks are performed. Unfortunately two things currently prevent that:
       *
       * . we can't rely on g_main_loop_quit() because we can't return from this
       *   function (well, we can, but Xlib will exit() before vmtoolsd is able
       *   to clean up things), so the main loop will never regain control off
       *   the app.
       *
       * . we can't access the internal vmtoolsd functions that cleanly shuts
       *   down plugins.
       *
       * So, right now, let's stick with just stopping the RPC channel so that
       * the host is notified the application is gone. This may cause temporary
       * issues with clients that only look at capabilities and not at the
       * status of vmusr.
       */
      if (gCtx->rpc != NULL) {
         RpcChannel_Stop(gCtx->rpc);
      }
      exit(EXIT_FAILURE);
   } else {
      /*
       * _exit is used here so that any atexit() registered routines don't
       * interfere with any resources shared with the parent.
       */
      g_debug("%s hit from forked() child", __func__);
      _exit(EXIT_FAILURE);
   }

   return 1;
}
Exemple #4
0
gboolean
RpcChannel_SendOneRaw(const char *data,
                      size_t dataLen,
                      char **result,
                      size_t *resultLen)
{
   RpcChannel *chan;
   gboolean status;

   status = FALSE;

   chan = RpcChannel_New();
   if (chan == NULL) {
      if (result != NULL) {
         *result = Util_SafeStrdup("RpcChannel: Unable to create "
                                   "the RpcChannel object");
         if (resultLen != NULL) {
            *resultLen = strlen(*result);
         }
      }
      goto sent;
   } else if (!RpcChannel_Start(chan)) {
      if (result != NULL) {
         *result = Util_SafeStrdup("RpcChannel: Unable to open the "
                                   "communication channel");
         if (resultLen != NULL) {
            *resultLen = strlen(*result);
         }
      }
      goto sent;
   } else if (!RpcChannel_Send(chan, data, dataLen, result, resultLen)) {
      /* We already have the description of the error */
      goto sent;
   }

   status = TRUE;

sent:
   Debug(LGPFX "Request %s: reqlen=%"FMTSZ"u, replyLen=%"FMTSZ"u\n",
         status ? "OK" : "FAILED", dataLen, resultLen ? *resultLen : 0);
   if (chan) {
      RpcChannel_Stop(chan);
      RpcChannel_Destroy(chan);
   }

   return status;
}
Exemple #5
0
static gboolean
RpcChannelRestart(gpointer _chan)
{
   RpcChannelInt *chan = _chan;

   RpcChannel_Stop(&chan->impl);
   if (!RpcChannel_Start(&chan->impl)) {
      Warning("Channel restart failed [%d]\n", chan->rpcErrorCount);
      if (chan->resetCb != NULL) {
         chan->resetCb(&chan->impl, FALSE, chan->resetData);
      }
   } else {
      chan->rpcError = FALSE;
   }

   return FALSE;
}