]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Linux DeployPkg should provide a configurable timeout for the spanning
authorOliver Kurth <okurth@vmware.com>
Tue, 19 Feb 2019 20:51:31 +0000 (12:51 -0800)
committerOliver Kurth <okurth@vmware.com>
Tue, 19 Feb 2019 20:51:31 +0000 (12:51 -0800)
customization process.  Right now it is hard-coded to 100 seconds.

Sources to provide "timeout" value:
1. Clients such as vCenter and SRM can pack timeout value in cab header
   via API func "DeployPkg_SetProcessTimeout(uint16 timeout)".  this timeout
   value will be implemented during the package deployment process.
2. Package deployment engines:
  - tools deployPkg plugin:
    Add "process-timeout" in tools.conf.  The tools deployPkg plugin will use
    that value to control the time period of the package deployment.
  - linuxDeployPkg:
    Add "-t <timeout>" as optional argument in linuxDeployPkg
    Usage: ./linuxDeployPkg -d <cabfile> -t <timeout> --skip-reboot
3. Default value in deployPkg is 100s.  If both the client and package
   deployment engines don't provid this value, then the default value of
   100s will be used.
4. The "timeout" value from clients will overwrite the value from the
   deployment engines when both of them provid this value.

open-vm-tools/lib/include/conf.h
open-vm-tools/lib/include/deployPkg/linuxDeployment.h
open-vm-tools/libDeployPkg/deployPkgFormat.h
open-vm-tools/libDeployPkg/linuxDeployment.c
open-vm-tools/services/plugins/deployPkg/deployPkg.c

index f9698c18991aa5cfd466d5823d9171ec43d793b7..6d33f40871a2871194d0d9354c887b43fe9e3c60 100644 (file)
  */
 
 
+/*
+ ******************************************************************************
+ * BEGIN deployPkg goodies.
+ */
+
+/**
+ * Defines the string used for the deployPkg config file group.
+ */
+#define CONFGROUPNAME_DEPLOYPKG "deployPkg"
+
+/**
+ * Lets users configure the process timeout value in deployPkg
+ * Valid value range: 0x01 ~ 0xFF
+ */
+#define CONFNAME_DEPLOYPKG_PROCESSTIMEOUT "process-timeout"
+
+/*
+ * END deployPkg goodies.
+ ******************************************************************************
+ */
+
+
 /** Where to find Tools data in the Win32 registry. */
 #define CONF_VMWARE_TOOLS_REGKEY    "Software\\VMware, Inc.\\VMware Tools"
 
index 3a999200fcd3afe58fffbb792f0f435823e23343..ea8b292c6dc51fc2dffe0cff0dac724ee227a600 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2009-2016,2018 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009-2019 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
@@ -30,6 +30,8 @@
 #include "imgcust-common/log.h"
 #include "imgcust-common/imgcust-api.h"
 
