From 243dfad2e21a452edf75708cf612583558c50b72 Mon Sep 17 00:00:00 2001 From: Lukas Rusak Date: Tue, 17 Jan 2017 11:11:51 -0800 Subject: [PATCH] open-vm-tools: update to 10.1.0 --- packages/sysutils/open-vm-tools/package.mk | 8 +- .../open-vm-tools-0001_glib-static.patch | 1507 ----------------- .../patches/open-vm-tools-0002_gcc6.patch | 60 - 3 files changed, 6 insertions(+), 1569 deletions(-) delete mode 100644 packages/sysutils/open-vm-tools/patches/open-vm-tools-0001_glib-static.patch delete mode 100644 packages/sysutils/open-vm-tools/patches/open-vm-tools-0002_gcc6.patch diff --git a/packages/sysutils/open-vm-tools/package.mk b/packages/sysutils/open-vm-tools/package.mk index 02fe305af8..6923dc59ee 100644 --- a/packages/sysutils/open-vm-tools/package.mk +++ b/packages/sysutils/open-vm-tools/package.mk @@ -18,12 +18,12 @@ ################################################################################ PKG_NAME="open-vm-tools" -PKG_VERSION="stable-10.0.7" +PKG_VERSION="stable-10.1.0" PKG_ARCH="x86_64" PKG_LICENSE="GPL" PKG_SITE="http://open-vm-tools.sourceforge.net" PKG_URL="https://github.com/vmware/open-vm-tools/archive/${PKG_VERSION}.tar.gz" -PKG_DEPENDS_TARGET="toolchain glib:host glib libdnet" +PKG_DEPENDS_TARGET="toolchain glib:host glib libdnet fuse" PKG_SECTION="virtualization" PKG_SHORTDESC="open-vm-tools: open source implementation of VMware Tools" PKG_LONGDESC="open-vm-tools: open source implementation of VMware Tools" @@ -43,10 +43,14 @@ PKG_CONFIGURE_OPTS_TARGET="--disable-docs \ --without-icu \ --without-procps \ --without-kernel-modules \ + --with-udev-rules-dir=/usr/lib/udev/rules.d/ \ --with-sysroot=$SYSROOT_PREFIX" post_unpack() { mv $PKG_BUILD/$PKG_NAME/* $PKG_BUILD/ + + sed -i -e 's|.*common-agent/etc/config/Makefile.*||' $ROOT/$PKG_BUILD/configure.ac + mkdir -p $ROOT/$PKG_BUILD/common-agent/etc/config } pre_configure_target() { diff --git a/packages/sysutils/open-vm-tools/patches/open-vm-tools-0001_glib-static.patch b/packages/sysutils/open-vm-tools/patches/open-vm-tools-0001_glib-static.patch deleted file mode 100644 index da5671f3ea..0000000000 --- a/packages/sysutils/open-vm-tools/patches/open-vm-tools-0001_glib-static.patch +++ /dev/null @@ -1,1507 +0,0 @@ -diff -Naur a/lib/glibUtils/fileLogger.c b/lib/glibUtils/fileLogger.c ---- a/lib/glibUtils/fileLogger.c 2015-11-24 07:59:42.000000000 +0100 -+++ b/lib/glibUtils/fileLogger.c 2016-01-15 10:22:59.976153011 +0100 -@@ -44,7 +44,7 @@ - guint maxFiles; - gboolean append; - gboolean error; -- GStaticMutex lock; -+ GMutex lock; - } FileLogger; - - -@@ -327,7 +327,7 @@ - FileLogger *logger = data; - gsize written; - -- g_static_mutex_lock(&logger->lock); -+ g_mutex_lock(&logger->lock); - - if (logger->error) { - goto exit; -@@ -366,7 +366,7 @@ - } - - exit: -- g_static_mutex_unlock(&logger->lock); -+ g_mutex_unlock(&logger->lock); - } - - -@@ -388,7 +388,7 @@ - if (logger->file != NULL) { - g_io_channel_unref(logger->file); - } -- g_static_mutex_free(&logger->lock); -+ g_mutex_free(&logger->lock); - g_free(logger->path); - g_free(logger); - } -@@ -435,7 +435,7 @@ - data->append = append; - data->maxSize = maxSize * 1024 * 1024; - data->maxFiles = maxFiles + 1; /* To account for the active log file. */ -- g_static_mutex_init(&data->lock); -+ g_mutex_init(&data->lock); - - return &data->handler; - } -diff -Naur a/lib/glibUtils/stdLogger.c b/lib/glibUtils/stdLogger.c ---- a/lib/glibUtils/stdLogger.c 2015-11-24 07:59:42.000000000 +0100 -+++ b/lib/glibUtils/stdLogger.c 2016-01-15 10:24:07.078256206 +0100 -@@ -66,12 +66,12 @@ - StdLogger *sdata = data; - - if (!sdata->attached) { -- g_static_mutex_lock(&gConsoleLock); -+ g_mutex_lock(&gConsoleLock); - if (gRefCount != 0 || GlibUtils_AttachConsole()) { - gRefCount++; - sdata->attached = TRUE; - } -- g_static_mutex_unlock(&gConsoleLock); -+ g_mutex_unlock(&gConsoleLock); - } - - if (!sdata->attached) { -@@ -105,11 +105,11 @@ - { - #if defined(_WIN32) - StdLogger *sdata = data; -- g_static_mutex_lock(&gConsoleLock); -+ g_mutex_lock(&gConsoleLock); - if (sdata->attached && --gRefCount == 0) { - FreeConsole(); - } -- g_static_mutex_unlock(&gConsoleLock); -+ g_mutex_unlock(&gConsoleLock); - #endif - g_free(data); - } -diff -Naur a/lib/glibUtils/sysLogger.c b/lib/glibUtils/sysLogger.c ---- a/lib/glibUtils/sysLogger.c 2015-11-24 07:59:42.000000000 +0100 -+++ b/lib/glibUtils/sysLogger.c 2016-01-15 10:37:53.148968674 +0100 -@@ -38,7 +38,7 @@ - - - static SysLogger *gSysLogger; --static GStaticMutex gSysLoggerLock = G_STATIC_MUTEX_INIT; -+static GMutex gSysLoggerLock; - - - /* -@@ -105,7 +105,7 @@ - { - g_return_if_fail(data == gSysLogger); - g_return_if_fail(gSysLogger->refcount > 0); -- g_static_mutex_lock(&gSysLoggerLock); -+ g_mutex_lock(&gSysLoggerLock); - gSysLogger->refcount -= 1; - if (gSysLogger->refcount == 0) { - closelog(); -@@ -113,7 +113,7 @@ - g_free(gSysLogger); - gSysLogger = NULL; - } -- g_static_mutex_unlock(&gSysLoggerLock); -+ g_mutex_unlock(&gSysLoggerLock); - } - - -@@ -140,7 +140,7 @@ - GlibUtils_CreateSysLogger(const char *domain, - const char *facility) - { -- g_static_mutex_lock(&gSysLoggerLock); -+ g_mutex_lock(&gSysLoggerLock); - if (gSysLogger == NULL) { - int facid = LOG_USER; - -@@ -203,7 +203,7 @@ - } else { - gSysLogger->refcount += 1; - } -- g_static_mutex_unlock(&gSysLoggerLock); -+ g_mutex_unlock(&gSysLoggerLock); - return &gSysLogger->handler; - } - -diff -Naur a/lib/rpcChannel/rpcChannelInt.h b/lib/rpcChannel/rpcChannelInt.h ---- a/lib/rpcChannel/rpcChannelInt.h 2015-11-24 07:59:42.000000000 +0100 -+++ b/lib/rpcChannel/rpcChannelInt.h 2016-01-15 11:30:31.403376775 +0100 -@@ -53,7 +53,7 @@ - GMainContext *mainCtx; - const char *appName; - gpointer appCtx; -- GStaticMutex outLock; -+ GMutex outLock; - struct RpcIn *in; - gboolean inStarted; - gboolean outStarted; -diff -Naur a/libvmtools/vmtoolsLog.c b/libvmtools/vmtoolsLog.c ---- a/libvmtools/vmtoolsLog.c 2015-11-24 07:59:42.000000000 +0100 -+++ b/libvmtools/vmtoolsLog.c 2016-01-15 11:34:45.221864504 +0100 -@@ -160,7 +160,7 @@ - static LogHandler *gErrorSyslog; - static GPtrArray *gDomains = NULL; - static gboolean gLogInitialized = FALSE; --static GStaticRecMutex gLogStateMutex = G_STATIC_REC_MUTEX_INIT; -+static GRecMutex gLogStateMutex; - static gboolean gLoggingStopped = FALSE; - static gboolean gLogIOSuspended = FALSE; - -@@ -1055,7 +1055,7 @@ - gLogEnabled |= force; - if (!gLogInitialized) { - gLogInitialized = TRUE; -- g_static_rec_mutex_init(&gLogStateMutex); -+ g_rec_mutex_init(&gLogStateMutex); - } - - gMaxCacheEntries = g_key_file_get_integer(cfg, LOGGING_GROUP, -@@ -1221,7 +1221,7 @@ - void - VMTools_AcquireLogStateLock(void) - { -- g_static_rec_mutex_lock(&gLogStateMutex); -+ g_rec_mutex_lock(&gLogStateMutex); - } - - -@@ -1232,7 +1232,7 @@ - void - VMTools_ReleaseLogStateLock(void) - { -- g_static_rec_mutex_unlock(&gLogStateMutex); -+ g_rec_mutex_unlock(&gLogStateMutex); - } - - -diff -Naur a/libvmtools/i18n.c b/libvmtools/i18n.c ---- a/libvmtools/i18n.c 2015-11-24 07:59:42.000000000 +0100 -+++ b/libvmtools/i18n.c 2016-01-15 11:37:18.900142179 +0100 -@@ -54,7 +54,7 @@ - - typedef struct MsgState { - HashTable *domains; /* List of text domains. */ -- GStaticMutex lock; /* Mutex to protect shared state. */ -+ GMutex lock; /* Mutex to protect shared state. */ - } MsgState; - - -@@ -132,7 +132,7 @@ - { - ASSERT(gMsgState == NULL); - gMsgState = g_new0(MsgState, 1); -- g_static_mutex_init(&gMsgState->lock); -+ g_mutex_init(&gMsgState->lock); - return NULL; - } - -@@ -343,7 +343,7 @@ - * This lock is pretty coarse-grained, but a lot of the code below just runs - * in exceptional situations, so it should be OK. - */ -- g_static_mutex_lock(&state->lock); -+ g_mutex_lock(&state->lock); - - catalog = MsgGetCatalog(domain); - if (catalog != NULL) { -@@ -414,7 +414,7 @@ - } - } - -- g_static_mutex_unlock(&state->lock); -+ g_mutex_unlock(&state->lock); - - return strp; - } -@@ -681,7 +681,7 @@ - if (gMsgState->domains != NULL) { - HashTable_Free(gMsgState->domains); - } -- g_static_mutex_free(&gMsgState->lock); -+ g_mutex_free(&gMsgState->lock); - g_free(gMsgState); - } - } -@@ -774,9 +774,9 @@ - "catalog dir '%s'.\n", domain, lang, catdir); - } - } else { -- g_static_mutex_lock(&state->lock); -+ g_mutex_lock(&state->lock); - MsgSetCatalog(domain, catalog); -- g_static_mutex_unlock(&state->lock); -+ g_mutex_unlock(&state->lock); - } - g_free(file); - free(dfltdir); -diff -Naur a/lib/rpcChannel/rpcChannel.c b/lib/rpcChannel/rpcChannel.c ---- a/lib/rpcChannel/rpcChannel.c 2015-11-24 07:59:42.000000000 +0100 -+++ b/lib/rpcChannel/rpcChannel.c 2016-01-15 11:46:08.061147289 +0100 -@@ -675,7 +675,7 @@ - chan = BackdoorChannel_New(); - #endif - if (chan) { -- g_static_mutex_init(&chan->outLock); -+ g_mutex_init(&chan->outLock); - } - return chan; - } -@@ -691,7 +691,7 @@ - RpcChannel_Shutdown(RpcChannel *chan) - { - if (chan != NULL) { -- g_static_mutex_free(&chan->outLock); -+ g_mutex_free(&chan->outLock); - } - - if (chan != NULL && chan->funcs != NULL && chan->funcs->shutdown != NULL) { -@@ -776,7 +776,7 @@ - g_return_if_fail(chan->funcs != NULL); - g_return_if_fail(chan->funcs->stop != NULL); - -- g_static_mutex_lock(&chan->outLock); -+ g_mutex_lock(&chan->outLock); - chan->funcs->stop(chan); - - if (chan->in != NULL) { -@@ -787,7 +787,7 @@ - } else { - ASSERT(!chan->inStarted); - } -- g_static_mutex_unlock(&chan->outLock); -+ g_mutex_unlock(&chan->outLock); - } - - -@@ -853,7 +853,7 @@ - - ASSERT(chan && chan->funcs); - -- g_static_mutex_lock(&chan->outLock); -+ g_mutex_lock(&chan->outLock); - - funcs = chan->funcs; - ASSERT(funcs->send); -@@ -902,7 +902,7 @@ - } - - exit: -- g_static_mutex_unlock(&chan->outLock); -+ g_mutex_unlock(&chan->outLock); - return ok; - } - -diff -Naur a/lib/rpcChannel/rpcChannel.c.save b/lib/rpcChannel/rpcChannel.c.save ---- a/lib/rpcChannel/rpcChannel.c.save 1970-01-01 01:00:00.000000000 +0100 -+++ b/lib/rpcChannel/rpcChannel.c.save 2016-01-15 11:44:57.245012048 +0100 -@@ -0,0 +1,1049 @@ -+/********************************************************* -+ * Copyright (C) 2008-2015 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 -+ * by the Free Software Foundation version 2.1 and no later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public -+ * License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ *********************************************************/ -+ -+/** -+ * @file rpcChannel.c -+ * -+ * Common functions to all RPC channel implementations. -+ */ -+ -+#include -+#include "vm_assert.h" -+#include "dynxdr.h" -+#include "rpcChannelInt.h" -+#include "str.h" -+#include "strutil.h" -+#include "vmxrpc.h" -+#include "xdrutil.h" -+#include "rpcin.h" -+#include "debug.h" -+ -+/** Internal state of a channel. */ -+typedef struct RpcChannelInt { -+ RpcChannel impl; -+ gchar *appName; -+ GHashTable *rpcs; -+ GMainContext *mainCtx; -+ GSource *resetCheck; -+ gpointer appCtx; -+ RpcChannelCallback resetReg; -+ RpcChannelResetCb resetCb; -+ gpointer resetData; -+ gboolean rpcError; -+ guint rpcErrorCount; -+} RpcChannelInt; -+ -+/** Max number of times to attempt a channel restart. */ -+#define RPCIN_MAX_RESTARTS 60 -+ -+#define LGPFX "RpcChannel: " -+ -+static gboolean -+RpcChannelPing(RpcInData *data); -+ -+static RpcChannelCallback gRpcHandlers[] = { -+ { "ping", RpcChannelPing, NULL, NULL, NULL, 0 } -+}; -+ -+static gboolean gUseBackdoorOnly = FALSE; -+ -+/* -+ * Track the vSocket connection failure, so that we can -+ * avoid using vSockets until a channel reset/restart or -+ * the service itself gets restarted. -+ */ -+static gboolean gVSocketFailed = FALSE; -+ -+/** -+ * Handler for a "ping" message. Does nothing. -+ * -+ * @param[in] data The RPC data. -+ * -+ * @return TRUE. -+ */ -+ -+static gboolean -+RpcChannelPing(RpcInData *data) -+{ -+ return RPCIN_SETRETVALS(data, "", TRUE); -+} -+ -+ -+/** -+ * Callback for restarting the RPC channel. -+ * -+ * @param[in] _chan The RPC channel -+ * -+ * @return FALSE -+ */ -+ -+static gboolean -+RpcChannelRestart(gpointer _chan) -+{ -+ RpcChannelInt *chan = _chan; -+ -+ RpcChannel_Stop(&chan->impl); -+ /* Clear vSocket channel failure */ -+ Debug(LGPFX "Clearing backdoor behavior ...\n"); -+ gVSocketFailed = FALSE; -+ -+ 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; -+} -+ -+ -+/** -+ * Checks and potentially resets the RPC channel. This code is based on the -+ * toolsDaemon.c function "ToolsDaemon_CheckReset". -+ * -+ * @param[in] _chan The RPC channel. -+ * -+ * @return FALSE. The reset callback will schedule a new check when it's called. -+ */ -+ -+static gboolean -+RpcChannelCheckReset(gpointer _chan) -+{ -+ static int channelTimeoutAttempts = RPCIN_MAX_RESTARTS; -+ RpcChannelInt *chan = _chan; -+ -+ /* Check the channel state. */ -+ if (chan->rpcError) { -+ GSource *src; -+ -+ if (++(chan->rpcErrorCount) > channelTimeoutAttempts) { -+ Warning("Failed to reset channel after %u attempts\n", -+ chan->rpcErrorCount - 1); -+ if (chan->resetCb != NULL) { -+ chan->resetCb(&chan->impl, FALSE, chan->resetData); -+ } -+ goto exit; -+ } -+ -+ /* Schedule the channel restart for 1 sec in the future. */ -+ Debug(LGPFX "Resetting channel [%u]\n", chan->rpcErrorCount); -+ src = g_timeout_source_new(1000); -+ g_source_set_callback(src, RpcChannelRestart, chan, NULL); -+ g_source_attach(src, chan->mainCtx); -+ g_source_unref(src); -+ goto exit; -+ } -+ -+ /* Reset was successful. */ -+ Debug(LGPFX "Channel was reset successfully.\n"); -+ chan->rpcErrorCount = 0; -+ Debug(LGPFX "Clearing backdoor behavior ...\n"); -+ gVSocketFailed = FALSE; -+ -+ if (chan->resetCb != NULL) { -+ chan->resetCb(&chan->impl, TRUE, chan->resetData); -+ } -+ -+exit: -+ g_source_unref(chan->resetCheck); -+ chan->resetCheck = NULL; -+ return FALSE; -+} -+ -+ -+/** -+ * Handles an RPC reset. Calls the reset callback of all loaded plugins. -+ * -+ * @param[in] data The RPC data. -+ * -+ * @return TRUE. -+ */ -+ -+static gboolean -+RpcChannelReset(RpcInData *data) -+{ -+ gchar *msg; -+ RpcChannelInt *chan = data->clientData; -+ -+ if (chan->resetCheck == NULL) { -+ chan->resetCheck = g_idle_source_new(); -+ g_source_set_priority(chan->resetCheck, G_PRIORITY_HIGH); -+ g_source_set_callback(chan->resetCheck, RpcChannelCheckReset, chan, NULL); -+ g_source_attach(chan->resetCheck, chan->mainCtx); -+ } -+ -+ msg = Str_Asprintf(NULL, "ATR %s", chan->appName); -+ ASSERT_MEM_ALLOC(msg); -+ return RPCIN_SETRETVALSF(data, msg, TRUE); -+} -+ -+ -+/** -+ * A wrapper for standard RPC callback functions which provides automatic -+ * XDR serialization / deserialization if requested by the application. -+ * -+ * @param[in] data RpcIn data. -+ * @param[in] rpc The RPC registration data. -+ * -+ * @return Whether the RPC was handled successfully. -+ */ -+ -+static Bool -+RpcChannelXdrWrapper(RpcInData *data, -+ RpcChannelCallback *rpc) -+{ -+ Bool ret; -+ RpcInData copy; -+ void *xdrData = NULL; -+ -+ if (rpc->xdrIn != NULL) { -+ xdrData = malloc(rpc->xdrInSize); -+ if (xdrData == NULL) { -+ ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE); -+ goto exit; -+ } -+ -+ memset(xdrData, 0, rpc->xdrInSize); -+ if (!XdrUtil_Deserialize(data->args + 1, data->argsSize - 1, -+ rpc->xdrIn, xdrData)) { -+ ret = RPCIN_SETRETVALS(data, "XDR deserialization failed.", FALSE); -+ free(xdrData); -+ goto exit; -+ } -+ -+ copy.name = data->name; -+ copy.args = xdrData; -+ copy.argsSize = rpc->xdrInSize; -+ copy.result = data->result; -+ copy.resultLen = data->resultLen; -+ copy.freeResult = data->freeResult; -+ copy.appCtx = data->appCtx; -+ copy.clientData = rpc->clientData; -+ } else { -+ memcpy(©, data, sizeof copy); -+ } -+ -+ ret = rpc->callback(©); -+ -+ if (rpc->xdrIn != NULL) { -+ VMX_XDR_FREE(rpc->xdrIn, xdrData); -+ free(xdrData); -+ copy.args = NULL; -+ data->result = copy.result; -+ data->resultLen = copy.resultLen; -+ data->freeResult = copy.freeResult; -+ } -+ -+ if (rpc->xdrOut != NULL && copy.result != NULL) { -+ XDR xdrs; -+ xdrproc_t xdrProc = rpc->xdrOut; -+ -+ if (DynXdr_Create(&xdrs) == NULL) { -+ ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE); -+ goto exit; -+ } -+ -+ if (!xdrProc(&xdrs, copy.result)) { -+ ret = RPCIN_SETRETVALS(data, "XDR serialization failed.", FALSE); -+ DynXdr_Destroy(&xdrs, TRUE); -+ goto exit; -+ } -+ -+ if (copy.freeResult) { -+ VMX_XDR_FREE(rpc->xdrOut, copy.result); -+ } -+ data->result = DynXdr_Get(&xdrs); -+ data->resultLen = XDR_GETPOS(&xdrs); -+ data->freeResult = TRUE; -+ DynXdr_Destroy(&xdrs, FALSE); -+ } -+ -+exit: -+ if (copy.freeResult && copy.result != NULL) { -+ g_free(copy.result); -+ } -+ return ret; -+} -+ -+ -+/** -+ * Builds an "rpcout" command to send a XDR struct. -+ * -+ * @param[in] cmd The command name. -+ * @param[in] xdrProc Function to use for serializing the XDR struct. -+ * @param[in] xdrData The XDR struct to serialize. -+ * @param[out] result Where to store the serialized data. -+ * @param[out] resultLen Where to store the serialized data length. -+ * -+ * @return Whether successfully built the command. -+ */ -+ -+gboolean -+RpcChannel_BuildXdrCommand(const char *cmd, -+ void *xdrProc, -+ void *xdrData, -+ char **result, -+ size_t *resultLen) -+{ -+ Bool ret = FALSE; -+ xdrproc_t proc = xdrProc; -+ XDR xdrs; -+ -+ if (DynXdr_Create(&xdrs) == NULL) { -+ return FALSE; -+ } -+ -+ if (!DynXdr_AppendRaw(&xdrs, cmd, strlen(cmd))) { -+ goto exit; -+ } -+ -+ if (!DynXdr_AppendRaw(&xdrs, " ", 1)) { -+ goto exit; -+ } -+ -+ if (!proc(&xdrs, xdrData)) { -+ goto exit; -+ } -+ -+ *result = DynXdr_Get(&xdrs); -+ *resultLen = xdr_getpos(&xdrs); -+ -+ ret = TRUE; -+ -+exit: -+ DynXdr_Destroy(&xdrs, !ret); -+ return ret; -+} -+ -+ -+/** -+ * Creates a new RpcChannel without any implementation. -+ * -+ * This is mainly for use of code that is implementing a custom RpcChannel. -+ * Such implementations should provide their own "constructor"-type function -+ * which should then call this function to get an RpcChannel instance. They -+ * should then fill in the function pointers that provide the implementation -+ * for the channel before making the channel available to the callers. -+ * -+ * @return A new RpcChannel instance. -+ */ -+ -+RpcChannel * -+RpcChannel_Create(void) -+{ -+ RpcChannelInt *chan = g_new0(RpcChannelInt, 1); -+ return &chan->impl; -+} -+ -+ -+/** -+ * Dispatches the given RPC to the registered handler. This mimics the behavior -+ * of the RpcIn library (but is not tied to that particular implementation of -+ * an RPC channel). -+ * -+ * @param[in,out] data The RPC data. -+ * -+ * @return Whether the RPC was handled successfully. -+ */ -+ -+gboolean -+RpcChannel_Dispatch(RpcInData *data) -+{ -+ char *name = NULL; -+ unsigned int index = 0; -+ size_t nameLen; -+ Bool status; -+ RpcChannelCallback *rpc = NULL; -+ RpcChannelInt *chan = data->clientData; -+ -+ name = StrUtil_GetNextToken(&index, data->args, " "); -+ if (name == NULL) { -+ Debug(LGPFX "Bad command (null) received.\n"); -+ status = RPCIN_SETRETVALS(data, "Bad command", FALSE); -+ goto exit; -+ } -+ -+ if (chan->rpcs != NULL) { -+ rpc = g_hash_table_lookup(chan->rpcs, name); -+ } -+ -+ if (rpc == NULL) { -+ Debug(LGPFX "Unknown Command '%s': Handler not registered.\n", name); -+ status = RPCIN_SETRETVALS(data, "Unknown Command", FALSE); -+ goto exit; -+ } -+ -+ /* Adjust the RPC arguments. */ -+ nameLen = strlen(name); -+ data->name = name; -+ data->args = data->args + nameLen; -+ data->argsSize -= nameLen; -+ data->appCtx = chan->appCtx; -+ data->clientData = rpc->clientData; -+ -+ if (rpc->xdrIn != NULL || rpc->xdrOut != NULL) { -+ status = RpcChannelXdrWrapper(data, rpc); -+ } else { -+ status = rpc->callback(data); -+ } -+ -+ ASSERT(data->result != NULL); -+ -+exit: -+ data->name = NULL; -+ free(name); -+ return status; -+} -+ -+ -+/** -+ * Shuts down an RPC channel and release any held resources. -+ * -+ * @param[in] chan The RPC channel. -+ * -+ * @return Whether the channel was shut down successfully. -+ */ -+ -+gboolean -+RpcChannel_Destroy(RpcChannel *chan) -+{ -+ size_t i; -+ RpcChannelInt *cdata = (RpcChannelInt *) chan; -+ -+ if (cdata->impl.funcs != NULL && cdata->impl.funcs->shutdown != NULL) { -+ cdata->impl.funcs->shutdown(chan); -+ } -+ -+ RpcChannel_UnregisterCallback(chan, &cdata->resetReg); -+ for (i = 0; i < ARRAYSIZE(gRpcHandlers); i++) { -+ RpcChannel_UnregisterCallback(chan, &gRpcHandlers[i]); -+ } -+ -+ if (cdata->rpcs != NULL) { -+ g_hash_table_destroy(cdata->rpcs); -+ cdata->rpcs = NULL; -+ } -+ -+ cdata->resetCb = NULL; -+ cdata->resetData = NULL; -+ cdata->appCtx = NULL; -+ -+ g_free(cdata->appName); -+ cdata->appName = NULL; -+ -+ if (cdata->mainCtx != NULL) { -+ g_main_context_unref(cdata->mainCtx); -+ cdata->mainCtx = NULL; -+ } -+ -+ if (cdata->resetCheck != NULL) { -+ g_source_destroy(cdata->resetCheck); -+ cdata->resetCheck = NULL; -+ } -+ -+ g_free(cdata); -+ return TRUE; -+} -+ -+ -+/** -+ * Error handling function for the RPC channel. Enqueues the "check reset" -+ * function for running later, if it's not yet enqueued. -+ * -+ * @param[in] _chan The RPC channel. -+ * @param[in] status Error description. -+ */ -+ -+void -+RpcChannel_Error(void *_chan, -+ char const *status) -+{ -+ RpcChannelInt *chan = _chan; -+ chan->rpcError = TRUE; -+ /* -+ * XXX: Workaround for PR 935520. -+ * Revert the log call to Warning() after fixing PR 955746. -+ */ -+ Debug(LGPFX "Error in the RPC receive loop: %s.\n", status); -+ -+ if (chan->resetCheck == NULL) { -+ chan->resetCheck = g_idle_source_new(); -+ g_source_set_callback(chan->resetCheck, RpcChannelCheckReset, chan, NULL); -+ g_source_attach(chan->resetCheck, chan->mainCtx); -+ } -+} -+ -+ -+/** -+ * Initializes the RPC channel for inbound operations. -+ * -+ * This function must be called before starting the channel if the application -+ * wants to receive messages on the channel. Applications don't need to call it -+ * if only using the outbound functionality. -+ * -+ * @param[in] chan The RPC channel. -+ * @param[in] appName TCLO application name. -+ * @param[in] mainCtx Application event context. -+ * @param[in] appCtx Application context. -+ * @param[in] resetCb Callback for when a reset occurs. -+ * @param[in] resetData Client data for the reset callback. -+ */ -+ -+void -+RpcChannel_Setup(RpcChannel *chan, -+ const gchar *appName, -+ GMainContext *mainCtx, -+ gpointer appCtx, -+ RpcChannelResetCb resetCb, -+ gpointer resetData) -+{ -+ size_t i; -+ RpcChannelInt *cdata = (RpcChannelInt *) chan; -+ -+ cdata->appName = g_strdup(appName); -+ cdata->appCtx = appCtx; -+ cdata->mainCtx = g_main_context_ref(mainCtx); -+ cdata->resetCb = resetCb; -+ cdata->resetData = resetData; -+ -+ cdata->resetReg.name = "reset"; -+ cdata->resetReg.callback = RpcChannelReset; -+ cdata->resetReg.clientData = chan; -+ -+ /* Register the callbacks handled by the rpcChannel library. */ -+ RpcChannel_RegisterCallback(chan, &cdata->resetReg); -+ -+ for (i = 0; i < ARRAYSIZE(gRpcHandlers); i++) { -+ RpcChannel_RegisterCallback(chan, &gRpcHandlers[i]); -+ } -+ -+ if (chan->funcs != NULL && chan->funcs->setup != NULL) { -+ chan->funcs->setup(chan, mainCtx, appName, appCtx); -+ } else { -+ chan->mainCtx = g_main_context_ref(mainCtx); -+ chan->in = RpcIn_Construct(mainCtx, RpcChannel_Dispatch, chan); -+ ASSERT(chan->in != NULL); -+ } -+} -+ -+ -+/** -+ * Sets the non-freeable result of the given RPC context to the given value. -+ * The result should be a NULL-terminated string. -+ * -+ * @param[in] data RPC context. -+ * @param[in] result Result string. -+ * @param[in] retVal Return value of this function. -+ * -+ * @return @a retVal -+ */ -+ -+gboolean -+RpcChannel_SetRetVals(RpcInData *data, -+ char const *result, -+ gboolean retVal) -+{ -+ ASSERT(data); -+ -+ /* This cast is safe: data->result will not be freed. */ -+ data->result = (char *)result; -+ data->resultLen = strlen(data->result); -+ data->freeResult = FALSE; -+ -+ return retVal; -+} -+ -+ -+/** -+ * Sets the freeable result of the given RPC context to the given value. -+ * The result should be a NULL-terminated string. -+ * -+ * @param[in] data RPC context. -+ * @param[in] result Result string. -+ * @param[in] retVal Return value of this function. -+ * -+ * @return @a retVal -+ */ -+ -+gboolean -+RpcChannel_SetRetValsF(RpcInData *data, -+ char *result, -+ gboolean retVal) -+{ -+ ASSERT(data); -+ -+ data->result = result; -+ data->resultLen = strlen(data->result); -+ data->freeResult = TRUE; -+ -+ return retVal; -+} -+ -+ -+/** -+ * Registers a new RPC handler in the given RPC channel. This function is -+ * not thread-safe. -+ * -+ * @param[in] chan The channel instance. -+ * @param[in] rpc Info about the RPC being registered. -+ */ -+ -+void -+RpcChannel_RegisterCallback(RpcChannel *chan, -+ RpcChannelCallback *rpc) -+{ -+ RpcChannelInt *cdata = (RpcChannelInt *) chan; -+ ASSERT(rpc->name != NULL && strlen(rpc->name) > 0); -+ ASSERT(rpc->callback); -+ ASSERT(rpc->xdrIn == NULL || rpc->xdrInSize > 0); -+ if (cdata->rpcs == NULL) { -+ cdata->rpcs = g_hash_table_new(g_str_hash, g_str_equal); -+ } -+ if (g_hash_table_lookup(cdata->rpcs, rpc->name) != NULL) { -+ Panic("Trying to overwrite existing RPC registration for %s!\n", rpc->name); -+ } -+ g_hash_table_insert(cdata->rpcs, (gpointer) rpc->name, rpc); -+} -+ -+ -+/** -+ * Unregisters a new RPC handler from the given RPC channel. This function is -+ * not thread-safe. -+ * -+ * @param[in] chan The channel instance. -+ * @param[in] rpc Info about the RPC being unregistered. -+ */ -+ -+void -+RpcChannel_UnregisterCallback(RpcChannel *chan, -+ RpcChannelCallback *rpc) -+{ -+ RpcChannelInt *cdata = (RpcChannelInt *) chan; -+ if (cdata->rpcs != NULL) { -+ g_hash_table_remove(cdata->rpcs, rpc->name); -+ } -+} -+ -+ -+/** -+ * Force to create backdoor channels only. -+ * This provides a kill-switch to disable vsocket channels if needed. -+ * This needs to be called before RpcChannel_New to take effect. -+ */ -+ -+void -+RpcChannel_SetBackdoorOnly(void) -+{ -+ gUseBackdoorOnly = TRUE; -+ Debug(LGPFX "Using vsocket is disabled.\n"); -+} -+ -+ -+/** -+ * Create an RpcChannel instance using a prefered channel implementation, -+ * currently this is VSockChannel. -+ * -+ * @return RpcChannel -+ */ -+ -+RpcChannel * -+RpcChannel_New(void) -+{ -+ RpcChannel *chan; -+#if (defined(__linux__) && !defined(USERWORLD)) || defined(_WIN32) -+ chan = (gUseBackdoorOnly || gVSocketFailed) ? -+ BackdoorChannel_New() : VSockChannel_New(); -+#else -+ chan = BackdoorChannel_New(); -+#endif -+ if (chan) { -+ g_mutex_init(&chan->outLock); -+ } -+ return chan; -+} -+ -+ -+/** -+ * Wrapper for the shutdown function of an RPC channel struct. -+ * -+ * @param[in] chan The RPC channel instance. -+ */ -+ -+void -+RpcChannel_Shutdown(RpcChannel *chan) -+{ -+ if (chan != NULL) { -+ g_static_mutex_free(&chan->outLock); -+ } -+ -+ if (chan != NULL && chan->funcs != NULL && chan->funcs->shutdown != NULL) { -+ if (chan->in != NULL) { -+ if (chan->inStarted) { -+ RpcIn_stop(chan->in); -+ } -+ chan->inStarted = FALSE; -+ RpcIn_Destruct(chan->in); -+ chan->in = NULL; -+ } else { -+ ASSERT(!chan->inStarted); -+ } -+ -+ if (chan->mainCtx != NULL) { -+ g_main_context_unref(chan->mainCtx); -+ } -+ chan->funcs->shutdown(chan); -+ } -+} -+ -+ -+/** -+ * Start an RPC channel. We may fallback to backdoor channel when other type -+ * of channel fails to start. -+ * -+ * @param[in] chan The RPC channel instance. -+ * -+ * @return TRUE on success. -+ */ -+ -+gboolean -+RpcChannel_Start(RpcChannel *chan) -+{ -+ gboolean ok; -+ const RpcChannelFuncs *funcs; -+ -+ if (chan == NULL || chan->funcs == NULL || chan->funcs->start == NULL) { -+ return FALSE; -+ } -+ -+ if (chan->outStarted) { -+ /* Already started. Make sure both channels are in sync and return. */ -+ ASSERT(chan->in == NULL || chan->inStarted); -+ return TRUE; -+ } -+ -+ if (chan->in != NULL && !chan->inStarted) { -+ ok = RpcIn_start(chan->in, RPCIN_MAX_DELAY, RpcChannel_Error, chan); -+ chan->inStarted = ok; -+ } -+ -+ funcs = chan->funcs; -+ ok = funcs->start(chan); -+ -+ if (!ok && funcs->onStartErr != NULL) { -+ Debug(LGPFX "Fallback to backdoor ...\n"); -+ funcs->onStartErr(chan); -+ ok = BackdoorChannel_Fallback(chan); -+ /* -+ * As vSocket is not available, we stick the backdoor -+ * behavior until the channel is reset/restarted. -+ */ -+ Debug(LGPFX "Sticking backdoor behavior ...\n"); -+ gVSocketFailed = TRUE; -+ } -+ -+ return ok; -+} -+ -+ -+/** -+ * Wrapper for the stop function of an RPC channel struct. -+ * -+ * @param[in] chan The RPC channel instance. -+ */ -+ -+void -+RpcChannel_Stop(RpcChannel *chan) -+{ -+ g_return_if_fail(chan != NULL); -+ g_return_if_fail(chan->funcs != NULL); -+ g_return_if_fail(chan->funcs->stop != NULL); -+ -+ g_static_mutex_lock(&chan->outLock); -+ chan->funcs->stop(chan); -+ -+ if (chan->in != NULL) { -+ if (chan->inStarted) { -+ RpcIn_stop(chan->in); -+ } -+ chan->inStarted = FALSE; -+ } else { -+ ASSERT(!chan->inStarted); -+ } -+ g_static_mutex_unlock(&chan->outLock); -+} -+ -+ -+/** -+ * Wrapper for get channel type function of an RPC channel struct. -+ * -+ * @param[in] chan The RPC channel instance. -+ */ -+ -+RpcChannelType -+RpcChannel_GetType(RpcChannel *chan) -+{ -+ if (chan == NULL || chan->funcs == NULL || chan->funcs->getType == NULL) { -+ return RPCCHANNEL_TYPE_INACTIVE; -+ } -+ return chan->funcs->getType(chan); -+} -+ -+ -+/** -+ * Free the allocated memory for the results from RpcChannel_Send* calls. -+ * -+ * @param[in] ptr result from RpcChannel_Send* calls. -+ * -+ * @return none -+ */ -+ -+void -+RpcChannel_Free(void *ptr) -+{ -+ free(ptr); -+} -+ -+ -+/** -+ * Send function of an RPC channel struct. Retry once if it fails for -+ * non-backdoor Channels. Backdoor channel already tries inside. A second try -+ * may create a different type of channel. -+ * -+ * @param[in] chan The RPC channel instance. -+ * @param[in] data Data to send. -+ * @param[in] dataLen Number of bytes to send. -+ * @param[out] result Response from other side (should be freed by -+ * calling RpcChannel_Free). -+ * @param[out] resultLen Number of bytes in response. -+ * -+ * @return The status from the remote end (TRUE if call was successful). -+ */ -+ -+gboolean -+RpcChannel_Send(RpcChannel *chan, -+ char const *data, -+ size_t dataLen, -+ char **result, -+ size_t *resultLen) -+{ -+ gboolean ok; -+ char *res = NULL; -+ size_t resLen = 0; -+ const RpcChannelFuncs *funcs; -+ -+ Debug(LGPFX "Sending: %"FMTSZ"u bytes\n", dataLen); -+ -+ ASSERT(chan && chan->funcs); -+ -+ g_static_mutex_lock(&chan->outLock); -+ -+ funcs = chan->funcs; -+ ASSERT(funcs->send); -+ -+ if (result != NULL) { -+ *result = NULL; -+ } -+ if (resultLen != NULL) { -+ *resultLen = 0; -+ } -+ -+ ok = funcs->send(chan, data, dataLen, &res, &resLen); -+ -+ if (!ok && (funcs->getType(chan) != RPCCHANNEL_TYPE_BKDOOR) && -+ (funcs->stopRpcOut != NULL)) { -+ -+ free(res); -+ res = NULL; -+ resLen = 0; -+ -+ /* retry once */ -+ Debug(LGPFX "Stop RpcOut channel and try to send again ...\n"); -+ funcs->stopRpcOut(chan); -+ if (RpcChannel_Start(chan)) { -+ /* The channel may get switched from vsocket to backdoor */ -+ funcs = chan->funcs; -+ ASSERT(funcs->send); -+ ok = funcs->send(chan, data, dataLen, &res, &resLen); -+ goto done; -+ } -+ -+ ok = FALSE; -+ goto exit; -+ } -+ -+done: -+ if (ok) { -+ Debug(LGPFX "Recved %"FMTSZ"u bytes\n", resLen); -+ } -+ -+ if (result != NULL) { -+ *result = res; -+ } -+ if (resultLen != NULL) { -+ *resultLen = resLen; -+ } -+ -+exit: -+ g_static_mutex_unlock(&chan->outLock); -+ return ok; -+} -+ -+ -+/** -+ * Open/close RpcChannel each time for sending a Rpc message, this is a wrapper -+ * for RpcChannel APIs. -+ * -+ * @param[in] data request data -+ * @param[in] dataLen data length -+ * @param[in] result reply, should be freed by calling RpcChannel_Free. -+ * @param[in] resultLen reply length -+ -+ * @returns TRUE on success. -+ */ -+ -+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; -+} -+ -+ -+/** -+ * Open/close RpcChannel each time for sending a Rpc message, this is a wrapper -+ * for RpcChannel APIs. -+ * -+ * @param[out] reply reply, should be freed by calling RpcChannel_Free. -+ * @param[out] repLen reply length -+ * @param[in] reqFmt request data -+ * @param[in] ... optional arguments depending on reqFmt. -+ -+ * @returns TRUE on success. -+ */ -+ -+gboolean -+RpcChannel_SendOne(char **reply, -+ size_t *repLen, -+ char const *reqFmt, -+ ...) -+{ -+ va_list args; -+ gboolean status; -+ char *request; -+ size_t reqLen = 0; -+ -+ status = FALSE; -+ -+ /* Format the request string */ -+ va_start(args, reqFmt); -+ request = Str_Vasprintf(&reqLen, reqFmt, args); -+ va_end(args); -+ -+ /* -+ * If Str_Vasprintf failed, write NULL into the reply if the caller wanted -+ * a reply back. -+ */ -+ if (request == NULL) { -+ goto error; -+ } -+ -+ /* -+ * If the command doesn't contain a space, add one to the end to maintain -+ * compatibility with old VMXs. -+ * -+ * For a long time, the GuestRpc logic in the VMX was wired to expect a -+ * trailing space in every command, even commands without arguments. That is -+ * no longer true, but we must continue to add a trailing space because we -+ * don't know whether we're talking to an old or new VMX. -+ */ -+ if (request[reqLen - 1] != ' ') { -+ char *tmp; -+ -+ tmp = Str_Asprintf(NULL, "%s ", request); -+ free(request); -+ request = tmp; -+ -+ /* -+ * If Str_Asprintf failed, write NULL into reply if the caller wanted -+ * a reply back. -+ */ -+ if (request == NULL) { -+ goto error; -+ } -+ } -+ -+ status = RpcChannel_SendOneRaw(request, reqLen, reply, repLen); -+ -+ free(request); -+ -+ return status; -+ -+error: -+ if (reply) { -+ *reply = NULL; -+ } -+ -+ if (repLen) { -+ *repLen = 0; -+ } -+ return FALSE; -+} -diff -Naur a/services/vmtoolsd/mainLoop.c b/services/vmtoolsd/mainLoop.c ---- a/services/vmtoolsd/mainLoop.c 2015-11-24 07:59:42.000000000 +0100 -+++ b/services/vmtoolsd/mainLoop.c 2016-01-15 11:52:19.332545573 +0100 -@@ -384,9 +384,7 @@ - GMainContext *gctx; - ToolsServiceProperty ctxProp = { TOOLS_CORE_PROP_CTX }; - -- if (!g_thread_supported()) { -- g_thread_init(NULL); -- } -+ g_thread_init(NULL); - - /* - * Useful for debugging purposes. Log the vesion and build information. -diff -Naur a/services/plugins/vmbackup/stateMachine.c b/services/plugins/vmbackup/stateMachine.c ---- a/services/plugins/vmbackup/stateMachine.c 2015-11-24 07:59:42.000000000 +0100 -+++ b/services/plugins/vmbackup/stateMachine.c 2016-01-15 11:58:56.387357439 +0100 -@@ -279,12 +279,12 @@ - g_source_unref(gBackupState->abortTimer); - } - -- g_static_mutex_lock(&gBackupState->opLock); -+ g_mutex_lock(&gBackupState->opLock); - if (gBackupState->currentOp != NULL) { - VmBackup_Cancel(gBackupState->currentOp); - VmBackup_Release(gBackupState->currentOp); - } -- g_static_mutex_unlock(&gBackupState->opLock); -+ g_mutex_unlock(&gBackupState->opLock); - - VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_DONE, VMBACKUP_SUCCESS, ""); - -@@ -299,7 +299,7 @@ - } - - gBackupState->provider->release(gBackupState->provider); -- g_static_mutex_free(&gBackupState->opLock); -+ g_mutex_free(&gBackupState->opLock); - g_free(gBackupState->scriptArg); - g_free(gBackupState->volumes); - g_free(gBackupState->snapshots); -@@ -418,13 +418,13 @@ - if (gBackupState->machineState != VMBACKUP_MSTATE_SCRIPT_ERROR && - gBackupState->machineState != VMBACKUP_MSTATE_SYNC_ERROR) { - /* Mark the current operation as cancelled. */ -- g_static_mutex_lock(&gBackupState->opLock); -+ g_mutex_lock(&gBackupState->opLock); - if (gBackupState->currentOp != NULL) { - VmBackup_Cancel(gBackupState->currentOp); - VmBackup_Release(gBackupState->currentOp); - gBackupState->currentOp = NULL; - } -- g_static_mutex_unlock(&gBackupState->opLock); -+ g_mutex_unlock(&gBackupState->opLock); - - VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_ABORT, - VMBACKUP_REMOTE_ABORT, -@@ -478,32 +478,32 @@ - g_source_unref(gBackupState->timerEvent); - gBackupState->timerEvent = NULL; - -- g_static_mutex_lock(&gBackupState->opLock); -+ g_mutex_lock(&gBackupState->opLock); - if (gBackupState->currentOp != NULL) { - g_debug("VmBackupAsyncCallback: checking %s\n", gBackupState->currentOpName); - status = VmBackup_QueryStatus(gBackupState->currentOp); - } -- g_static_mutex_unlock(&gBackupState->opLock); -+ g_mutex_unlock(&gBackupState->opLock); - - switch (status) { - case VMBACKUP_STATUS_PENDING: - goto exit; - - case VMBACKUP_STATUS_FINISHED: -- g_static_mutex_lock(&gBackupState->opLock); -+ g_mutex_lock(&gBackupState->opLock); - if (gBackupState->currentOpName != NULL) { - g_debug("Async request '%s' completed\n", gBackupState->currentOpName); - VmBackup_Release(gBackupState->currentOp); - gBackupState->currentOpName = NULL; - } - gBackupState->currentOp = NULL; -- g_static_mutex_unlock(&gBackupState->opLock); -+ g_mutex_unlock(&gBackupState->opLock); - break; - - default: - { - gchar *msg; -- g_static_mutex_lock(&gBackupState->opLock); -+ g_mutex_lock(&gBackupState->opLock); - if (gBackupState->errorMsg != NULL) { - msg = g_strdup_printf("'%s' operation failed: %s", - gBackupState->currentOpName, -@@ -519,7 +519,7 @@ - - VmBackup_Release(gBackupState->currentOp); - gBackupState->currentOp = NULL; -- g_static_mutex_unlock(&gBackupState->opLock); -+ g_mutex_unlock(&gBackupState->opLock); - VmBackupOnError(); - goto exit; - } -@@ -534,12 +534,12 @@ - gBackupState->callback = NULL; - - if (cb(gBackupState)) { -- g_static_mutex_lock(&gBackupState->opLock); -+ g_mutex_lock(&gBackupState->opLock); - if (gBackupState->currentOp != NULL || gBackupState->forceRequeue) { -- g_static_mutex_unlock(&gBackupState->opLock); -+ g_mutex_unlock(&gBackupState->opLock); - goto exit; - } -- g_static_mutex_unlock(&gBackupState->opLock); -+ g_mutex_unlock(&gBackupState->opLock); - } else { - VmBackupOnError(); - goto exit; -@@ -823,7 +823,7 @@ - gBackupState->freezeStatus = VMBACKUP_FREEZE_FINISHED; - gBackupState->provider = provider; - gBackupState->needsPriv = FALSE; -- g_static_mutex_init(&gBackupState->opLock); -+ g_mutex_init(&gBackupState->opLock); - gBackupState->enableNullDriver = VmBackupConfigGetBoolean(ctx->config, - "enableNullDriver", - TRUE); -diff -Naur a/services/plugins/vmbackup/vmBackupInt.h b/services/plugins/vmbackup/vmBackupInt.h ---- a/services/plugins/vmbackup/vmBackupInt.h 2015-11-24 07:59:42.000000000 +0100 -+++ b/services/plugins/vmbackup/vmBackupInt.h 2016-01-15 11:55:41.944020643 +0100 -@@ -98,7 +98,7 @@ - ToolsAppCtx *ctx; - VmBackupOp *currentOp; - const char *currentOpName; -- GStaticMutex opLock; // See note above -+ GMutex opLock; // See note above - char *volumes; - char *snapshots; - guint pollPeriod; -@@ -171,14 +171,14 @@ - ASSERT(state->currentOp == NULL); - ASSERT(currentOpName != NULL); - -- g_static_mutex_lock(&state->opLock); -+ g_mutex_lock(&state->opLock); - - state->currentOp = op; - state->callback = callback; - state->currentOpName = currentOpName; - state->forceRequeue = (callback != NULL && op == NULL); - -- g_static_mutex_unlock(&state->opLock); -+ g_mutex_unlock(&state->opLock); - - return (op != NULL); - } diff --git a/packages/sysutils/open-vm-tools/patches/open-vm-tools-0002_gcc6.patch b/packages/sysutils/open-vm-tools/patches/open-vm-tools-0002_gcc6.patch deleted file mode 100644 index 8a8098fdc5..0000000000 --- a/packages/sysutils/open-vm-tools/patches/open-vm-tools-0002_gcc6.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 08726e150faca5b67ff981680e556b908aa806d0 Mon Sep 17 00:00:00 2001 -From: Bernd Zeimetz -Date: Sat, 17 Sep 2016 11:15:12 +0200 -Subject: [PATCH] Make open-vm-tools build with gcc 6. - -diff --git a/lib/include/x86cpuid.h b/lib/include/x86cpuid.h ---- a/lib/include/x86cpuid.h -+++ b/lib/include/x86cpuid.h -@@ -909,7 +909,7 @@ FIELD(81E, 0, ECX, 8, 3, NODES_PER_PKG, NA, FALSE) - * Note: The MASK definitions must use some gymnastics to get - * around a warning when shifting left by 32. - */ --#define VMW_BIT_MASK(shift) (((1 << (shift - 1)) << 1) - 1) -+#define VMW_BIT_MASK(shift) (((1u << (shift - 1)) << 1) - 1) - - #define FIELD(lvl, ecxIn, reg, bitpos, size, name, s, c3) \ - CPUID_##name##_SHIFT = bitpos, \ -diff --git a/libDeployPkg/linuxDeployment.c b/libDeployPkg/linuxDeployment.c ---- a/libDeployPkg/linuxDeployment.c -+++ b/libDeployPkg/linuxDeployment.c -@@ -67,7 +67,6 @@ - * Constant definitions - */ - --static const char ENDOFLINEMARKER = '\n'; - static const char SPACECHAR = ' '; - static const char TABCHAR = '\t'; - static const char QUOTECHAR = '"'; -@@ -913,22 +912,28 @@ Deploy(const char* packageName) - deploymentResult = ForkExecAndWaitCommand(command); - free (command); - -- if (deploymentResult != 0) { -+ if (deploymentResult != CUST_SUCCESS) { - sLog(log_error, "Customization process returned with error. \n"); - sLog(log_debug, "Deployment result = %d \n", deploymentResult); - -- if (deploymentResult == CUST_NETWORK_ERROR || deploymentResult == CUST_NIC_ERROR) { -+ if (deploymentResult == CUST_NETWORK_ERROR || deploymentResult == CUST_NIC_ERROR || deploymentResult == CUST_DNS_ERROR) { - // Network specific error in the guest - sLog(log_info, "Setting network error status in vmx. \n"); - SetCustomizationStatusInVmx(TOOLSDEPLOYPKG_RUNNING, - GUESTCUST_EVENT_NETWORK_SETUP_FAILED, - NULL); -- } else { -+ } else if (deploymentResult == CUST_GENERIC_ERROR) { - // Generic error in the guest - sLog(log_info, "Setting generic error status in vmx. \n"); - SetCustomizationStatusInVmx(TOOLSDEPLOYPKG_RUNNING, - GUESTCUST_EVENT_CUSTOMIZE_FAILED, - NULL); -+ } else { -+ // Unknown error in the guest -+ sLog(log_info, "Setting unknown error status in vmx. \n"); -+ SetCustomizationStatusInVmx(TOOLSDEPLOYPKG_RUNNING, -+ GUESTCUST_EVENT_CUSTOMIZE_FAILED, -+ NULL); - } - - // Move to ERROR state