From: John Wolfe Date: Fri, 11 Sep 2020 19:11:06 +0000 (-0700) Subject: Changes to Common source files not applicable to open-vm-tools. X-Git-Tag: stable-11.2.0~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e0117e5ac8620ee00906fb9f070e92ac6a15baf;p=thirdparty%2Fopen-vm-tools.git Changes to Common source files not applicable to open-vm-tools. --- diff --git a/open-vm-tools/lib/include/vmware/tools/plugin.h b/open-vm-tools/lib/include/vmware/tools/plugin.h index 48d2f36b4..1776a6260 100644 --- a/open-vm-tools/lib/include/vmware/tools/plugin.h +++ b/open-vm-tools/lib/include/vmware/tools/plugin.h @@ -217,6 +217,15 @@ ToolsCore_LogState(guint level, */ #define TOOLS_CORE_SIG_SERVICE_CONTROL "tcs_service_control" +/** + * Signal sent when a new version of global configuration is downloaded. + * + * @param[in] src The source object. + * @param[in] ctx ToolsAppCtx *: The application context. + * @param[in] data Client data. + */ +#define TOOLS_CORE_SIG_GLOBALCONF_UPDATE "tcs_globalconf_update" + #endif /** diff --git a/open-vm-tools/lib/include/vmware/tools/utils.h b/open-vm-tools/lib/include/vmware/tools/utils.h index cfa35019b..cd8ca14e0 100644 --- a/open-vm-tools/lib/include/vmware/tools/utils.h +++ b/open-vm-tools/lib/include/vmware/tools/utils.h @@ -105,6 +105,10 @@ VMTools_LoadConfig(const gchar *path, GKeyFile **config, time_t *mtime); +gboolean +VMTools_AddConfig(GKeyFile *srcConfig, + GKeyFile *dstConfig); + gboolean VMTools_WriteConfig(const gchar *path, GKeyFile *config, diff --git a/open-vm-tools/libvmtools/vmtoolsConfig.c b/open-vm-tools/libvmtools/vmtoolsConfig.c index c38fd312d..47f20b861 100644 --- a/open-vm-tools/libvmtools/vmtoolsConfig.c +++ b/open-vm-tools/libvmtools/vmtoolsConfig.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2008-2019 VMware, Inc. All rights reserved. + * Copyright (C) 2008-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 @@ -175,6 +175,87 @@ exit: } +/** + * Copies the key/value pairs from one config dictionary to another config + * dictionary. The key/value pairs are added only if they are not + * already present in the destination configuration dictionary. + * + * @param[in] srcConfig Configuration dictionary from which the + * key/value pairs should be added. + * @param[in] dstConfig Configuration dictionary to which the + * key/value pairs should be added.. + * + * @return Whether any key/value pairs have been added to the config + * dictionary. + */ + +gboolean +VMTools_AddConfig(GKeyFile *srcConfig, + GKeyFile *dstConfig) +{ + gsize numGroups; + gchar **groupNames; + gsize i; + gboolean configAdded = FALSE; + + g_return_val_if_fail(srcConfig != NULL, configAdded); + g_return_val_if_fail(dstConfig != NULL, configAdded); + + groupNames = g_key_file_get_groups(srcConfig, &numGroups); + + g_debug("%s: Found %d groups in config.\n", __FUNCTION__, (int) numGroups); + + for (i = 0; i < numGroups; ++i) { + gsize numKeys; + gchar **keyNames; + gsize j; + GError *gErr = NULL; + const gchar *group = groupNames[i]; + + keyNames = g_key_file_get_keys(srcConfig, group, &numKeys, &gErr); + if (gErr != NULL) { + g_warning("%s: g_key_file_get_keys(%s) failed: %s\n", + __FUNCTION__, group, gErr->message); + g_clear_error(&gErr); + continue; + } + + g_debug("%s: Found %d keys for group: '%s' in config.\n", + __FUNCTION__, (int) numKeys, group); + + for (j = 0; j < numKeys; ++j) { + const gchar* key = keyNames[j]; + + if (!g_key_file_has_key(dstConfig, group, key, NULL)) { + gchar *value = g_key_file_get_value(srcConfig, group, key, &gErr); + + if (value == NULL && gErr != NULL) { + g_warning("%s: g_key_file_get_value(%s:%s) failed: %s\n", + __FUNCTION__, group, key, gErr->message); + g_clear_error(&gErr); + continue; + } + + g_key_file_set_value(dstConfig, group, key, value); + g_debug("%s: Added (%s:%s) to the new config\n", + __FUNCTION__, group, key); + configAdded = TRUE; + g_free(value); + } else { + g_debug("%s: Ignoring (%s:%s)\n", __FUNCTION__, group, key); + } + } + + g_strfreev(keyNames); + } + + g_debug("%s: Added the config. Return val: %d\n", __FUNCTION__, configAdded); + + g_strfreev(groupNames); + return configAdded; +} + + /** * Saves the given config data to the given path. * diff --git a/open-vm-tools/services/vmtoolsd/mainLoop.c b/open-vm-tools/services/vmtoolsd/mainLoop.c index 3a67a085e..3c6313adf 100644 --- a/open-vm-tools/services/vmtoolsd/mainLoop.c +++ b/open-vm-tools/services/vmtoolsd/mainLoop.c @@ -47,6 +47,7 @@ #if defined(_WIN32) # include "codeset.h" # include "guestStoreClient.h" +# include "globalConfig.h" # include "windowsu.h" #else # include "posix.h" @@ -79,6 +80,13 @@ #define CONFNAME_MAX_CHANNEL_ATTEMPTS "maxChannelAttempts" +#if defined(_WIN32) +/* + * The state of the global conf module. + */ +static gGlobalConfEnabled = FALSE; +#endif + /* ****************************************************************************** @@ -190,6 +198,28 @@ ToolsCoreConfFileCb(gpointer clientData) } +#if defined(_WIN32) +/** + * Callback TOOLS_CORE_SIG_GLOBALCONF_UPDATE signal. The signal is + * triggered whenever a new global configuration is downloaded. + * + * @param[in] src The source object. + * @param[in] ctx The ToolsAppCtx for passing config. + * @param[in] state Service state. + */ + +static void +ToolsCoreGlobalConfUpdateSignalCb(gpointer src, + ToolsAppCtx *ctx, + ToolsServiceState *state) +{ + g_debug("%s: global config is updated. Reloading the config.", __FUNCTION__); + + ToolsCore_ReloadConfigEx(state, FALSE, TRUE); +} +#endif + + /** * IO freeze signal handler. Disables the conf file check task if I/O is * frozen, re-enable it otherwise. See bug 529653. @@ -481,9 +511,32 @@ ToolsCoreRunLoop(ToolsServiceState *state) /* * For now exclude the MAC due to limited testing. */ - if (state->mainService && ToolsCoreHangDetector_Start(&state->ctx)) { - g_info("Successfully started tools hang detector"); + if (state->mainService) { + if (ToolsCoreHangDetector_Start(&state->ctx)) { + g_info("%s: Successfully started tools hang detector", + __FUNCTION__); + } +#if defined(_WIN32) + if (GlobalConfig_Start(&state->ctx)) { + g_info("%s: Successfully started global config module.", + __FUNCTION__); + if (g_signal_lookup(TOOLS_CORE_SIG_GLOBALCONF_UPDATE, + G_OBJECT_TYPE(state->ctx.serviceObj)) != 0) { + g_signal_connect(state->ctx.serviceObj, + TOOLS_CORE_SIG_GLOBALCONF_UPDATE, + G_CALLBACK(ToolsCoreGlobalConfUpdateSignalCb), + state); + g_debug("%s: Registered the handler for the " + "global config update signal.", __FUNCTION__); + gGlobalConfEnabled = TRUE; + } else { + g_debug("%s: Failed to register the handler for the " + "global config update signal", __FUNCTION__); + } + } +#endif } + g_main_loop_run(state->ctx.mainLoop); #endif } @@ -616,19 +669,37 @@ ToolsCore_GetTcloName(ToolsServiceState *state) * * @param[in] state Service state. * @param[in] reset Whether to reset the logging subsystem. + * @param[in] force If TRUE, the config file will be loaded even if it + * has not been modified since the last check. */ void -ToolsCore_ReloadConfig(ToolsServiceState *state, - gboolean reset) +ToolsCore_ReloadConfigEx(ToolsServiceState *state, + gboolean reset, + gboolean force) { gboolean first = state->ctx.config == NULL; gboolean loaded; + if (force) { + /* + * Set the configMtime to 0 so that the config file from the file system + * is reloaded. Else, the config is loaded only if it's been modified + * since the last check. + */ + state->configMtime = 0; + } + loaded = VMTools_LoadConfig(state->configFile, G_KEY_FILE_NONE, &state->ctx.config, &state->configMtime); +#if defined(_WIN32) + if (gGlobalConfEnabled && (loaded || force)) { + gboolean globalConfigUpdated = GlobalConfig_Update(state->ctx.config); + loaded = loaded || globalConfigUpdated; + } +#endif if (!first && loaded) { g_debug("Config file reloaded.\n"); @@ -664,6 +735,24 @@ ToolsCore_ReloadConfig(ToolsServiceState *state, } +/** + * Reloads the config file and re-configure the logging subsystem if the + * log file was updated. If the config file is being loaded for the first + * time, try to upgrade it to the new version if an old version is + * detected. + * + * @param[in] state Service state. + * @param[in] reset Whether to reset the logging subsystem. + */ + +void +ToolsCore_ReloadConfig(ToolsServiceState *state, + gboolean reset) +{ + ToolsCore_ReloadConfigEx(state, reset, FALSE); +} + + #if defined(_WIN32) /** diff --git a/open-vm-tools/services/vmtoolsd/toolsCoreInt.h b/open-vm-tools/services/vmtoolsd/toolsCoreInt.h index 06c990202..6b9f38a29 100644 --- a/open-vm-tools/services/vmtoolsd/toolsCoreInt.h +++ b/open-vm-tools/services/vmtoolsd/toolsCoreInt.h @@ -143,6 +143,11 @@ void ToolsCore_ReloadConfig(ToolsServiceState *state, gboolean reset); +void +ToolsCore_ReloadConfigEx(ToolsServiceState *state, + gboolean reset, + gboolean force); + void ToolsCore_RegisterPlugins(ToolsServiceState *state);