From: Oliver Kurth Date: Fri, 15 Sep 2017 18:23:39 +0000 (-0700) Subject: Spawn a new thread to handle deployPkg.deploy RPC X-Git-Tag: stable-10.2.0~210 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4a9834cedf0bc1c0303e2b078db87f8754c99564;p=thirdparty%2Fopen-vm-tools.git Spawn a new thread to handle deployPkg.deploy RPC Deploypkg takes some time to complete, so separating it to a new thread helps guarantee that the main tools thread can still respond to VMX ping/heartbeat messages. Before this change, the state changes on the vmx side are: ToolsDeployPkg_Begin ToolsDeployPkg begin finished ToolsDeployPkg finished copy deployPkg.deploy deployPkg.update.state 3 -- TOOLSDEPLOYPKG_DEPLOYING deployPkg.update.state 4 0 -- TOOLSDEPLOYPKG_RUNNING deployPkg.update.state 4 103 -- TOOLSDEPLOYPKG_RUNNING GUESTCUST_EVENT_ENABLE_NICS deployPkg.update.state 4 104 -- TOOLSDEPLOYPKG_RUNNING GUESTCUST_EVENT_QUERY_NICS ToolsDeployPkg finished deploy ToolsDeployPkg_Begin ToolsDeployPkg deploy state: 4 deployPkg.update.state 5 0 -- TOOLSDEPLOYPKG_DONE After this change, the state changes are: ToolsDeployPkg_Begin ToolsDeployPkg begin finished ToolsDeployPkg finished copy deployPkg.deploy deployPkg.update.state 3 ToolsDeployPkg finished deploy deployPkg.update.state 4 0 deployPkg.update.state 4 103 deployPkg.update.state 4 104 ToolsDeployPkg_Begin ToolsDeployPkg deploy state: 4 deployPkg.update.state 5 0 There are no specific changes on vmx side. --- diff --git a/open-vm-tools/services/plugins/deployPkg/Makefile.am b/open-vm-tools/services/plugins/deployPkg/Makefile.am index 6f6873cde..781f47df8 100644 --- a/open-vm-tools/services/plugins/deployPkg/Makefile.am +++ b/open-vm-tools/services/plugins/deployPkg/Makefile.am @@ -28,6 +28,7 @@ libdeployPkgPlugin_la_LDFLAGS += @PLUGIN_LDFLAGS@ libdeployPkgPlugin_la_LIBADD = libdeployPkgPlugin_la_LIBADD += @VMTOOLS_LIBS@ +libdeployPkgPlugin_la_LIBADD += @GOBJECT_LIBS@ libdeployPkgPlugin_la_LIBADD += $(top_builddir)/libDeployPkg/libDeployPkg.la libdeployPkgPlugin_la_SOURCES = diff --git a/open-vm-tools/services/plugins/deployPkg/deployPkg.c b/open-vm-tools/services/plugins/deployPkg/deployPkg.c index f5479400f..df18663c8 100644 --- a/open-vm-tools/services/plugins/deployPkg/deployPkg.c +++ b/open-vm-tools/services/plugins/deployPkg/deployPkg.c @@ -41,6 +41,7 @@ extern "C" { #endif #include "vmware/tools/plugin.h" + #include "vmware/tools/threadPool.h" #ifdef __cplusplus } #endif @@ -149,16 +150,77 @@ DeployPkg_TcloBegin(RpcInData *data) // IN } +/* + * --------------------------------------------------------------------------- + * DeployPkgExecDeploy -- + * + * Start the deploy execution in a new thread. + * + * Return Value: + * None. + * + * Side effects: + * None. + * + * --------------------------------------------------------------------------- + */ + +void +DeployPkgExecDeploy(ToolsAppCtx *ctx, // IN: app context + void *pkgName) // IN: pkg file name +{ + char errMsg[2048]; + ToolsDeployPkgError ret; + gchar *msg; + char *pkgNameStr = (char *) pkgName; + + g_debug("%s: Deploypkg deploy task started.\n", __FUNCTION__); + + /* Unpack the package and run the command. */ + ret = DeployPkgDeployPkgInGuest(pkgNameStr, errMsg, sizeof errMsg); + if (ret != TOOLSDEPLOYPKG_ERROR_SUCCESS) { + msg = g_strdup_printf("deployPkg.update.state %d %d %s", + TOOLSDEPLOYPKG_DEPLOYING, + TOOLSDEPLOYPKG_ERROR_DEPLOY_FAILED, + errMsg); + if (!RpcChannel_Send(ctx->rpc, msg, strlen(msg), NULL, NULL)) { + g_warning("%s: failed to send error code %d for state TOOLSDEPLOYPKG_DEPLOYING\n", + __FUNCTION__, + TOOLSDEPLOYPKG_ERROR_DEPLOY_FAILED); + } + g_free(msg); + g_warning("DeployPkgInGuest failed, error = %d\n", ret); + } + + /* Attempt to delete the package file and tempdir. */ + Log("Deleting file %s\n", pkgNameStr); + if (File_Unlink(pkgNameStr) == 0) { + char *vol, *dir, *path; + File_SplitName(pkgNameStr, &vol, &dir, NULL); + path = Str_Asprintf(NULL, "%s%s", vol, dir); + if (path != NULL) { + Log("Deleting directory %s\n", path); + File_DeleteEmptyDirectory(path); + free(path); + } + free(vol); + free(dir); + } else { + g_warning("Unable to delete the file: %s\n", pkgNameStr); + } +} + + /* *----------------------------------------------------------------------------- * - * DeployPkgTcloDeploy -- + * DeployPkg_TcloDeploy -- * * TCLO handler for "deployPkg.deploy". Start image guest package deployment. * * Return value: * TRUE if success - * FALSE if anything failed + * FALSE if pkg file path is not valid * * Side effects: * None @@ -169,9 +231,7 @@ DeployPkg_TcloBegin(RpcInData *data) // IN gboolean DeployPkg_TcloDeploy(RpcInData *data) // IN { - char errMsg[2048]; - ToolsDeployPkgError ret; - char *argCopy, *pkgStart, *pkgEnd; + char *argCopy, *pkgStart, *pkgEnd, *pkgName; const char *white = " \t\r\n"; /* Set state to DEPLOYING. */ @@ -181,7 +241,7 @@ DeployPkg_TcloDeploy(RpcInData *data) // IN msg = g_strdup_printf("deployPkg.update.state %d", TOOLSDEPLOYPKG_DEPLOYING); if (!RpcChannel_Send(ctx->rpc, msg, strlen(msg), NULL, NULL)) { - g_warning("%s: failed update state to TOOLSDEPLOYPKG_DEPLOYING\n", + g_warning("%s: failed to update state to TOOLSDEPLOYPKG_DEPLOYING\n", __FUNCTION__); } g_free(msg); @@ -205,44 +265,31 @@ DeployPkg_TcloDeploy(RpcInData *data) // IN TOOLSDEPLOYPKG_ERROR_DEPLOY_FAILED, pkgStart); if (!RpcChannel_Send(ctx->rpc, msg, strlen(msg), NULL, NULL)) { - g_warning("%s: failed update state to TOOLSDEPLOYPKG_DEPLOYING\n", - __FUNCTION__); + g_warning("%s: failed to send error code %d for state TOOLSDEPLOYPKG_DEPLOYING\n", + __FUNCTION__, + TOOLSDEPLOYPKG_ERROR_DEPLOY_FAILED); } g_free(msg); g_warning("Package file '%s' doesn't exist!!\n", pkgStart); - goto ExitPoint; + + free(argCopy); + return RPCIN_SETRETVALS(data, "failed to get package file", FALSE); } - /* Unpack the package and run the command. */ - ret = DeployPkgDeployPkgInGuest(pkgStart, errMsg, sizeof errMsg); - if (ret != TOOLSDEPLOYPKG_ERROR_SUCCESS) { + pkgName = Util_SafeStrdup(pkgStart); + if (!ToolsCorePool_SubmitTask(ctx, DeployPkgExecDeploy, pkgName, free)) { + g_warning("%s: failed to start deploy execution thread\n", + __FUNCTION__); msg = g_strdup_printf("deployPkg.update.state %d %d %s", TOOLSDEPLOYPKG_DEPLOYING, TOOLSDEPLOYPKG_ERROR_DEPLOY_FAILED, - errMsg); + "failed to spawn deploy execution thread"); if (!RpcChannel_Send(ctx->rpc, msg, strlen(msg), NULL, NULL)) { - g_warning("%s: failed update state to TOOLSDEPLOYPKG_DEPLOYING\n", - __FUNCTION__); + g_warning("%s: failed to send error code %d for state TOOLSDEPLOYPKG_DEPLOYING\n", + __FUNCTION__, + TOOLSDEPLOYPKG_ERROR_DEPLOY_FAILED); } g_free(msg); - g_warning("DeployPkgInGuest failed, error = %d\n", ret); - } - - ExitPoint: - - /* Attempt to delete the package file and tempdir. */ - Log("Deleting file %s\n", pkgStart); - if (File_Unlink(pkgStart) == 0) { - char *vol, *dir, *path; - File_SplitName(pkgStart, &vol, &dir, NULL); - path = Str_Asprintf(NULL, "%s%s", vol, dir); - if (path != NULL) { - Log("Deleting directory %s\n", path); - File_DeleteEmptyDirectory(path); - free(path); - } - free(vol); - free(dir); } free(argCopy);