From: VMware, Inc <> Date: Tue, 17 Nov 2009 22:11:10 +0000 (-0800) Subject: Clean up the Tools Core "utils" API. X-Git-Tag: 2009.11.16-210370~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=86d8a0f07b80502ab9c076ebb4522e22f590af55;p=thirdparty%2Fopen-vm-tools.git Clean up the Tools Core "utils" API. Get rid of a bunch of functions that were either sort of redundant or not really needed at all. Now an app that needs to use the vmtools.dll logging just needs to call two functions: VMTools_LoadConfig() (or load the config data some other way) VMTools_ConfigLogging() And those same functions provide all the functionality previously offered by the other, now defunt, functions. Change all call sites to use the new functions. Also, two minor improvements to the library: . the logging subsystem is not activated by default when a process loads the library. This makes it opt-in (users have to explicitly call VMTools_ConfigLogging() to enable the vmtools.dll logging code). . the log reset code now handles keeping log files opened also for sub-domains (previously only the default log domain would get that treatment). Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/hgfsclient/hgfsclient.c b/open-vm-tools/hgfsclient/hgfsclient.c index f387483bc..8229c805e 100644 --- a/open-vm-tools/hgfsclient/hgfsclient.c +++ b/open-vm-tools/hgfsclient/hgfsclient.c @@ -316,21 +316,15 @@ static Bool HgfsClient_Init(void) { Bool success = FALSE; - gchar *confFile; - GKeyFile *conf; - - confFile = VMTools_GetToolsConfFile(); - conf = VMTools_LoadConfig(confFile, G_KEY_FILE_NONE, FALSE); + GKeyFile *conf = NULL; + VMTools_LoadConfig(NULL, G_KEY_FILE_NONE, &conf, NULL); + VMTools_ConfigLogging("hgfsclient", conf, FALSE, FALSE); if (conf != NULL) { - VMTools_ConfigLogging(conf); g_key_file_free(conf); conf = NULL; } - g_free(confFile); - confFile = NULL; - if (!VmCheck_IsVirtualWorld()) { Warning("This application must be run in a Virtual Machine.\n"); goto out; diff --git a/open-vm-tools/lib/include/vmware/tools/utils.h b/open-vm-tools/lib/include/vmware/tools/utils.h index f38ff851b..0ea624f83 100644 --- a/open-vm-tools/lib/include/vmware/tools/utils.h +++ b/open-vm-tools/lib/include/vmware/tools/utils.h @@ -22,16 +22,12 @@ /** * @file utils.h * - * Public functions from the VMTools shared library. + * Public functions from the VMTools shared library, and other definitions. * * @addtogroup vmtools_utils * @{ */ -#if !defined(G_LOG_DOMAIN) -# define G_LOG_DOMAIN VMTools_GetDefaultLogDomain() -#endif - #define VMTOOLS_GUEST_SERVICE "vmsvc" #define VMTOOLS_USER_SERVICE "vmusr" @@ -41,10 +37,6 @@ # define VMTOOLS_EXTERN_C #endif -/* Needs to come before glib.h. */ -VMTOOLS_EXTERN_C const char * -VMTools_GetDefaultLogDomain(void); - #include #if defined(G_PLATFORM_WIN32) # include @@ -67,7 +59,7 @@ VMTools_GetDefaultLogDomain(void); * Converts an UTF-8 path to the local (i.e., glib) file name encoding. * This is a no-op on Windows, since the local encoding is always UTF-8 * in glib. The returned value should not be freed directly; instead, - * use VMTOOLS_FREE_FILENAME. + * use VMTOOLS_RELEASE_FILENAME_LOCAL. * * @param[in] path Path in UTF-8 (should not be NULL). * @param[out] err Where to store errors (type: GError **; may be NULL). @@ -103,31 +95,16 @@ void vm_free(void *ptr); void -VMTools_SetDefaultLogDomain(const gchar *domain); - -void -VMTools_ConfigLogging(GKeyFile *cfg); - -void -VMTools_EnableLogging(gboolean enable); +VMTools_ConfigLogging(const gchar *defaultDomain, + GKeyFile *cfg, + gboolean force, + gboolean reset); -gchar * -VMTools_GetToolsConfFile(void); - -GKeyFile * +gboolean VMTools_LoadConfig(const gchar *path, GKeyFileFlags flags, - gboolean autoUpgrade); - - -gboolean -VMTools_ReloadConfig(const gchar *path, - GKeyFileFlags flags, - GKeyFile **config, - time_t *mtime); - -void -VMTools_ResetLogging(gboolean cleanDefault); + GKeyFile **config, + time_t *mtime); gboolean VMTools_WriteConfig(const gchar *path, diff --git a/open-vm-tools/libvmtools/vmtools.c b/open-vm-tools/libvmtools/vmtools.c index 544a49188..021782c16 100644 --- a/open-vm-tools/libvmtools/vmtools.c +++ b/open-vm-tools/libvmtools/vmtools.c @@ -86,14 +86,12 @@ VMToolsDllInit(void *lib) #if defined(_WIN32) WiperInitData wiperData; CoreDump_SetUnhandledExceptionFilter(); - VMTools_ResetLogging(FALSE); wiperData.resourceModule = lib; success = (NetUtil_LoadIpHlpApiDll() == ERROR_SUCCESS); ASSERT(success); success = Wiper_Init(&wiperData); ASSERT(success); #else - VMTools_ResetLogging(FALSE); success = Wiper_Init(NULL); ASSERT(success); #endif @@ -113,7 +111,6 @@ VMToolsDllFini(void) #if defined(_WIN32) NetUtil_FreeIpHlpApiDll(); #endif - VMTools_ResetLogging(TRUE); } diff --git a/open-vm-tools/libvmtools/vmtoolsConfig.c b/open-vm-tools/libvmtools/vmtoolsConfig.c index db7b262d5..9ed39fa16 100644 --- a/open-vm-tools/libvmtools/vmtoolsConfig.c +++ b/open-vm-tools/libvmtools/vmtoolsConfig.c @@ -29,11 +29,10 @@ #include #include #include + +#include "vm_assert.h" #include "conf.h" -#include "file.h" #include "guestApp.h" -#include "str.h" -#include "util.h" /** Data types supported for translation. */ typedef enum { @@ -184,8 +183,8 @@ VMToolsConfigUpgrade(GuestApp_Dict *old, * @return String with the default config path (should be freed by caller). */ -gchar * -VMTools_GetToolsConfFile(void) +static gchar * +VMToolsGetToolsConfFile(void) { char *confPath = GuestApp_GetConfPath(); gchar *confFilePath; @@ -202,7 +201,7 @@ VMTools_GetToolsConfFile(void) confPath = GuestApp_GetConfPath(); ASSERT(confPath != NULL); } - confFilePath = g_strdup_printf("%s%c%s", confPath, DIRSEPC, CONF_FILE); + confFilePath = g_build_filename(confPath, CONF_FILE, NULL); free(confPath); return confFilePath; @@ -210,38 +209,79 @@ VMTools_GetToolsConfFile(void) /** - * Loads the configuration file at the given path. If an old configuration - * file is detected, the caller can request for it to be automatically upgraded - * to the new configuration format (the old configuration file is saved with a + * Loads the configuration file at the given path. + * + * If an old configuration file is detected and the current process has write + * permission to the file, the configuration data will automatically upgraded to + * the new configuration format (the old configuration file is saved with a * ".old" extension). * - * @param[in] path Path to the configuration file. - * @param[in] flags Flags for opening the file. - * @param[in] autoUpgrade Whether to try to upgrade old tools configuration. + * @param[in] path Path to the configuration file, or NULL for default + * Tools config file. + * @param[in] flags Flags for opening the file. + * @param[in,out] config Where to store the config dictionary; when reloading + * the file, the old config object will be destroyed. + * @param[in,out] mtime Last known modification time of the config file. + * When the function succeeds, will contain the new + * modification time read from the file. If NULL (or 0), + * the config dictionary is always loaded. * - * @return A configuration dictionary, or NULL on error. + * @return Whether a new config dictionary was loaded. */ -GKeyFile * +gboolean VMTools_LoadConfig(const gchar *path, GKeyFileFlags flags, - gboolean autoUpgrade) + GKeyFile **config, + time_t *mtime) { gchar *backup = NULL; - gchar *localPath; + gchar *defaultPath = NULL; + gchar *localPath = NULL; + struct stat confStat; GuestApp_Dict *old = NULL; GError *err = NULL; - GKeyFile *cfg; + GKeyFile *cfg = NULL; - cfg = g_key_file_new(); + g_return_val_if_fail(config != NULL, FALSE); + + if (path == NULL) { + defaultPath = VMToolsGetToolsConfFile(); + } - localPath = VMTOOLS_GET_FILENAME_LOCAL(path, &err); + localPath = VMTOOLS_GET_FILENAME_LOCAL((path != NULL) ? path : defaultPath, &err); if (err != NULL) { g_warning("Error converting to local encoding: %s\n", err->message); goto exit; } - if (!File_IsFile(path) || File_GetSizeByPath(path) == 0) { + if (g_stat(localPath, &confStat) == -1) { + /* + * If the file doesn't exist, it's not an error. Just return an + * empty dictionary in that case. The mtime will be set to 0 if + * the caller requested it. + */ + memset(&confStat, 0, sizeof confStat); + if (errno != ENOENT) { + g_warning("Failed to stat conf file: %s\n", strerror(errno)); + goto exit; + } else { + cfg = g_key_file_new(); + goto exit; + } + } + + /* Check if we really need to load the data. */ + if (mtime != NULL && confStat.st_mtime <= *mtime) { + goto exit; + } + + /* Need to load the configuration data. */ + + cfg = g_key_file_new(); + + /* Empty file: just return an empty dictionary. */ + if (confStat.st_size == 0) { goto exit; } @@ -255,33 +295,35 @@ VMTools_LoadConfig(const gchar *path, goto error; } - /* Failed to load the config file; try to upgrade if requested. */ - if (!autoUpgrade) { - goto error; - } - - old = Conf_Load(); - if (old == NULL) { - g_warning("Error loading old tools config data, bailing out.\n"); - goto error; - } + /* + * Failed to load the config file; try to upgrade if requested. But only do + * it if the user is using the default conf file path; the old "Conf_Load()" + * API doesn't allow us to provide a custom config file path. + */ + if (path == NULL) { + old = Conf_Load(); + if (old == NULL) { + g_warning("Error loading old tools config data, bailing out.\n"); + goto error; + } - VMToolsConfigUpgrade(old, cfg); - backup = g_strdup_printf("%s.old", path); + VMToolsConfigUpgrade(old, cfg); + backup = g_strdup_printf("%s.old", localPath); - if (!File_IsFile(backup)) { - if (!File_Rename(path, backup)) { - g_warning("Error creating backup of old config file.\n"); - goto error; + if (!g_file_test(backup, G_FILE_TEST_IS_REGULAR)) { + if (g_rename(localPath, backup) == -1) { + g_warning("Error creating backup of old config file.\n"); + goto error; + } + } else { + g_warning("Backup config exists, skipping backup.\n"); } - } else { - g_warning("Backup config exists, skipping backup.\n"); - } - g_clear_error(&err); + g_clear_error(&err); - if (!VMTools_WriteConfig(path, cfg, NULL)) { - goto error; + if (!VMTools_WriteConfig((path != NULL) ? path : defaultPath, cfg, NULL)) { + goto error; + } } goto exit; @@ -295,81 +337,19 @@ exit: if (old != NULL) { GuestApp_FreeDict(old); } - g_free(backup); - VMTOOLS_RELEASE_FILENAME_LOCAL(localPath); - return cfg; -} - - -/** - * Reloads the configuration file at the given path if it has changed since the - * given timestamp. No translation (such as in VMTools_LoadConfig()) will be - * performed. - * - * @param[in] path Path to the config file. - * @param[in] flags Flags to use when opening the file. - * @param[in,out] config GKeyFile object; when reloading the file, the old - * config object will be destroyed. - * @param[in,out] mtime Last known modification time of the config file. - * When the function succeeds, will contain the new - * modification time read from the file. - * - * @return Whether the file was reloaded. - */ - -gboolean -VMTools_ReloadConfig(const gchar *path, - GKeyFileFlags flags, - GKeyFile **config, - time_t *mtime) -{ - struct stat confStat; - gboolean ret = FALSE; - GKeyFile *newConfig = NULL; - - ASSERT(config != NULL); - ASSERT(mtime != NULL); - - if (g_stat(path, &confStat) == -1) { - g_debug("Failed to stat conf file: %s\n", strerror(errno)); - goto exit; - } - - if (*mtime == 0 || confStat.st_mtime > *mtime) { - GError *err = NULL; - gchar *localPath; - - localPath = VMTOOLS_GET_FILENAME_LOCAL(path, &err); - if (err != NULL) { - g_warning("Error converting to local encoding: %s\n", err->message); - goto exit; - } - - newConfig = g_key_file_new(); - g_key_file_load_from_file(newConfig, localPath, flags, &err); - - if (err != NULL) { - g_warning("Error loading conf file: %s\n", err->message); - g_clear_error(&err); - g_key_file_free(newConfig); - newConfig = NULL; - } else { - ret = TRUE; - } - - VMTOOLS_RELEASE_FILENAME_LOCAL(localPath); - } - - if (newConfig != NULL) { + if (cfg != NULL) { if (*config != NULL) { g_key_file_free(*config); } - *config = newConfig; - *mtime = confStat.st_mtime; + *config = cfg; + if (mtime != NULL) { + *mtime = confStat.st_mtime; + } } - -exit: - return ret; + g_free(backup); + g_free(defaultPath); + VMTOOLS_RELEASE_FILENAME_LOCAL(localPath); + return (cfg != NULL); } @@ -390,14 +370,18 @@ VMTools_WriteConfig(const gchar *path, { gboolean ret = FALSE; gchar *data = NULL; + gchar *defaultPath = NULL; gchar *localPath = NULL; FILE *out = NULL; GError *lerr = NULL; - ASSERT(path != NULL); ASSERT(config != NULL); - localPath = VMTOOLS_GET_FILENAME_LOCAL(path, &lerr); + if (path == NULL) { + defaultPath = VMToolsGetToolsConfFile(); + } + + localPath = VMTOOLS_GET_FILENAME_LOCAL((path != NULL) ? path : defaultPath, &lerr); if (lerr != NULL) { g_warning("Error converting to local encoding: %s\n", lerr->message); goto exit; @@ -437,6 +421,7 @@ exit: g_clear_error(&lerr); } g_free(data); + g_free(defaultPath); VMTOOLS_RELEASE_FILENAME_LOCAL(localPath); return ret; } diff --git a/open-vm-tools/libvmtools/vmtoolsLog.c b/open-vm-tools/libvmtools/vmtoolsLog.c index d0821209d..e44af17d6 100644 --- a/open-vm-tools/libvmtools/vmtoolsLog.c +++ b/open-vm-tools/libvmtools/vmtoolsLog.c @@ -66,6 +66,15 @@ #define SHOULD_LOG(level, data) (IS_FATAL(level) || \ (gLogEnabled && ((data)->mask & (level)))) +/** Clean up the contents of a log handler. */ +#define CLEAR_LOG_HANDLER(handler) do { \ + if ((handler)->file != NULL) { \ + fclose((handler)->file); \ + } \ + g_free((handler)->path); \ + g_free((handler)->domain); \ +} while (0) + static void VMToolsLogFile(const gchar *domain, @@ -148,13 +157,15 @@ VMToolsLogOpenFile(const gchar *path, ASSERT(path != NULL); pathLocal = VMTOOLS_GET_FILENAME_LOCAL(path, NULL); - if (!append && g_file_test(path, G_FILE_TEST_EXISTS)) { + if (!append && g_file_test(pathLocal, G_FILE_TEST_EXISTS)) { /* Back up existing log file. */ gchar *bakFile = g_strdup_printf("%s.old", pathLocal); if (!g_file_test(bakFile, G_FILE_TEST_IS_DIR) && (!g_file_test(bakFile, G_FILE_TEST_EXISTS) || g_unlink(bakFile) == 0)) { g_rename(pathLocal, bakFile); + } else { + g_unlink(pathLocal); } g_free(bakFile); } @@ -390,12 +401,11 @@ VMToolsLogFile(const gchar *domain, /** * Configures the given log domain based on the data provided in the given - * dictionary. If the log domain being configured doesn't match the default - * (@see VMTools_GetDefaultLogDomain()), and no specific handler is defined - * for the domain, the handler is inherited from the default domain, instead - * of using the default handler. This allows reusing the same log file, for - * example, while maintaining the ability to enable different log levels - * for different domains. + * dictionary. If the log domain being configured doesn't match the default, and + * no specific handler is defined for the domain, the handler is inherited from + * the default domain, instead of using the default handler. This allows reusing + * the same log file, for example, while maintaining the ability to enable + * different log levels for different domains. * * For the above to properly work, the default log domain has to be configured * before any other domains. @@ -441,7 +451,7 @@ VMToolsConfigLogDomain(const gchar *domain, handler = g_key_file_get_string(cfg, LOGGING_GROUP, key, NULL); if (handler == NULL) { - if (strcmp(domain, VMTools_GetDefaultLogDomain()) == 0) { + if (strcmp(domain, gLogDomain) == 0) { handlerFn = DEFAULT_HANDLER; } else { handlerFn = gDefaultLogFunc; @@ -538,7 +548,7 @@ VMToolsConfigLogDomain(const gchar *domain, data->append = (handler != NULL && strcmp(handler, "file+") == 0); logpath = NULL; - if (strcmp(domain, VMTools_GetDefaultLogDomain()) == 0) { + if (strcmp(domain, gLogDomain) == 0) { /* * Replace the global log configuration. If the default log domain was * logging to a file and the file path hasn't changed, then keep the old @@ -546,7 +556,7 @@ VMToolsConfigLogDomain(const gchar *domain, */ LogHandlerData *old = gDefaultData; - if (old->file != NULL) { + if (old != NULL && old->file != NULL) { ASSERT(old->path); if (data->path != NULL && strcmp(data->path, old->path) == 0) { g_free(data->path); @@ -574,7 +584,7 @@ VMToolsConfigLogDomain(const gchar *domain, gDomains = g_ptr_array_new(); } g_ptr_array_add(gDomains, data); - data->handlerId = g_log_set_handler(domain, + data->handlerId = g_log_set_handler(domain, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, @@ -588,63 +598,187 @@ exit: } -/* Public API. */ - /** - * Returns the default log domain for the application. + * Resets the vmtools logging subsystem, freeing up data and restoring the + * original glib configuration. * - * @return A string with the name of the log domain. + * @param[in] hard Whether to do a "hard" reset of the logging system + * (cleaning up any log domain existing state and freeing + * associated memory). */ -const char * -VMTools_GetDefaultLogDomain(void) +static void +VMToolsResetLogging(gboolean hard) { - return gLogDomain; + gLogEnabled = FALSE; + g_log_set_default_handler(g_log_default_handler, NULL); + + if (gDomains != NULL) { + guint i; + for (i = 0; i < gDomains->len; i++) { + LogHandlerData *data = g_ptr_array_index(gDomains, i); + g_log_remove_handler(data->domain, data->handlerId); + if (hard) { + CLEAR_LOG_HANDLER(data); + g_free(data); + } + } + if (hard) { + g_ptr_array_free(gDomains, TRUE); + gDomains = NULL; + } + } + + if (hard && gDefaultData != NULL) { + CLEAR_LOG_HANDLER(gDefaultData); + g_free(gDefaultData); + gDefaultData = NULL; + } + + if (gLogDomain != NULL) { + g_free(gLogDomain); + gLogDomain = NULL; + } + + gDefaultLogFunc = DEFAULT_HANDLER; } /** - * Sets the default log domain. This only changes the output of the default - * log handler. + * Restores the logging configuration in the given config data. This means doing + * the following: + * + * . if the old log domain exists in the current configuration, and in case both + * the old and new configuration used log files, then re-use the file that was + * already opened. + * . if they don't use the same configuration, close the log file for the old + * configuration. + * . if an old log domain doesn't exist in the new configuration, then + * release any resources the old configuration was using for that domain. * - * @param[in] domain The log domain. + * @param[in] oldDefault Data for the old default domain. + * @param[in] oldDomains List of old log domains. */ -void -VMTools_SetDefaultLogDomain(const gchar *domain) +static void +VMToolsRestoreLogging(LogHandlerData *oldDefault, + GPtrArray *oldDomains) { - ASSERT(domain != NULL); - if (gLogDomain != NULL) { - g_free(gLogDomain); + /* First, restore what needs to be restored. */ + if (gDomains != NULL && oldDomains != NULL) { + guint i; + for (i = 0; i < gDomains->len; i++) { + guint j; + LogHandlerData *data = g_ptr_array_index(gDomains, i); + + /* Try to find the matching old config. */ + for (j = 0; j < oldDomains->len; j++) { + LogHandlerData *olddata = g_ptr_array_index(oldDomains, j); + if (strcmp(data->domain, olddata->domain) == 0) { + if (data->path != NULL && olddata->file != NULL) { + ASSERT(data->file == NULL); + data->file = olddata->file; + olddata->file = NULL; + } + break; + } + } + } + } + + if (gDefaultData != NULL && oldDefault != NULL) { + if (gDefaultData->path != NULL && oldDefault->file != NULL) { + ASSERT(gDefaultData->file == NULL); + gDefaultData->file = oldDefault->file; + oldDefault->file = NULL; + } + } + + /* Second, clean up the old configuration data. */ + if (oldDomains != NULL) { + while (oldDomains->len > 0) { + LogHandlerData *data = g_ptr_array_remove_index_fast(oldDomains, + oldDomains->len - 1); + CLEAR_LOG_HANDLER(data); + g_free(data); + } + } + + if (oldDefault != NULL) { + CLEAR_LOG_HANDLER(oldDefault); } - gLogDomain = g_strdup(domain); } +/* Public API. */ + /** - * Configures the logging system according to the configuration provided from - * the given dictionary. + * Configures the logging system according to the configuration in the given + * dictionary. * - * @param[in] cfg The configuration data. + * Optionally, it's possible to reset the logging subsystem; this will shut + * down all log handlers managed by the vmtools library before configuring + * the log system, which means that logging will behave as if the application + * was just started. A visible side-effect of this is that log files may be + * rotated (if they're not configure for appending). + * + * @param[in] defaultDomain Name of the default log domain. + * @param[in] cfg The configuration data. May be NULL. + * @param[in] force Whether to force logging to be enabled. + * @param[in] reset Whether to reset the logging subsystem first. */ void -VMTools_ConfigLogging(GKeyFile *cfg) +VMTools_ConfigLogging(const gchar *defaultDomain, + GKeyFile *cfg, + gboolean force, + gboolean reset) { gchar **list; gchar **curr; + GPtrArray *oldDomains = NULL; + LogHandlerData *oldDefault = NULL; - VMTools_ResetLogging(FALSE); + g_return_if_fail(defaultDomain != NULL); - if (!g_key_file_has_group(cfg, LOGGING_GROUP)) { - return; + /* + * If not resetting the logging system, keep the old domains around. After + * we're done loading the new configuration, we'll go through the old domains + * and restore any data that needs restoring, and clean up anything else. + */ + VMToolsResetLogging(reset); + if (!reset) { + oldDefault = gDefaultData; + oldDomains = gDomains; + gDomains = NULL; + gDefaultData = NULL; + } + + gLogDomain = g_strdup(defaultDomain); + + /* + * If no logging config data exists, then we install a default log handler, + * just so we override the default glib one, since the caller has asked us to + * enable our logging system. + */ + if (cfg == NULL || !g_key_file_has_group(cfg, LOGGING_GROUP)) { + gDefaultData = g_malloc0(sizeof *gDefaultData); + gDefaultData->domain = g_strdup(defaultDomain); + gDefaultData->mask = G_LOG_LEVEL_ERROR | + G_LOG_LEVEL_CRITICAL | + G_LOG_LEVEL_WARNING; +#if defined(VMX86_DEBUG) + gDefaultData->mask |= G_LOG_LEVEL_MESSAGE; +#endif + g_log_set_default_handler(gDefaultLogFunc, gDefaultData); + goto exit; } /* * Configure the default domain first. See function documentation for * VMToolsConfigLogDomain() for the reason. */ - VMToolsConfigLogDomain(VMTools_GetDefaultLogDomain(), cfg); + VMToolsConfigLogDomain(gLogDomain, cfg); list = g_key_file_get_keys(cfg, LOGGING_GROUP, NULL, NULL); @@ -660,7 +794,7 @@ VMTools_ConfigLogging(GKeyFile *cfg) domain[strlen(domain) - 6] = '\0'; /* Skip the default domain. */ - if (strcmp(domain, VMTools_GetDefaultLogDomain()) == 0) { + if (strcmp(domain, gLogDomain) == 0) { continue; } @@ -674,97 +808,18 @@ VMTools_ConfigLogging(GKeyFile *cfg) gEnableCoreDump = g_key_file_get_boolean(cfg, LOGGING_GROUP, "enableCoreDump", NULL); } -} - - -/** - * Enables of disables all the log domains configured by the vmtools library. - * This doesn't affect other log domains that may have configured by other - * code. - * - * @param[in] enable Whether logging should be enabled. - */ -void -VMTools_EnableLogging(gboolean enable) -{ - gLogEnabled = enable; -} - - -/** - * Resets the vmtools logging subsystem, freeing up data and optionally - * restoring the original glib configuration. - * - * @param[in] cleanDefault Whether to clean up the default handler and - * restore the original glib handler. - */ - -void -VMTools_ResetLogging(gboolean cleanDefault) -{ - gboolean oldLogEnabled = gLogEnabled; - gchar *currentPath = NULL; - FILE *currentFile = NULL; - - /* Disable logging while we're playing with the configuration. */ - gLogEnabled = FALSE; - - if (cleanDefault) { - g_log_set_default_handler(g_log_default_handler, NULL); - } - - if (gDomains != NULL) { - guint i; - for (i = 0; i < gDomains->len; i++) { - LogHandlerData *data = g_ptr_array_index(gDomains, i); - g_log_remove_handler(data->domain, data->handlerId); - if (data->file != NULL) { - fclose(data->file); - } - g_free(data->path); - g_free(data->domain); - g_free(data); +exit: + /* If needed, restore the old configuration. */ + if (!reset) { + VMToolsRestoreLogging(oldDefault, oldDomains); + g_free(oldDefault); + if (oldDomains != NULL) { + g_ptr_array_free(oldDomains, TRUE); } - g_ptr_array_free(gDomains, TRUE); - gDomains = NULL; - } - - if (gDefaultData != NULL) { - currentFile = gDefaultData->file; - currentPath = gDefaultData->path; - g_free(gDefaultData); - gDefaultData = NULL; - } - - if (cleanDefault && gLogDomain != NULL) { - g_free(gLogDomain); - gLogDomain = NULL; } - gDefaultLogFunc = DEFAULT_HANDLER; - - if (!cleanDefault) { - if (gLogDomain == NULL) { - gLogDomain = g_strdup("vmtools"); - } - gDefaultData = g_malloc0(sizeof *gDefaultData); - gDefaultData->mask = G_LOG_LEVEL_ERROR | - G_LOG_LEVEL_CRITICAL | - G_LOG_LEVEL_WARNING; -#if defined(VMX86_DEBUG) - gDefaultData->mask |= G_LOG_LEVEL_MESSAGE; -#endif - gDefaultData->file = currentFile; - gDefaultData->path = currentPath; - gLogEnabled = oldLogEnabled; - g_log_set_default_handler(gDefaultLogFunc, gDefaultData); - } else { - if (currentFile != NULL) { - fclose(currentFile); - } - g_free(currentPath); - } + gLogEnabled |= force; } diff --git a/open-vm-tools/services/vmtoolsd/cmdLine.c b/open-vm-tools/services/vmtoolsd/cmdLine.c index 13b135746..608634f69 100644 --- a/open-vm-tools/services/vmtoolsd/cmdLine.c +++ b/open-vm-tools/services/vmtoolsd/cmdLine.c @@ -235,7 +235,6 @@ ToolsCore_ParseCommandLine(ToolsServiceState *state, exit(0); } - VMTools_EnableLogging(state->log); if (state->name == NULL) { state->name = VMTOOLS_GUEST_SERVICE; state->mainService = TRUE; @@ -247,6 +246,11 @@ ToolsCore_ParseCommandLine(ToolsServiceState *state, state->mainService = (strcmp(state->name, VMTOOLS_GUEST_SERVICE) == 0); } + VMTools_ConfigLogging(state->name, + NULL, + state->log, + FALSE); + #if defined(G_PLATFORM_WIN32) if (kill) { exit(ToolsCoreSignalEvent(state->name, QUIT_EVENT_NAME_FMT) ? 0 : 1); diff --git a/open-vm-tools/services/vmtoolsd/mainLoop.c b/open-vm-tools/services/vmtoolsd/mainLoop.c index 49b231b99..235a11835 100644 --- a/open-vm-tools/services/vmtoolsd/mainLoop.c +++ b/open-vm-tools/services/vmtoolsd/mainLoop.c @@ -206,55 +206,41 @@ ToolsCore_GetTcloName(ToolsServiceState *state) * detected. * * @param[in] state Service state. - * @param[in] force Whether to force reconfiguration of the logging - * subsystem. + * @param[in] reset Whether to reset the logging subsystem. */ void ToolsCore_ReloadConfig(ToolsServiceState *state, - gboolean force) + gboolean reset) { - char *confFile; - gboolean loaded = TRUE; + gboolean first = state->ctx.config == NULL; + gboolean loaded; - VMTools_SetDefaultLogDomain(state->name); + loaded = VMTools_LoadConfig(state->configFile, + G_KEY_FILE_NONE, + &state->ctx.config, + &state->configMtime); - confFile = g_strdup(state->configFile); - if (confFile == NULL) { - confFile = VMTools_GetToolsConfFile(); - } - - if (state->ctx.config == NULL) { - state->ctx.config = VMTools_LoadConfig(confFile, - G_KEY_FILE_NONE, - state->mainService); - state->configMtime = time(NULL); - if (state->ctx.config == NULL) { - /* Couldn't load the config file. Just create an empty dictionary. */ - state->ctx.config = g_key_file_new(); - } - } else if (VMTools_ReloadConfig(confFile, - G_KEY_FILE_NONE, - &state->ctx.config, - &state->configMtime)) { + if (!first && loaded) { g_debug("Config file reloaded.\n"); /* Inform plugins of config file update. */ g_signal_emit_by_name(state->ctx.serviceObj, TOOLS_CORE_SIG_CONF_RELOAD, &state->ctx); - } else { - loaded = FALSE; } - if (force || loaded) { - VMTools_ConfigLogging(state->ctx.config); - if (state->log) { - VMTools_EnableLogging(state->log); - } + if (state->ctx.config == NULL) { + /* Couldn't load the config file. Just create an empty dictionary. */ + state->ctx.config = g_key_file_new(); } - g_free(confFile); + if (reset || loaded) { + VMTools_ConfigLogging(state->name, + state->ctx.config, + state->log, + reset); + } } diff --git a/open-vm-tools/services/vmtoolsd/mainPosix.c b/open-vm-tools/services/vmtoolsd/mainPosix.c index 66647cd09..83833d068 100644 --- a/open-vm-tools/services/vmtoolsd/mainPosix.c +++ b/open-vm-tools/services/vmtoolsd/mainPosix.c @@ -59,7 +59,6 @@ static gboolean ToolsCoreSigHUPCb(const siginfo_t *info, gpointer data) { - VMTools_ResetLogging(TRUE); ToolsCore_ReloadConfig(data, TRUE); return TRUE; } diff --git a/open-vm-tools/services/vmtoolsd/toolsCoreInt.h b/open-vm-tools/services/vmtoolsd/toolsCoreInt.h index c127698aa..54942bd34 100644 --- a/open-vm-tools/services/vmtoolsd/toolsCoreInt.h +++ b/open-vm-tools/services/vmtoolsd/toolsCoreInt.h @@ -125,7 +125,7 @@ ToolsCore_LoadPlugins(ToolsServiceState *state); void ToolsCore_ReloadConfig(ToolsServiceState *state, - gboolean force); + gboolean reset); void ToolsCore_RegisterPlugins(ToolsServiceState *state); diff --git a/open-vm-tools/toolbox/toolboxInt.c b/open-vm-tools/toolbox/toolboxInt.c index 889b8fa8f..8d19c0a02 100644 --- a/open-vm-tools/toolbox/toolboxInt.c +++ b/open-vm-tools/toolbox/toolboxInt.c @@ -106,19 +106,18 @@ Toolbox_GetScriptPath(const gchar *script) // IN GKeyFile * Toolbox_LoadToolsConf(void) { - gchar *path = VMTools_GetToolsConfFile(); - GKeyFile *config; + GKeyFile *config = NULL; - config = VMTools_LoadConfig(path, - G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, - TRUE); + VMTools_LoadConfig(NULL, + G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, + &config, + NULL); if (config == NULL) { Debug("Unable to load config file.\n"); config = g_key_file_new(); } - g_free(path); return config; } @@ -146,18 +145,15 @@ gboolean Toolbox_SaveToolsConf(GKeyFile *config) // IN { gboolean ret = FALSE; - gchar *path = NULL; GError *err = NULL; - path = VMTools_GetToolsConfFile(); - ret = VMTools_WriteConfig(path, config, &err); + ret = VMTools_WriteConfig(NULL, config, &err); if (!ret) { Warning("Error saving conf data: %s\n", err->message); g_clear_error(&err); } - g_free(path); return ret; } diff --git a/open-vm-tools/toolbox/toolboxcmd-scripts.c b/open-vm-tools/toolbox/toolboxcmd-scripts.c index ee51f424d..1e2a16d0b 100644 --- a/open-vm-tools/toolbox/toolboxcmd-scripts.c +++ b/open-vm-tools/toolbox/toolboxcmd-scripts.c @@ -101,19 +101,17 @@ GetConfName(const char *apm) // IN: apm name. static GKeyFile * LoadConfFile(void) { - gchar *confPath; - GKeyFile *confDict; + GKeyFile *confDict = NULL; - confPath = VMTools_GetToolsConfFile(); - confDict = VMTools_LoadConfig(confPath, - G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, - System_IsUserAdmin()); + VMTools_LoadConfig(NULL, + G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, + &confDict, + NULL); if (confDict == NULL) { confDict = g_key_file_new(); } - g_free(confPath); return confDict; } @@ -250,7 +248,6 @@ ScriptToggle(const char *apm, // IN: APM name { const char *path; const char *confName; - gchar *confPath; int ret = EXIT_SUCCESS; GKeyFile *confDict; GError *err = NULL; @@ -271,15 +268,13 @@ ScriptToggle(const char *apm, // IN: APM name } g_key_file_set_string(confDict, "powerops", confName, path); - confPath = VMTools_GetToolsConfFile(); - if (!VMTools_WriteConfig(confPath, confDict, &err)) { + if (!VMTools_WriteConfig(NULL, confDict, &err)) { fprintf(stderr, "Error writing config: %s\n", err->message); g_clear_error(&err); ret = EX_TEMPFAIL; } g_key_file_free(confDict); - g_free(confPath); return ret; } @@ -358,7 +353,6 @@ Script_Set(const char *apm, // IN: APM name { const char *confName; int ret = EXIT_SUCCESS; - gchar *confPath = NULL; GKeyFile *confDict = NULL; GError *err = NULL; @@ -373,19 +367,16 @@ Script_Set(const char *apm, // IN: APM name return EX_USAGE; } - confPath = VMTools_GetToolsConfFile(); confDict = LoadConfFile(); - g_key_file_set_string(confDict, "powerops", confName, path); - if (!VMTools_WriteConfig(confPath, confDict, &err)) { + if (!VMTools_WriteConfig(NULL, confDict, &err)) { fprintf(stderr, "Error writing config: %s\n", err->message); g_clear_error(&err); ret = EX_TEMPFAIL; } g_key_file_free(confDict); - g_free(confPath); return ret; }