+#define DEPLOYPKG_PROCESSTIMEOUT_DEFAULT 100
+
 typedef enum {
    DEPLOYPKG_STATUS_SUCCESS,
    DEPLOYPKG_STATUS_CLOUD_INIT_DELEGATED,
@@ -37,6 +39,31 @@ typedef enum {
    DEPLOYPKG_STATUS_CAB_ERROR
 } DeployPkgStatus;
 
+/*
+ *------------------------------------------------------------------------------
+ *
+ * DeployPkg_SetTimeout --
+ *
+ *      Give the deploy package an application specific timeout value.
+ *      Package deployment engines such as tools-deployPkg-plugin or standalone program
+ * linuxDeployPkg can call this API to set gProcessTimeout.
+ *      This API should be called before DeployPkg_DeployPackageFromFile or
+ * DeployPkg_DeployPackageFromFileEx.
+ *      If the package header includs valid 'timeout' value, then that value will
+ * overwrite gProcessTimeout.
+ *      If no valid 'timeout' value from both package header and deployment engine, then
+ * default value 100s will be used.
+ *
+ * @param logger [in]
+ *      timeout value to be used for process execution period control
+ *
+ *------------------------------------------------------------------------------
+ */
+
+IMGCUST_API void
+DeployPkg_SetProcessTimeout(uint16 timeout);
+
+
 /*
  *------------------------------------------------------------------------------
  *
index d08a13ea1808d7b7ffafa89c92cc74d9256a56d5..595b652c0940e152d6654707ddcc4f8f2c1416d8 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2006-2017 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2019 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
@@ -103,11 +103,13 @@ typedef enum {
  *         +-------------------------+
  *         |      (seed+command)     |
  *         |         padding         |
- *         +-------------------------+      
+ *         +-------------------------+
  * </pre>
  */
 
-typedef struct
+typedef
+#include "vmware_pack_begin.h"
+struct
 {
    char signature[VMWAREDEPLOYPKG_SIGNATURE_LENGTH]; // Not null terminated.
    uint8 majorVersion;
@@ -115,34 +117,35 @@ typedef struct
    uint8 payloadType;
    uint8 reserved;
 
+   uint16 pkgProcessTimeout; // timeout value for process execution in deployPkg
+
    /*
     * Structs are aligned to word length. For 32 bit architecture it is 4 bytes
-    * aligned and for 64 bit it is 8 bytes aligned. To make sure 64 bit field
-    * "pkgLength" starts at the same place in both 32 and 64 bit architecture,
-    * we need to add a 4 byte padding. If the padding is not present, package
-    * created in 32 bit architecture will not be read correctly in 64 bit
-    * architecture and vice-versa.
-    *
-    * NOTE: Positioning and size of the pad will change if fields are
-    * added/removed.
+    * aligned and for 64 bit it is 8 bytes aligned. Need to make sure package
+    * created in 32 bit architecture can be read correctly in 64 bit architecture
+    * and vice-versa. So when adding or removing fields, a padding field maybe
+    * needed to enable the payload section to start at the same place in both 32
+    * and 64 bit architecture.
     */
-   uint32 archPadding;
+   uint16 archPadding;   // offset 22
 
-   uint64 pkgLength;     // Total length of package including header, offset 20.
-   uint64 payloadOffset; // Relative to beginning of header, offset 28.
-   uint64 payloadLength; // Length of payload, offset 36.
+   uint64 pkgLength;     // Total length of package including header, offset 24.
+   uint64 payloadOffset; // Relative to beginning of header, offset 32.
+   uint64 payloadLength; // Length of payload, offset 40.
 
    /*
-    * Command string and padding, null terminated, offset 44.
+    * Command string and padding, null terminated.
     * This padding makes the header sector-aligned, making it easier
     * to embed in disks and disk partitions.
     * This string may contain OS-specific env variables, e.g. %SYSTEMDRIVE%.
     */
 
-   char seed[VMWAREDEPLOYPKG_SEED_LENGTH];
-   char command[VMWAREDEPLOYPKG_CMD_LENGTH];
+   char seed[VMWAREDEPLOYPKG_SEED_LENGTH];   // offset 48
+   char command[VMWAREDEPLOYPKG_CMD_LENGTH]; // offset 56
 
-} VMwareDeployPkgHdr;
+}
+#include "vmware_pack_end.h"
+VMwareDeployPkgHdr;
 
 #ifdef _WIN32
 #include "poppack.h"
index c38ed3d400413f53ab3000bb79643adaf5c9b46c..223dddf3f5673070646fce1365a6f96c43522efd 100644 (file)
@@ -155,6 +155,40 @@ static void NoLogging(int level, const char* fmtstr, ...);
 
 static char* gDeployError = NULL;
 LogFunction sLog = NoLogging;
+static uint16 gProcessTimeout = DEPLOYPKG_PROCESSTIMEOUT_DEFAULT;
+
+// .....................................................................................
+
+/*
+ *------------------------------------------------------------------------------
+ *
+ * DeployPkg_SetTimeout --
+ *
+ *      Give the deploy package an application specific timeout value.
+ *      Package deployment engines such as tools-deployPkg-plugin or standalone program
+ * linuxDeployPkg can call this API to set gProcessTimeout.
+ *      This API should be called before DeployPkg_DeployPackageFromFile or
+ * DeployPkg_DeployPackageFromFileEx.
+ *      If the package header includs valid 'timeout' value, then that value will
+ * overwrite gProcessTimeout.
+ *      If no valid 'timeout' value from both package header and deployment engine, then
+ * default value 100s will be used.
+ *
+ * @param logger [in]
+ *      timeout value to be used for process execution period control
+ *
+ *------------------------------------------------------------------------------
+ */
+
+void
+DeployPkg_SetProcessTimeout(uint16 timeout)
+{
+   if (timeout > 0) {
+      gProcessTimeout = timeout;
+      sLog(log_debug, "Process timeout value from deployment launcher: %u\n",
+           gProcessTimeout);
+   }
+}
 
 // .....................................................................................
 
