瀏覽代碼

Fix gh-1573 slave PID file is compenentname_slave_slavenum

To identify multiple slave processes in one node, the PID file
name has been changed to compenentname_slave_slavenum.pid.

Signed-off-by: Kevin Wang <kevin.wang@lexisnexis.com>
Kevin Wang 13 年之前
父節點
當前提交
1f776fa3f3

+ 2 - 2
esp/eclwatch/ws_XSLT/machines.xslt

@@ -310,12 +310,12 @@
                 <xsl:if test="$ShowPreflightInfo">
                     <xsl:choose>
                         <xsl:when test="not($SwapNode)">
-                            <input type="checkbox" name="Addresses_i{position()}" value="{Netaddress}|{ConfigNetaddress}:{Type}:{$clusterName}:{OS}:{translate(Directory, ':', '$')}" onclick="return clicked(this, event)">
+                            <input type="checkbox" name="Addresses_i{position()}" value="{Netaddress}|{ConfigNetaddress}:{Type}:{$clusterName}:{OS}:{translate(Directory, ':', '$')}:{ProcessNumber}" onclick="return clicked(this, event)">
                                 <xsl:attribute name="checked">true</xsl:attribute>
                             </input>
                         </xsl:when>
                         <xsl:otherwise>
-                            <input type="checkbox" name="Addresses_i{position()}" value="{Netaddress}:{Type}:{$clusterName}:{OS}:{translate(Directory, ':', '$')}" onclick="return clicked(this, event)"/>
+                            <input type="checkbox" name="Addresses_i{position()}" value="{Netaddress}:{Type}:{$clusterName}:{OS}:{translate(Directory, ':', '$')}:{ProcessNumber}" onclick="return clicked(this, event)"/>
                         </xsl:otherwise>
                     </xsl:choose>
                 </xsl:if>

+ 2 - 1
esp/scm/ws_machine.ecm

@@ -129,6 +129,7 @@ ESPstruct MachineInfoEx
    string ComponentName;
    string ComponentPath;
    int    OS;
+   [min_ver("1.10")] int    ProcessNumber;
    ESParray<ESPstruct ProcessorInfo> Processors;
    ESParray<ESPstruct StorageInfo> Storage;
    ESParray<ESPstruct SWRunInfo> Running;
@@ -301,7 +302,7 @@ ESPresponse [encode(0), exceptions_inline] GetTargetClusterInfoResponse
     string TimeStamp;
 };
 //-------- service ---------
-ESPservice [version("1.09"), default_client_version("1.09")] ws_machine
+ESPservice [version("1.10"), default_client_version("1.10")] ws_machine
 {
     ESPuses ESPstruct RequestInfoStruct;
     ESPuses ESPstruct MachineInfoEx;

+ 2 - 1
esp/scm/ws_topology.ecm

@@ -31,6 +31,7 @@ ESPStruct TpMachine
     int    OS;
     string Path;
     int    Port;
+    [min_ver("1.18")] int    ProcessNumber;
 };
 //  ===========================================================================
 ESPStruct TpCluster
@@ -543,7 +544,7 @@ ESPresponse [exceptions_inline,encode(0)] TpThorStatusResponse
     int AutoRefresh;
 };
 
