]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Change to common source files not applicable to open-vm-tools.
authorKruti Pendharkar <kp025370@broadcom.com>
Wed, 8 Jan 2025 06:05:49 +0000 (22:05 -0800)
committerKruti Pendharkar <kp025370@broadcom.com>
Wed, 8 Jan 2025 06:05:49 +0000 (22:05 -0800)
open-vm-tools/lib/include/vmware/tools/plugin.h
open-vm-tools/services/plugins/gdp/gdpPlugin.c
open-vm-tools/services/plugins/serviceDiscovery/serviceDiscovery.c
open-vm-tools/services/vmtoolsd/mainLoop.c
open-vm-tools/services/vmtoolsd/serviceObj.c
open-vm-tools/tests/testPlugin/testPlugin.c

index 91c74e1814fc4c517b345bfaef081b2c44bf6781..1ce4504444ba38f6d41b651d837f6a78f9d946e1 100644 (file)
@@ -1,5 +1,6 @@
 /*********************************************************
- * Copyright (c) 2008-2020,2023 VMware, Inc. All rights reserved.
+ * Copyright (c) 2008-2024 Broadcom. All Rights Reserved.
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
  *
  * 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
@@ -190,6 +191,18 @@ ToolsCore_LogState(guint level,
  */
 #define TOOLS_CORE_SIG_SET_OPTION "tcs_set_option"
 
+/**
+ * Signal sent when the service is going to be shutdown. Allow for listeners to
+ * prepare for a pending shutdown. Signal occurs before the service thread pool
+ * gets shutdown. The signal handler must not perform long running and/or
+ * blocking operation, as well as not perform core resource releases.
+ *
+ * @param[in]  src      The source object.
+ * @param[in]  ctx      ToolsAppCtx *: The application context.
+ * @param[in]  data     Client data.
+ */
+#define TOOLS_CORE_SIG_PRE_SHUTDOWN "tcs_pre_shutdown"
+
 /**
  * Signal sent when shutting down the service.
  *
index 412c016f64262b652a63c7a7c287ecebcaef2536..563071c43b0ecc36540118399ff3010017636d5e 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (c) 2020-2021,2023-2024 Broadcom. All Rights Reserved.
+ * Copyright (c) 2020-2024 Broadcom. All Rights Reserved.
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -364,6 +364,10 @@ typedef struct PluginState {
                             * FALSE: otherwise
                             * Transitions from FALSE to TRUE only */
 
+   Atomic_Bool stopping;   /* TRUE : Guest data publishing is stopping
+                            * FALSE: otherwise
+                            * Transitions from FALSE to TRUE only */
+
    GdpEvent eventConfig;   /* The config event object:
                             * Signalled to update config */
 } PluginState;
@@ -3183,6 +3187,7 @@ GdpInit(ToolsAppCtx *ctx) // IN
 {
    gPluginState.ctx = ctx;
    Atomic_WriteBool(&gPluginState.started, FALSE);
+   Atomic_WriteBool(&gPluginState.stopping, FALSE);
 
 #if defined(_WIN32)
    gPluginState.wsaStarted = FALSE;
@@ -3295,7 +3300,31 @@ GdpStart(void)
                                   GdpThreadTask,
                                   GdpThreadInterrupt,
                                   NULL, NULL)) {
-      g_critical("%s: Failed to start the gdp task thread.\n", __FUNCTION__);
+      /*
+       * Is the failure to start caused by pending service stop?
+       *   - stopping is true if a pre-shutdown signal was handled
+       *   - stopped is true if a shutdown signal was handled
+       *
+       * During the transition from stopping to stopped, the thread pool can
+       * be/become inactive resulting in a failure to start the gdp task thread.
+       *
+       * This is an expected failure, log it as a warning.
+       */
+      if (Atomic_ReadBool(&gPluginState.stopping)) {
+         g_debug(
+            "%s: gdp: start=%s, stop=%s, pre=%s; task: pool=%s\n",
+            __FUNCTION__,
+            Atomic_ReadBool(&gPluginState.started) ? "true" : "false",
+            Atomic_ReadBool(&gPluginState.stopped) ? "true" : "false",
+            Atomic_ReadBool(&gPluginState.stopping) ? "true" : "false",
+            (ToolsCorePool_GetPool(gPluginState.ctx) == NULL) ? "no":"yes");
+
+         g_warning("%s: Failed to start the gdp task thread.\n",
+                    __FUNCTION__);
+      } else {
+         g_critical("%s: Failed to start the gdp task thread.\n",
+                    __FUNCTION__);
+      }
       goto exit;
    }
 