@@ -610,6 +644,15 @@ GetPackageInfo(const char* packageName,
 
    //TODO hdr->command[VMWAREDEPLOYPKG_CMD_LENGTH - 1] = '\0';
 
+   // Get process timeout value from client
+   if (hdr.pkgProcessTimeout > 0 && hdr.pkgProcessTimeout <= MAX_UINT16) {
+      gProcessTimeout = hdr.pkgProcessTimeout;
+      sLog(log_info, "Process timeout value in header: %u\n",
+             hdr.pkgProcessTimeout);
+   } else {
+      sLog(log_info, "No valid timeout value from package header");
+   }
+
    return TRUE;
 }
 
@@ -1424,7 +1467,7 @@ ExtractZipPackage(const char* pkgName,
    args[5] = NULL;
    Process_Create(&h, args, sLog);
    free(destCopy);
-   Process_RunToComplete(h, 100);
+   Process_RunToComplete(h, gProcessTimeout);
 
    sLog(log_info, "unzip output: %s\n", Process_GetStdout(h));
 
@@ -1558,7 +1601,7 @@ ForkExecAndWaitCommand(const char* command, bool ignoreStdErr)
    }
    free(args);
 
-   Process_RunToComplete(hp, 100);
+   Process_RunToComplete(hp, gProcessTimeout);
    sLog(log_info, "Customization command output: %s\n", Process_GetStdout(hp));
    retval = Process_GetExitCode(hp);
 
index 06719ec9c5b11387af1a001c8578694978b36be3..713222cf36d7d0ff0131c347d1b7a1030a7866ad 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2006-2018 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2019 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
@@ -35,6 +35,7 @@
 #include "str.h"
 #include "util.h"
 #include "unicodeBase.h"
+#include "conf.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -72,12 +73,16 @@ static char *DeployPkgGetTempDir(void);
  */
 
 static ToolsDeployPkgError
-DeployPkgDeployPkgInGuest(const char* pkgFile, // IN: the package filename
+DeployPkgDeployPkgInGuest(ToolsAppCtx *ctx,    // IN: app context
+                          const char* pkgFile, // IN: the package filename
                           char* errBuf,        // OUT: buffer for msg on fail
                           int errBufSize)      // IN: size of errBuf
 {
    char *tempFileName = NULL;
    ToolsDeployPkgError ret = TOOLSDEPLOYPKG_ERROR_SUCCESS;
+#ifndef _WIN32
+   int processTimeout;
+#endif
 
    /* Init the logger */
    DeployPkgLog_Open();
@@ -102,6 +107,30 @@ DeployPkgDeployPkgInGuest(const char* pkgFile, // IN: the package filename
       goto ExitPoint;
    }
    pkgFile = tempFileName;
+#else
+   /*
+    * Get processTimeout from tools.conf.
+    * Only when we get valid 'timeout' value from tools.conf, we will call
+    * DeployPkg_SetProcessTimeout to over-write the processTimeout in deployPkg
+    *
+    */
+   processTimeout =
+        VMTools_ConfigGetInteger(ctx->config,
+                                 CONFGROUPNAME_DEPLOYPKG,
+                                 CONFNAME_DEPLOYPKG_PROCESSTIMEOUT,
+                                 0);
+   if (processTimeout > 0 && processTimeout <= MAX_UINT16) {
+      DeployPkgLog_Log(log_debug, "%s.%s in tools.conf: %d\n",
+                       CONFGROUPNAME_DEPLOYPKG,
+                       CONFNAME_DEPLOYPKG_PROCESSTIMEOUT,
+                       processTimeout);
+      DeployPkg_SetProcessTimeout(processTimeout);
+   } else {
+      DeployPkgLog_Log(log_debug, "No valid value from tools.conf %s.%s",
+                       CONFGROUPNAME_DEPLOYPKG,
+                       CONFNAME_DEPLOYPKG_PROCESSTIMEOUT);
+      DeployPkgLog_Log(log_info, "The valid timeout value range: 1 ~ 65535\n");
+   }
 #endif
 
    if (0 != DeployPkg_DeployPackageFromFile(pkgFile)) {
@@ -182,7 +211,7 @@ DeployPkgExecDeploy(ToolsAppCtx *ctx,   // IN: app context
    g_debug("%s: Deploypkg deploy task started.\n", __FUNCTION__);
 
    /* Unpack the package and run the command. */
-   ret = DeployPkgDeployPkgInGuest(pkgNameStr, errMsg, sizeof errMsg);
+   ret = DeployPkgDeployPkgInGuest(ctx, pkgNameStr, errMsg, sizeof errMsg);
    if (ret != TOOLSDEPLOYPKG_ERROR_SUCCESS) {
       msg = g_strdup_printf("deployPkg.update.state %d %d %s",
                             TOOLSDEPLOYPKG_DEPLOYING,