-ESPservice [noforms, version("1.17"), default_client_version("1.17"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsTopology
+ESPservice [noforms, version("1.18"), default_client_version("1.18"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsTopology
 {
     ESPuses ESPStruct TpBinding;
     ESPuses ESPstruct TpCluster;

+ 1 - 1
esp/services/ws_machine/machines.xslt

@@ -391,7 +391,7 @@
                <input type="checkbox" name="Addresses_i{position()}" value="{Address}|{ConfigAddress}:EclAgentProcess:eclagent:{OS}:{translate(ComponentPath, ':', '$')}" onclick="return clicked(this, event)" checked="true"/>
             </xsl:when>
             <xsl:otherwise>
-              <input type="checkbox" name="Addresses_i{position()}" value="{Address}|{ConfigAddress}:{ProcessType}:{ComponentName}:{OS}:{translate(ComponentPath, ':', '$')}" onclick="return clicked(this, event)" checked="true"/>
+              <input type="checkbox" name="Addresses_i{position()}" value="{Address}|{ConfigAddress}:{ProcessType}:{ComponentName}:{OS}:{translate(ComponentPath, ':', '$')}:{ProcessNumber}" onclick="return clicked(this, event)" checked="true"/>
             </xsl:otherwise>
            </xsl:choose>
          </td>

+ 102 - 106
esp/services/ws_machine/ws_machineService.cpp

@@ -91,29 +91,30 @@ class CMachineInfoThreadParam : public CWsMachineThreadParam
 public:
    IMPLEMENT_IINTERFACE;
 
-   IEspContext& m_context;
-   StringBuffer m_sProcessType;
+    IEspContext& m_context;
+    StringBuffer m_sProcessType;
     StringBuffer m_sCompName;
     StringBuffer m_sConfigAddress;
-   StringBuffer m_sUserId;
-   StringBuffer m_sPassword;
+    StringBuffer m_sUserId;
+    StringBuffer m_sPassword;
     StringBuffer m_sPath;
+    unsigned     m_processNumber;
     bool             m_bECLAgent;
-   bool         m_bGetProcessorInfo;
-   bool         m_bGetStorageInfo;
-   bool         m_bGetSwInfo;
-   bool         m_bFilterProcesses;
-   bool         m_bMonitorDaliFileServer;
+    bool         m_bGetProcessorInfo;
+    bool         m_bGetStorageInfo;
+    bool         m_bGetSwInfo;
+    bool         m_bFilterProcesses;
+    bool         m_bMonitorDaliFileServer;
     bool             m_bMultipleInstances;
-   Cws_machineEx::OpSysType   m_operatingSystem;
-   Linked<IEspMachineInfoEx>    m_pMachineInfo;
-   Linked<IEspMachineInfoEx>    m_pMachineInfo1;
-   set<string>& m_columnSet;
-   StringArray& m_columnArray;
-   const StringArray& m_additionalProcesses;
+    Cws_machineEx::OpSysType   m_operatingSystem;
+    Linked<IEspMachineInfoEx>    m_pMachineInfo;
+    Linked<IEspMachineInfoEx>    m_pMachineInfo1;
+    set<string>& m_columnSet;
+    StringArray& m_columnArray;
+    const StringArray& m_additionalProcesses;
 
     CMachineInfoThreadParam( const char* pszAddress, const char* pszProcessType, const char* pszCompName, const char* pszUserId,
-                            const char* pszPassword, const char* pszPath, set<string>& columnSet, StringArray& columnArray,
+                            const char* pszPassword, const char* pszPath, unsigned processNumber, set<string>& columnSet, StringArray& columnArray,
                             bool bGetProcessorInfo, bool bGetStorageInfo, bool bGetSwInfo, bool bFilterProcesses,
                             bool bMonitorDaliFileServer, Cws_machineEx::OpSysType os, const StringArray& additionalProcesses,
                             IEspMachineInfoEx* pMachineInfo,  Cws_machineEx* pService, IEspContext& context, const char* pszConfigAddress)
@@ -123,25 +124,26 @@ public:
          m_operatingSystem(os),
          m_context(context),
          m_additionalProcesses(additionalProcesses)
-   {
+    {
         m_bECLAgent        = false;
-      m_sUserId          = pszUserId;
-      m_sPassword        = pszPassword;
+        m_sUserId          = pszUserId;
+        m_sPassword        = pszPassword;
         m_sPath              = pszPath;
-      m_bFilterProcesses = bFilterProcesses;
-      m_bMonitorDaliFileServer = bMonitorDaliFileServer;
-      m_sProcessType     = pszProcessType;
+        m_bFilterProcesses = bFilterProcesses;
+        m_bMonitorDaliFileServer = bMonitorDaliFileServer;
+        m_sProcessType     = pszProcessType;
         m_sCompName          = pszCompName;
         m_sConfigAddress     = pszConfigAddress,
-      m_bGetProcessorInfo= bGetProcessorInfo;
-      m_bGetStorageInfo  = bGetStorageInfo;
-      m_bGetSwInfo       = bGetSwInfo;
-      m_pMachineInfo.set( pMachineInfo );
+        m_bGetProcessorInfo= bGetProcessorInfo;
+        m_bGetStorageInfo  = bGetStorageInfo;
+        m_bGetSwInfo       = bGetSwInfo;
+        m_pMachineInfo.set( pMachineInfo );
         m_bMultipleInstances = false;
+        m_processNumber = processNumber;
     }
 
     CMachineInfoThreadParam( const char* pszAddress, const char* pszProcessType, const char* pszCompName, const char* pszUserId,
-                            const char* pszPassword, const char* pszPath, set<string>& columnSet, StringArray& columnArray,
+                            const char* pszPassword, const char* pszPath, unsigned processNumber, set<string>& columnSet, StringArray& columnArray,
                             bool bGetProcessorInfo, bool bGetStorageInfo, bool bGetSwInfo, bool bFilterProcesses,
                             bool bMonitorDaliFileServer, Cws_machineEx::OpSysType os, const StringArray& additionalProcesses,
                             IEspMachineInfoEx* pMachineInfo,  IEspMachineInfoEx* pMachineInfo1,  Cws_machineEx* pService, IEspContext& context, const char* pszConfigAddress)
@@ -152,51 +154,24 @@ public:
          m_context(context),
          m_additionalProcesses(additionalProcesses)
    {
-      m_sUserId          = pszUserId;
-      m_sPassword        = pszPassword;
+        m_sUserId          = pszUserId;
+        m_sPassword        = pszPassword;
         m_sPath              = pszPath;
-      m_bFilterProcesses = bFilterProcesses;
-      m_bMonitorDaliFileServer = bMonitorDaliFileServer;
-      m_sProcessType     = pszProcessType;
+        m_bFilterProcesses = bFilterProcesses;
+        m_bMonitorDaliFileServer = bMonitorDaliFileServer;
+        m_sProcessType     = pszProcessType;
         m_sCompName          = pszCompName;
         m_sConfigAddress     = pszConfigAddress,
-      m_bGetProcessorInfo= bGetProcessorInfo;
-      m_bGetStorageInfo  = bGetStorageInfo;
-      m_bGetSwInfo       = bGetSwInfo;
-      m_pMachineInfo.set( pMachineInfo );
-      m_pMachineInfo1.set( pMachineInfo1 );
+        m_bGetProcessorInfo= bGetProcessorInfo;
+        m_bGetStorageInfo  = bGetStorageInfo;
+        m_bGetSwInfo       = bGetSwInfo;
+        m_pMachineInfo.set( pMachineInfo );
+        m_pMachineInfo1.set( pMachineInfo1 );
         m_bECLAgent        = true;
         m_bMultipleInstances = false;
+        m_processNumber = processNumber;
     }
 
-    CMachineInfoThreadParam( const char* pszAddress, const char* pszProcessType,
-                                     const char* pszCompName, const char* pszSecString, const char* pszUserId,
-                            const char* pszPassword, const char* pszPath, set<string>& columnSet, StringArray& columnArray,
-                            bool bGetProcessorInfo, bool bGetStorageInfo, bool bGetSwInfo, bool bFilterProcesses,
-                            bool bMonitorDaliFileServer, Cws_machineEx::OpSysType os, const StringArray& additionalProcesses,
-                            IEspMachineInfoEx* pMachineInfo,  Cws_machineEx* pService, IEspContext& context)
-       : CWsMachineThreadParam(pszAddress, pszSecString, pService),
-         m_columnSet(columnSet),
-         m_columnArray(columnArray),
-         m_operatingSystem(os),
-         m_context(context),
-         m_additionalProcesses(additionalProcesses)
-   {
-      m_sUserId          = pszUserId;
-      m_sPassword        = pszPassword;
-        m_sPath              = pszPath;
-      m_bFilterProcesses = bFilterProcesses;
-      m_bMonitorDaliFileServer = bMonitorDaliFileServer;
-      m_sProcessType     = pszProcessType;
-        m_sCompName          = pszCompName;
-      m_bGetProcessorInfo= bGetProcessorInfo;
-      m_bGetStorageInfo  = bGetStorageInfo;
-      m_bGetSwInfo       = bGetSwInfo;
-      m_pMachineInfo.set( pMachineInfo );
-        m_bMultipleInstances = false;
-        m_bECLAgent        = false;
-   }
-
    virtual void doWork()
    {
       m_pService->doGetMachineInfo(m_context, this);
@@ -605,6 +580,7 @@ void Cws_machineEx::RunMachineQuery(IEspContext &context, StringArray &addresses
         StringBuffer sCompName;
         OpSysType    os = OS_Windows;
         StringBuffer sPath;
+        unsigned processNumber = 0;
 
         const char *configAddress = (*iAddr).second.c_str();
         char* props = (char*) strchr(configAddress, ':');
@@ -614,7 +590,7 @@ void Cws_machineEx::RunMachineQuery(IEspContext &context, StringArray &addresses
             props = (char*) configAddress;
 
         if (props)
-            parseProperties( props, sProcessType, sCompName, os, sPath);
+            parseProperties( props, sProcessType, sCompName, os, sPath, processNumber);
         else
             bFilterProcesses = false;
 
@@ -629,7 +605,7 @@ void Cws_machineEx::RunMachineQuery(IEspContext &context, StringArray &addresses
                machineArray.append(*pMachineInfo.getLink());
 
                 CMachineInfoThreadParam* pThreadReq =
-                    new CMachineInfoThreadParam( address.str(), sProcessType.str(), sCompName.str(), reqInfo.getUserName(), reqInfo.getPassword(), sPath.str(),
+                    new CMachineInfoThreadParam( address.str(), sProcessType.str(), sCompName.str(), reqInfo.getUserName(), reqInfo.getPassword(), sPath.str(), processNumber,
                                                           columnSet, columnArray, reqInfo.getGetProcessorInfo(), reqInfo.getGetStorageInfo(), reqInfo.getGetSoftwareInfo(),
                                                           bFilterProcesses, bMonitorDaliFileServer, os, additionalProcesses, pMachineInfo, this, context, configAddress);
 
@@ -643,7 +619,7 @@ void Cws_machineEx::RunMachineQuery(IEspContext &context, StringArray &addresses
                 machineArray.append(*pMachineInfo1.getLink());
 
                 CMachineInfoThreadParam* pThreadReq =
-                    new CMachineInfoThreadParam( address.str(), sProcessType.str(), sCompName.str(), reqInfo.getUserName(), reqInfo.getPassword(), sPath.str(),
+                    new CMachineInfoThreadParam( address.str(), sProcessType.str(), sCompName.str(), reqInfo.getUserName(), reqInfo.getPassword(), sPath.str(), processNumber,
                                          columnSet, columnArray, reqInfo.getGetProcessorInfo(), reqInfo.getGetStorageInfo(), reqInfo.getGetSoftwareInfo(),
                                          bFilterProcesses, bMonitorDaliFileServer, os, additionalProcesses, pMachineInfo, pMachineInfo1, this, context, configAddress);
 
@@ -1119,7 +1095,12 @@ void Cws_machineEx::doGetMachineInfo(IEspContext& context, CMachineInfoThreadPar
         if (!stricmp(pParam->m_sProcessType.str(), "ThorMasterProcess"))
             preFlightCommand.append("_master");
         else if (!stricmp(pParam->m_sProcessType.str(), "ThorSlaveProcess"))
-            preFlightCommand.append("_slave");
+        {
+            preFlightCommand.appendf("_slave_%d", pParam->m_processNumber);
+            double version = context.getClientVersion();
+            if (version > 1.09)
+                info->setProcessNumber(pParam->m_processNumber);
+        }
 
         StringBuffer sResponse;
         iRet = remoteGetMachineInfo(context, pParam->m_sAddress.str(), pParam->m_sConfigAddress.str(), preFlightCommand.str(), pParam->m_sUserName.str(), pParam->m_sPassword.str(), sResponse, machineInfo);
@@ -1965,7 +1946,7 @@ void Cws_machineEx::doGetSWRunInfo(IEspContext& context, CMachineInfoThreadParam
 //this method parses address info of the form "192.168.1.4-6:ThorSlaveProcess:thor1:2:path1"
 //into respective components
 void Cws_machineEx::parseProperties(const char* info, StringBuffer& processType, StringBuffer& sCompName,
-                                                OpSysType& os, StringBuffer& path)
+                                                OpSysType& os, StringBuffer& path, unsigned& processNumber)
 {
     StringArray sArray;
     DelimToStringArray(info, sArray, ":");
@@ -1979,47 +1960,53 @@ void Cws_machineEx::parseProperties(const char* info, StringBuffer& processType,
     path.clear();
     os  = OS_Windows;
 
-    if (ordinality > 1)
-    {
-        sCompName.append( sArray.item(1) );
-        if (ordinality > 2)
-        {
-            os  = (OpSysType) atoi( sArray.item(2) );
-            if (ordinality > 3)
-            {
-                path.append( sArray.item(3) );
-                if (path.length())
-                {
-                    char pat1, pat2;
-                    char rep1, rep2;
+    if (ordinality < 2)
+        return;
 
-                    if (os == OS_Linux)
-                    {
-                        pat1 = ':'; rep1 = '$';
-                        pat2 = '\\';rep2 = '/';
-                    }
-                    else
-                    {
-                        pat1 = '$'; rep1 = ':';
-                        pat2 = '/';rep2 = '\\';
-                    }
+    sCompName.append( sArray.item(1) );
+    if (ordinality < 3)
+        return;
 
-                    path.replace( pat1, rep1 );
-                    path.replace( pat2, rep2 );
+    os  = (OpSysType) atoi( sArray.item(2) );
+    if (ordinality < 4)
+        return;
 
-                    const char* pszPath = path.str();
-                    if (os == OS_Linux && *pszPath != '/')
-                    {
-                        path.insert(0, '/');
-                        pszPath = path.str();
-                    }
+    path.append( sArray.item(3) );
+    if (path.length())
+    {
+        char pat1, pat2;
+        char rep1, rep2;
 
-                    if (*(pszPath + path.length()-1) != rep2)
-                        path.append(rep2);
-                }
-            }
+        if (os == OS_Linux)
+        {
+            pat1 = ':'; rep1 = '$';
+            pat2 = '\\';rep2 = '/';
+        }
+        else
+        {
+            pat1 = '$'; rep1 = ':';
+            pat2 = '/';rep2 = '\\';
         }
+
+        path.replace( pat1, rep1 );
+        path.replace( pat2, rep2 );
+
+        const char* pszPath = path.str();
+        if (os == OS_Linux && *pszPath != '/')
+        {
+            path.insert(0, '/');
+            pszPath = path.str();
+        }
+
+        if (*(pszPath + path.length()-1) != rep2)
+            path.append(rep2);
     }
+
+    if (ordinality < 5)
+        return;
+
+    processNumber  = atoi( sArray.item(4) );
+    return;
 }
 
 void Cws_machineEx::getTimeStamp(char* timeStamp)
@@ -2173,6 +2160,7 @@ void Cws_machineEx::getThorMachineList(IConstEnvironment* constEnv, IPropertyTre
     if (!nodeGroup || (nodeGroup->ordinality() == 0))
         return;
 
+    StringArray netAddresses;
     Owned<INodeIterator> gi = nodeGroup->getIterator();
     ForEach(*gi)
     {
@@ -2202,12 +2190,20 @@ void Cws_machineEx::getThorMachineList(IConstEnvironment* constEnv, IPropertyTre
             continue;
         }
 
+        unsigned countSameAddress = 1;
+        ForEachItemIn(i, netAddresses)
+        {
+            if (streq(netAddresses.item(i), netAddress.str()))
+                countSameAddress++;
+        }
+        netAddresses.append(netAddress.str());
+
         Owned<IConstMachineInfo> pMachineInfo =  constEnv->getMachineByAddress(addressRead.str());
         if (pMachineInfo.get())
         {
             StringBuffer os, processAddress;
             os.append(pMachineInfo->getOS());
-            processAddress.appendf("%s|%s:%s:%s:%s:%s", netAddress.str(), addressRead.str(), machineType, machineName, os.str(), directory);
+            processAddress.appendf("%s|%s:%s:%s:%s:%s:%d", netAddress.str(), addressRead.str(), machineType, machineName, os.str(), directory, countSameAddress);
             processAddresses.append(processAddress);
         }
         else

+ 1 - 1
esp/services/ws_machine/ws_machineService.hpp

@@ -261,7 +261,7 @@ private:
     void determineRequredProcesses(CMachineInfoThreadParam* pParam, const char* pszProcessType, 
                                              bool bMonitorDaliFileServer, const StringArray& additionalProcesses, 
                                              set<string>& requiredProcesses);
-    void parseProperties(const char* info, StringBuffer& processType, StringBuffer& sCompName, OpSysType& os, StringBuffer& path);
+    void parseProperties(const char* info, StringBuffer& processType, StringBuffer& sCompName, OpSysType& os, StringBuffer& path, unsigned& processNumber);
     int lookupSnmpComponentIndex(const StringBuffer& sProcessType);
     const char* GetDisplayProcessName(const char* processName, char* buf);
 

+ 4 - 4
esp/services/ws_topology/ws_topologyService.cpp

@@ -1422,13 +1422,13 @@ bool CWsTopologyEx::onTpMachineQuery(IEspContext &context, IEspTpMachineQueryReq
         const char* type = req.getType();
         if (!type || !*type || (strcmp(eqAllNodes,type) == 0))
         {
-            m_TpWrapper.getClusterMachineList(eqTHORMACHINES, path, directory, MachineList, hasThorSpareProcess);
-            m_TpWrapper.getClusterMachineList(eqHOLEMACHINES, path, directory, MachineList, hasThorSpareProcess);
-            m_TpWrapper.getClusterMachineList(eqROXIEMACHINES,path, directory, MachineList, hasThorSpareProcess);
+            m_TpWrapper.getClusterMachineList(version, eqTHORMACHINES, path, directory, MachineList, hasThorSpareProcess);
+            m_TpWrapper.getClusterMachineList(version, eqHOLEMACHINES, path, directory, MachineList, hasThorSpareProcess);
+            m_TpWrapper.getClusterMachineList(version, eqROXIEMACHINES,path, directory, MachineList, hasThorSpareProcess);
         }
         else
         {
-            m_TpWrapper.getClusterMachineList(type, path, directory, MachineList, hasThorSpareProcess, req.getCluster());
+            m_TpWrapper.getClusterMachineList(version, type, path, directory, MachineList, hasThorSpareProcess, req.getCluster());
         }
         resp.setTpMachines(MachineList);
         resp.setType( req.getType() );

+ 22 - 7
esp/smc/SMCLib/TpWrapper.cpp

@@ -85,7 +85,8 @@ bool CTpWrapper::getClusterLCR(const char* clusterType, const char* clusterName)
     return bLCR;
 }
 
-void CTpWrapper::getClusterMachineList(const char* ClusterType,
+void CTpWrapper::getClusterMachineList(double clientVersion,
+                                       const char* ClusterType,
                                        const char* ClusterPath,
                                        const char* ClusterDirectory,
                                        IArrayOf<IEspTpMachine> &MachineList,
@@ -102,9 +103,9 @@ void CTpWrapper::getClusterMachineList(const char* ClusterType,
         {
             bool multiSlaves = false;
             getMachineList(eqThorMasterProcess,path.str(),"", ClusterDirectory, MachineList);
-            getMachineList(ClusterName, eqThorSlaveProcess,path.str(),"", ClusterDirectory, multiSlaves, MachineList);
+            getMachineList(clientVersion, ClusterName, eqThorSlaveProcess,path.str(),"", ClusterDirectory, multiSlaves, MachineList);
             unsigned count = MachineList.length();
-            getMachineList(ClusterName, eqThorSpareProcess,path.str(),"", ClusterDirectory, multiSlaves, MachineList);
+            getMachineList(clientVersion, ClusterName, eqThorSpareProcess,path.str(),"", ClusterDirectory, multiSlaves, MachineList);
 
             //The multiSlaves is for legacy multiSlaves environment.
             //count < MachineList.length(): There is some node for eqThorSpareProcess being added to the MachineList.
@@ -140,13 +141,13 @@ void CTpWrapper::getClusterMachineList(const char* ClusterType,
         else if (strcmp("STANDBYNNODE",ClusterType) == 0)
         {
             bool multiSlaves = false;
-            getMachineList(ClusterName,eqThorSpareProcess,path.str(),"", ClusterDirectory, multiSlaves, MachineList);
+            getMachineList(clientVersion, ClusterName,eqThorSpareProcess,path.str(),"", ClusterDirectory, multiSlaves, MachineList);
             getMachineList(eqHoleStandbyProcess,path.str(),"", ClusterDirectory, MachineList);
         }
         else if (strcmp("THORSPARENODES",ClusterType) == 0)
         {
             bool multiSlaves = false;
-            getMachineList(ClusterName, eqThorSpareProcess,path.str(),"", ClusterDirectory, multiSlaves, MachineList);
+            getMachineList(clientVersion, ClusterName, eqThorSpareProcess,path.str(),"", ClusterDirectory, multiSlaves, MachineList);
         }
         else if (strcmp("HOLESTANDBYNODES",ClusterType) == 0)
       {
@@ -1002,7 +1003,7 @@ void CTpWrapper::queryTargetClusterProcess(double version, const char* processNa
     {
         bool hasThorSpareProcess = false;
         IArrayOf<IEspTpMachine> machineList;
-        getClusterMachineList(clusterType0, tmpPath.str(), dirStr.str(), machineList, hasThorSpareProcess, processName);
+        getClusterMachineList(version, clusterType0, tmpPath.str(), dirStr.str(), machineList, hasThorSpareProcess, processName);
         if (machineList.length() > 0)
             clusterInfo->setTpMachines(machineList);
         if (version > 1.14)
@@ -1530,7 +1531,8 @@ void CTpWrapper::getMachineInfo(IEspTpMachine& machineInfo,IPropertyTree& machin
     machineInfo.setPath(tmpPath.str());
 }
 
-void CTpWrapper::getMachineList(const char* clusterName,
+void CTpWrapper::getMachineList(double clientVersion,
+                                const char* clusterName,
                                 const char* MachineType,
                                 const char* ParentPath,
                                 const char* Status,
@@ -1572,6 +1574,7 @@ void CTpWrapper::getMachineList(const char* clusterName,
         if (!nodeGroup || (nodeGroup->ordinality() == 0))
             return;
 
+        StringArray netAddresses;
         INodeIterator &gi = *nodeGroup->getIterator();
         ForEach(gi)
         {
@@ -1615,6 +1618,18 @@ void CTpWrapper::getMachineList(const char* clusterName,
                     SCMStringBuffer sName;
                     machineInfo.setDomain(pDomain->getName(sName).str());
                 }
+
+                if (clientVersion > 1.17)
+                {
+                    unsigned countSameAddress = 1;
+                    ForEachItemIn(i, netAddresses)
+                    {
+                        if (streq(netAddresses.item(i), netAddress.str()))
+                            countSameAddress++;
+                    }
+                    netAddresses.append(netAddress.str());
+                    machineInfo.setProcessNumber(countSameAddress);
+                }
             }
             else
             {

+ 2 - 2
esp/smc/SMCLib/TpWrapper.hpp

@@ -149,7 +149,7 @@ public:
     void getHthorClusterList(IArrayOf<IEspTpCluster>& clusterList);
     void getGroupList(IArrayOf<IEspTpGroup> &Groups);
     void getCluster(const char* ClusterType,IPropertyTree& returnRoot);
-    void getClusterMachineList(const char* ClusterType,const char* ClusterPath, const char* ClusterDirectory, 
+    void getClusterMachineList(double clientVersion, const char* ClusterType,const char* ClusterPath, const char* ClusterDirectory, 
                                         IArrayOf<IEspTpMachine> &MachineList, bool& hasThorSpareProcess, const char* ClusterName = NULL);
     void getMachineList( const char* MachineType,
                         const char* MachinePath,
@@ -157,7 +157,7 @@ public:
                                 const char* Directory,
                         IArrayOf<IEspTpMachine> &MachineList, 
                         set<string>* pMachineNames=NULL);
-    void getMachineList(const char* clusterName, const char* MachineType, const char* ParentPath, const char* Status,
+    void getMachineList(double clientVersion, const char* clusterName, const char* MachineType, const char* ParentPath, const char* Status,
                                 const char* Directory, bool& multiSlaves, IArrayOf<IEspTpMachine> &MachineList);
     void getDropZoneList(const char* MachineType, const char* MachinePath, const char* Directory, IArrayOf<IEspTpMachine> &MachineList);
     void setMachineInfo(const char* name,const char* type,IEspTpMachine& machine);