@@ -3415,14 +3444,29 @@ GdpPublish(gint64 createTime,     // IN
 
    g_mutex_lock(&gPublishState.mutex);
 
-   if (Atomic_ReadBool(&gPluginState.stopped)) {
+   if (Atomic_ReadBool(&gPluginState.stopping)) {
+      /*
+       * Do not publish when publishing is stopped or gdp is stopping in
+       * preparation for stopping.
+       */
+      g_debug(
+         "%s: gdp: start=%s, stop=%s, pre=%s; task: pool=%s\n",
+         __FUNCTION__,
+         Atomic_ReadBool(&gPluginState.started) ? "true" : "false",
+         Atomic_ReadBool(&gPluginState.stopped) ? "true" : "false",
+         Atomic_ReadBool(&gPluginState.stopping) ? "true" : "false",
+         (ToolsCorePool_GetPool(gPluginState.ctx) == NULL) ? "no":"yes");
       gdpErr = GDP_ERROR_STOP;
       goto exit;
    }
 
    if (!Atomic_ReadBool(&gPluginState.started) &&
        !GdpStart()) {
-      gdpErr = GDP_ERROR_GENERAL;
+      if (Atomic_ReadBool(&gPluginState.stopping)) {
+         gdpErr = GDP_ERROR_STOP;
+      } else {
+         gdpErr = GDP_ERROR_GENERAL;
+      }
       goto exit;
    }
 
@@ -3482,6 +3526,31 @@ GdpConfReload(gpointer src,     // IN
 }
 
 
+/*
+ ******************************************************************************
+ * GdpPreShutdown --
+ *
+ * Prepare for shutdown.  Set 'stopping' to TRUE to prevent new publications,
+ * or starting the gdp task thread in the case of a first publication.
+ *
+ * @param[in] src   The source object, unused
+ * @param[in] ctx   The application context
+ * @param[in] data  Unused
+ *
+ ******************************************************************************
+ */
+
+static void
+GdpPreShutdown(gpointer src,     // IN
+               ToolsAppCtx *ctx, // IN
+               gpointer data)    // IN
+{
+   g_info("%s: Entering ...\n", __FUNCTION__);
+   Atomic_WriteBool(&gPluginState.stopping, TRUE);
+   g_debug("%s: Exiting ...\n", __FUNCTION__);
+}
+
+
 /*
  ******************************************************************************
  * GdpShutdown --
@@ -3505,6 +3574,7 @@ GdpShutdown(gpointer src,     // IN
           Atomic_ReadBool(&gPluginState.stopped));
    g_object_set(ctx->serviceObj, TOOLS_PLUGIN_SVC_PROP_GDP, NULL, NULL);
    GdpDestroy();
+   g_debug("%s: Exiting ...\n", __FUNCTION__);
 }
 
 
@@ -3564,6 +3634,7 @@ ToolsOnLoad(ToolsAppCtx *ctx) // IN
 
       ToolsPluginSignalCb sigs[] = {
          { TOOLS_CORE_SIG_CONF_RELOAD, GdpConfReload, NULL },
+         { TOOLS_CORE_SIG_PRE_SHUTDOWN, GdpPreShutdown, NULL },
          { TOOLS_CORE_SIG_SHUTDOWN, GdpShutdown, NULL },
       };
       ToolsAppReg regs[] = {
index e35f1c00800372b360818d8dca7bb212a44964fe..0da598f131a477bb1f915dbce3627bd633a1e39d 100644 (file)
@@ -1,5 +1,6 @@
 /*********************************************************
- * Copyright (c) 2020-2021,2023 VMware, Inc. All rights reserved.
+ * Copyright (c) 2020-2024 Broadcom. All Rights Reserved.
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
  *
  * 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
@@ -369,8 +370,12 @@ SendData(ToolsAppCtx *ctx,
    if (gdpErr != GDP_ERROR_SUCCESS) {
       g_info("%s: ToolsPluginSvcGdp_Publish error: %s\n",
              __FUNCTION__, gdpErrMsgs[gdpErr]);
-      /* NOTE to SD maintainer: gdpErr == GDP_ERROR_NO_SUBSCRIBERS to be handled here when ready*/
+      /*
+       *  NOTE to SD maintainer:
+       *  GDP_ERROR_NO_SUBSCRIBERS to be handled here when ready
+       */
       if (gdpErr == GDP_ERROR_STOP ||
+          gdpErr == GDP_ERROR_GENERAL ||
           gdpErr == GDP_ERROR_UNREACH ||
           gdpErr == GDP_ERROR_TIMEOUT) {
          gSkipThisTask = TRUE;
index 1ae277eacf5c93b0ed8a832c54da770b9fce3371..44ab42655945a8e3876e9ece72dc18a521378ae7 100644 (file)
@@ -120,6 +120,13 @@ static gboolean gGlobalConfStarted = FALSE;
 static void
 ToolsCoreCleanup(ToolsServiceState *state)
 {
+   g_info("%s: Entering\n", __FUNCTION__);
+   /*
+    * Emit the early shutdown signal.
+    */
+   g_signal_emit_by_name(state->ctx.serviceObj,
+                         TOOLS_CORE_SIG_PRE_SHUTDOWN,
+                         &state->ctx);
 #if (defined(_WIN32) && !defined(_ARM64_)) || \
     (defined(__linux__) && !defined(USERWORLD))
    if (state->mainService) {
@@ -1219,6 +1226,7 @@ ToolsCore_Setup(ToolsServiceState *state)
    ToolsCoreService_RegisterProperty(state->ctx.serviceObj,
                                      &ctxProp);
    g_object_set(state->ctx.serviceObj, TOOLS_CORE_PROP_CTX, &state->ctx, NULL);
+
    /* Initialize the environment from config. */
    ToolsCoreInitEnv(&state->ctx);
    ToolsCorePool_Init(&state->ctx);
index 0df4acba62f1f9ab4ac1d7954309e15560517c00..f5a084e6b832d5f5ad9310be5cddfb7589787a72 100644 (file)
@@ -1,5 +1,6 @@
 /*********************************************************
- * Copyright (C) 2008-2019, 2021 VMware, Inc. All rights reserved.
+ * Copyright (c) 2008-2024 Broadcom. All Rights Reserved.
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
  *
  * 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
@@ -378,6 +379,16 @@ ToolsCore_Service_class_init(gpointer _klass,
                 G_TYPE_POINTER,
                 G_TYPE_STRING,
                 G_TYPE_STRING);
+   g_signal_new(TOOLS_CORE_SIG_PRE_SHUTDOWN,
+                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_SHUTDOWN,
                 G_OBJECT_CLASS_TYPE(klass),
                 G_SIGNAL_RUN_LAST,
index 5229e9a8707a3748f79bb9bd8f8d2226453c9b0f..f63bf993b5a512f32911f498aa2003317b889715 100644 (file)
@@ -1,5 +1,6 @@
 /*********************************************************
- * Copyright (C) 2008-2016 VMware, Inc. All rights reserved.
+ * Copyright (c) 2008-2024 Broadcom. All Rights Reserved.
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
  *
  * 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
@@ -227,6 +228,30 @@ TestPluginServiceControl(gpointer src,
 #endif
 
 
+/**
+ * Handles a pre-shutdown callback; just logs debug information. This is called
+ * at the start of a service shutdown prior to the shut down signal, and should
+ * be used to prepare for an incoming shutdown signal.
+ *
+ * @param[in]  src      The source object.
+ * @param[in]  ctx      The app context.
+ * @param[in]  plugin   Plugin registration data.
+ */
+
+static void
+TestPluginPreShutdown(gpointer src,
+                      ToolsAppCtx *ctx,
+                      ToolsPluginData *plugin)
+{
+   vm_debug("pre-shutdown signal.");
+   CU_ASSERT(gInvalidSigError);
+   CU_ASSERT(gInvalidAppError);
+   CU_ASSERT(gInvalidAppProvider);
+   CU_ASSERT(gValidAppRegistration);
+}
+
+
+
 /**
  * Handles a shutdown callback; just logs debug information. This is called
  * before the service is shut down, and should be used to clean up any resources
@@ -375,6 +400,7 @@ ToolsOnLoad(ToolsAppCtx *ctx)
    };
    ToolsPluginSignalCb sigs[] = {
       { TOOLS_CORE_SIG_RESET, TestPluginReset, &regData },
+      { TOOLS_CORE_SIG_SHUTDOWN, TestPluginPreShutdown, &regData },
       { TOOLS_CORE_SIG_SHUTDOWN, TestPluginShutdown, &regData },
       { TOOLS_CORE_SIG_CAPABILITIES, TestPluginCapabilities, &regData },
       { TOOLS_CORE_SIG_SET_OPTION, TestPluginSetOption, &regData },