You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafodion.apache.org by db...@apache.org on 2019/05/16 21:14:08 UTC

[trafodion] branch master updated: [TRAFODION-3308] Improve error reporting when an executable is unavailable

This is an automated email from the ASF dual-hosted git repository.

dbirdsall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafodion.git


The following commit(s) were added to refs/heads/master by this push:
     new b60192c  [TRAFODION-3308] Improve error reporting when an executable is unavailable
     new 6a6ec64  Merge pull request #1840 from DaveBirdsall/Trafodion3308
b60192c is described below

commit b60192cc925073079e318ab651232c1ea9e8e4e6
Author: Dave Birdsall <db...@apache.org>
AuthorDate: Wed May 15 22:53:00 2019 +0000

    [TRAFODION-3308] Improve error reporting when an executable is unavailable
---
 core/sql/bin/SqlciErrors.txt                       |  2 +-
 core/sql/cli/ExSqlComp.cpp                         | 13 ++--
 core/sql/comexe/FragDir.cpp                        |  8 ++-
 core/sql/comexe/FragDir.h                          |  2 +-
 core/sql/common/Ipc.cpp                            |  6 +-
 core/sql/common/Ipc.h                              | 17 +++--
 core/sql/common/IpcGuardian.cpp                    | 74 ++++++++++++++++++----
 core/sql/executor/ExCancel.cpp                     |  3 +-
 core/sql/executor/ExExeUtil.h                      |  8 ---
 core/sql/executor/ExExeUtilCommon.cpp              | 35 ----------
 core/sql/executor/ExUdrServer.cpp                  | 21 +-----
 core/sql/optimizer/NodeMap.cpp                     | 37 ++++-------
 core/sql/runtimestats/ssmpipc.cpp                  | 12 ++--
 .../src/asciidoc/_chapters/compiler_msgs.adoc      | 24 ++++---
 .../src/asciidoc/_chapters/sqlstate.adoc           |  8 +--
 15 files changed, 127 insertions(+), 143 deletions(-)

diff --git a/core/sql/bin/SqlciErrors.txt b/core/sql/bin/SqlciErrors.txt
index 0b007dc..8034bf1 100644
--- a/core/sql/bin/SqlciErrors.txt
+++ b/core/sql/bin/SqlciErrors.txt
@@ -528,7 +528,7 @@
 2009 40000 99999 ADVANCED MAJOR DBADMIN The user transaction must be rolled back (or committed, if that makes sense in the application) before Compiler can be restarted and proceed.
 2010 ZZZZZ 99999 ADVANCED MAJOR DBADMIN Internal IPC error.
 2011 ZZZZZ 99999 ADVANCED MAJOR DBADMIN Server process could not be created - Operating system error $0~int0 while resolving program file name $1~string0.
-2012 ZZZZZ 99999 ADVANCED MAJOR DBADMIN Server process $0~string0 could not be created on $1~string1 - Operating system error $2~int0, TPCError = $3~int1, error detail = $4~int2.  (See variants of Seabed procedure msg_mon_start_process for details).
+2012 ZZZZZ 99999 ADVANCED MAJOR DBADMIN Server process $0~string0 could not be created on $1~string1 - Operating system error $2~int0, TPCError = $3~int1, error detail = $4~int2. $2~string2
 2013 ZZZZZ 99999 ADVANCED MAJOR DBADMIN Server process $0~string0 could not be created on $1~string1 - Operating system error $2~int0.
 2014 ZZZZZ 99999 ADVANCED MAJOR DBADMIN Server process $0~string0 could not be created on $1~string1 - Operating system error $2~int0 on swap file.
 2015 ZZZZZ 99999 ADVANCED CRTCL DIALOUT Server process $0~string0 could not be created on $1~string1 - CPU is unavailable (Operating system error $2~int0).
diff --git a/core/sql/cli/ExSqlComp.cpp b/core/sql/cli/ExSqlComp.cpp
index 01f8396..015f621 100644
--- a/core/sql/cli/ExSqlComp.cpp
+++ b/core/sql/cli/ExSqlComp.cpp
@@ -172,7 +172,8 @@ ExSqlComp::ReturnStatus ExSqlComp::createServer()
   //  
   if (ret == ERROR)
   {
-	error(arkcmpErrorServer);
+	if ((!diagArea_->contains(-2013)) && (!diagArea_->contains(-2012))) // avoid generating redundant error
+	  error(arkcmpErrorServer);
 	if (getenv("DEBUG_SERVER"))
 	  MessageBox(NULL, "ExSqlComp:createServer", "error ", MB_OK|MB_ICONINFORMATION);
   }
@@ -911,7 +912,7 @@ ExSqlComp::ExSqlComp(void* ex_environment,
                      short version,
                      char *nodeName ,
                      IpcEnvironment *env):
-isShared_(FALSE), lastContext_(NULL), resendingControls_(FALSE)
+isShared_(FALSE), lastContext_(NULL), resendingControls_(FALSE), nodeName_(NULL)
 {
   h_ = h;
 
@@ -930,17 +931,11 @@ isShared_(FALSE), lastContext_(NULL), resendingControls_(FALSE)
   breakReceived_ = FALSE;
   currentISPRequest_ = 0;
   connectionType_ = CmpMessageConnectionType::DMLDDL;
-  nodeName_ = new (h_) char[9];
   if (nodeName)
    {
+     nodeName_ = new (h_) char[strlen(nodeName)+1];
      strcpy(nodeName_,nodeName);
    }
-  else
-    {
-      nodeName_[0] = '\\';
-      if (ComRtGetOSClusterName(&nodeName_[1], 8, NULL) <= 0)
-	nodeName_ = nodeName;
-    }
   server_ = 0;
 
   diagArea_ = ComDiagsArea::allocate(h_);  
diff --git a/core/sql/comexe/FragDir.cpp b/core/sql/comexe/FragDir.cpp
index 245a394..c2e0ddd 100644
--- a/core/sql/comexe/FragDir.cpp
+++ b/core/sql/comexe/FragDir.cpp
@@ -41,6 +41,8 @@
 #include "ComPackDefs.h"
 #include "PartInputDataDesc.h"
 #include "Ipc.h"
+#include "trafconf/trafconfig.h"
+static const int nodeNameLen = TC_PROCESSOR_NAME_MAX;//defined in trafconf/trafconfig.h
 
 ExFragDir::ExFragDir(Lng32 entries, Space *space,
             NABoolean multiFragments, NABoolean fragmentQuotas,
@@ -150,11 +152,13 @@ const char * ExEspNodeMap::getClusterName(Lng32 instance) const
 
 void ExEspNodeMap::setEntry(Lng32 instance,
 			    const char *clusterName,
-			    Lng32 nodeNumber)
+			    Lng32 nodeNumber,
+			    Space *space)
 {
   if (map_ && entries_ > instance)
     {
-      map_[instance].clusterName_ = clusterName;
+      map_[instance].clusterName_ = space->allocateMemory(nodeNameLen);
+      strcpy(map_[instance].clusterName_, clusterName);
       map_[instance].nodeNumber_ = nodeNumber;
     }
 }
diff --git a/core/sql/comexe/FragDir.h b/core/sql/comexe/FragDir.h
index be6b9ab..d910534 100644
--- a/core/sql/comexe/FragDir.h
+++ b/core/sql/comexe/FragDir.h
@@ -137,7 +137,7 @@ public:
   // Mutator methods (for code generator only)
   void setMapArray(Lng32 entries, ExEspNodeMapEntry *me) 
                                       { map_ = me; entries_ = entries; }
-  void setEntry(Lng32 instance, const char *clusterName, Lng32 nodeNumber);
+  void setEntry(Lng32 instance, const char *clusterName, Lng32 nodeNumber, Space *space);
 
   // pack and unpack
   Long pack(void * space);
diff --git a/core/sql/common/Ipc.cpp b/core/sql/common/Ipc.cpp
index 4106896..0113996 100644
--- a/core/sql/common/Ipc.cpp
+++ b/core/sql/common/Ipc.cpp
@@ -4959,9 +4959,9 @@ void IpcServerClass::freeServerProcess(IpcServer *s)
   NADELETE(s, IpcServer, environment_->getHeap());
 }
 
-char *IpcServerClass::getProcessName(const char *nodeName, short nodeNameLen, short cpuNum, char *processName)
+char *IpcServerClass::getProcessName(short cpuNum, char *processName)
 {
-  return getServerProcessName(serverType_, nodeName, nodeNameLen, cpuNum, processName);
+  return getServerProcessName(serverType_, cpuNum, processName);
 }
 // -----------------------------------------------------------------------
 // methods for class IpcEnvironment
@@ -5607,7 +5607,7 @@ void * operator new[](size_t size, IpcEnvironment *env)
   return env->getHeap()->allocateMemory(size);
 }
 
-char *getServerProcessName(IpcServerType serverType, const char *nodeName, short nodeNameLen, 
+char *getServerProcessName(IpcServerType serverType,
                            short cpuNum, char *processName, short *envType)
 {
   const char *processPrefix = NULL;
diff --git a/core/sql/common/Ipc.h b/core/sql/common/Ipc.h
index bd58a26..2cb9db0 100644
--- a/core/sql/common/Ipc.h
+++ b/core/sql/common/Ipc.h
@@ -2806,9 +2806,9 @@ private:
   // put server cpu location in the given string. e.g. \EJR0101 cpu 1
   void getCpuLocationString(char *location);
 
-  // the node name (Expand) on which the process is started or NULL for local
-  // node, note that this name must NOT contain the leading backslash
-  const char  * nodeName_;
+  // the node name on which the process is started (determined
+  // only if needed at process start time as a function of actualCpuNum_)
+  char  * nodeName_;
 
   // The program file name of the server; if partially qualified it gets
   // expanded with $SYSTEM.SYSTEM as the default. A DEFINE name could also
@@ -2816,9 +2816,14 @@ private:
   // name unspecified or has the same system as "nodeName_".
   const char  * className_;
 
-  // the requested CPU number (on node "nodeName_")
+  // the requested Trafodion node number to start the process on
+  // (for historical reasons this is called a CpuNum); IPC_CPU_DONT_CARE
+  // if we don't care which node 
   IpcCpuNum   cpuNum_;
 
+  // the actual Trafodion node where the process was started
+  IpcCpuNum   actualCpuNum_;
+
   // remember if node-down caused server to be created on a CPU 
   // different from the requested one. (tbd - could the IpcConnection's
   // phandle be compared to cpuNum_ to give the same info?)
@@ -2915,7 +2920,7 @@ public:
 
   inline IpcServerType getServerType() { return serverType_;}
 
-  char *getProcessName(const char *nodeName, short nodeNameLen, short cpuNum, char *processName);
+  char *getProcessName(short cpuNum, char *processName);
   NABoolean parallelOpens() { return parallelOpens_; }
   NowaitedEspServer nowaitedEspServer_;
 private:
@@ -3418,7 +3423,7 @@ void * operator new[](size_t size, IpcEnvironment *env);
 
 void operator delete(void *p, IpcEnvironment *env);
 
-char *getServerProcessName(IpcServerType serverType, const char *nodeName, short nodeNameLen, 
+char *getServerProcessName(IpcServerType serverType,
                            short cpuNum, char *processName, short *envType = NULL);
 
 #endif /* IPC_H */
diff --git a/core/sql/common/IpcGuardian.cpp b/core/sql/common/IpcGuardian.cpp
index 710a58f..436801c 100644
--- a/core/sql/common/IpcGuardian.cpp
+++ b/core/sql/common/IpcGuardian.cpp
@@ -69,6 +69,8 @@ extern "C" {
 }
 #include "fs/feerrors.h"
 
+#include "trafconf/trafconfig.h"  // to get TC_PROCESSOR_NAME_MAX
+
 // Uncomment the next line to debug IPC problems (log of client's I/O)
 // #define LOG_IPC
 
@@ -3414,9 +3416,10 @@ IpcGuardianServer::IpcGuardianServer(
 					       serverClass)
 {
   serverState_                 = INITIAL;
-  nodeName_                    = nodeName;
+  nodeName_                    = NULL;
   className_                   = className;
-  cpuNum_                   = cpuNum;
+  cpuNum_                      = cpuNum;
+  actualCpuNum_                = cpuNum;
   requestedCpuDown_            = FALSE;
   priority_                    = priority;
   allocMethod_                 = allocMethod;
@@ -3531,7 +3534,7 @@ short IpcGuardianServer::workOnStartup(IpcTimeout timeout,
     {
       if (diags && (allocMethod_ != IPC_USE_PROCESS))
 	{
-	  if (!(**diags).contains(-2013))
+	  if ((!(**diags).contains(-2013)) && (!(**diags).contains(-2012))) // avoid generating redundant error
 	    {
 	      IpcAllocateDiagsArea(*diags,diagsHeap);
 
@@ -3946,6 +3949,7 @@ void IpcGuardianServer::launchNSKLiteProcess(ComDiagsArea **diags,
       bool retryStartProcess;
       do
       {
+        actualCpuNum_ = server_nid;  // save requested CPU (might be IPC_CPU_DONT_CARE)
         returnValue =  msg_mon_start_process_nowait_cb2(NewProcessCallback,
 			    prog,           /* prog */
 			    process_name,   /* name */
@@ -3965,6 +3969,8 @@ void IpcGuardianServer::launchNSKLiteProcess(ComDiagsArea **diags,
 			    NULL,
 			    unhooked_);
         ESP_TRACE2("MT: Back MMSPNW, svr: %p\n", &nowaitedEspStartup_);
+        if (actualCpuNum_ == IPC_CPU_DONT_CARE)
+          actualCpuNum_ = server_nid;  // msg_mon_start_process_nowait_cb2 might have assigned server_nid
         if (returnValue == XZFIL_ERR_FSERR && server_nid != -1)
         {
           server_nid = -1;
@@ -3987,6 +3993,7 @@ void IpcGuardianServer::launchNSKLiteProcess(ComDiagsArea **diags,
          strncpy (process_name, processName_, 99);
       }
 
+      actualCpuNum_ = server_nid;  // save requested CPU (might be IPC_CPU_DONT_CARE)
       Int32 returnValue = msg_mon_start_process2(
 			    prog,           /* prog */
 			    process_name,   /* name */
@@ -4006,6 +4013,8 @@ void IpcGuardianServer::launchNSKLiteProcess(ComDiagsArea **diags,
 			    NULL,
 			    unhooked_);
       procCreateError_ = returnValue;
+      if (actualCpuNum_ == IPC_CPU_DONT_CARE)
+        actualCpuNum_ = server_nid;  // msg_mon_start_process2 might have assigned server_nid
     }
   
   
@@ -4115,8 +4124,7 @@ void IpcGuardianServer::useProcess(ComDiagsArea **diags,
   if (processName_ == NULL)
   {
 
-    tmpProcessName = getServerClass()->getProcessName(nodeName_, 
-        (short)str_len(nodeName_), (short)cpuNum_, processName);
+    tmpProcessName = getServerClass()->getProcessName((short)cpuNum_, processName);
     // use diagsHeap for the time being
     Int32 len = str_len(processName);
 
@@ -4244,12 +4252,42 @@ void IpcGuardianServer::populateDiagsAreaFromTPCError(ComDiagsArea *&diags,
       break;
     }
 
-  char location[100];
+  char location[TC_PROCESSOR_NAME_MAX];
   getCpuLocationString(location);
   (*diags) << DgString1(location);
 
   // the $string0 parameter always identifies the program file name
   (*diags) <<  DgString0(progFileName_);
+
+  const char * interpretiveText = NULL; // for 2012 errors, we add interpretive text
+
+  switch (procCreateError_)
+    {
+    case XZFIL_ERR_NOSUCHDEV:  //  14
+    case XZFIL_ERR_FSERR:      //  53
+    case XZFIL_ERR_DEVERR:     // 190
+      interpretiveText = "Could not access executable file.";
+      break;
+
+    case XZFIL_ERR_NOBUFSPACE: //  22
+      interpretiveText = "Insufficient buffer space.";
+      break;
+
+    case XZFIL_ERR_BADREPLY:   //  74
+      interpretiveText = "Incorrect reply received from monitor.";
+      break;
+
+    case XZFIL_ERR_OVERRUN:    // 121
+      interpretiveText = "A message overrun occurred while communicating with the monitor.";
+      break;
+   
+    default:
+      interpretiveText = NULL;
+      break;
+    }
+  
+  if (interpretiveText)
+    (*diags) << DgString2(interpretiveText);
 }
 
 void IpcGuardianServer::getCpuLocationString(char *location)
@@ -4257,12 +4295,26 @@ void IpcGuardianServer::getCpuLocationString(char *location)
   if (!location)
     return;
 
-  strcpy(location, "\\");
-  strcat(location, nodeName_);
-  if (cpuNum_ != IPC_CPU_DONT_CARE)
+  // populate the nodeName_ if it has not already been captured
+  if ((nodeName_ == NULL) && (actualCpuNum_ != IPC_CPU_DONT_CARE))
+    {
+      // populate nodeName_ from the Trafodion node number that we actually attempted to use 
+      MS_Mon_Node_Info_Type nodeInfo;
+      Int32 rc = msg_mon_get_node_info_detail(actualCpuNum_, &nodeInfo);
+      if (rc == 0)
+        {
+          nodeName_ =  new (getServerClass()->getEnv()->getHeap()) char[TC_PROCESSOR_NAME_MAX];
+          strcpy(nodeName_, nodeInfo.node[0].node_name);
+        }
+    }
+
+  if (nodeName_)
+    {
+      strcpy(location,nodeName_);
+    }
+  else
     {
-      UInt32 len = strlen(location);
-      str_sprintf(&location[len], " cpu %d", cpuNum_);
+      strcpy(location,"an unspecified node");
     }
 }
 
diff --git a/core/sql/executor/ExCancel.cpp b/core/sql/executor/ExCancel.cpp
index b425ca4..53c0380 100755
--- a/core/sql/executor/ExCancel.cpp
+++ b/core/sql/executor/ExCancel.cpp
@@ -512,8 +512,7 @@ void ExCancelTcb::reportError(ComDiagsArea *da, bool addCondition,
         char processName[50];
         ContextCli *context = getGlobals()->castToExExeStmtGlobals()->
                 castToExMasterStmtGlobals()->getStatement()->getContext();
-        context->getSsmpManager()->getServerClass()->getProcessName(nodeName, (short)
-                           str_len(nodeName), cpu, processName);
+        context->getSsmpManager()->getServerClass()->getProcessName(cpu, processName);
         *diagsArea << DgString0(processName);
       }
 
diff --git a/core/sql/executor/ExExeUtil.h b/core/sql/executor/ExExeUtil.h
index 49acbad..43f2d51 100644
--- a/core/sql/executor/ExExeUtil.h
+++ b/core/sql/executor/ExExeUtil.h
@@ -207,14 +207,6 @@ class ExExeUtilTcb : public ex_tcb
                           char * &gluedQuery,
                           Lng32 &gluedQuerySize);
 
-  short extractObjectParts(
-                           char * objectName,
-                           char * sys,
-                           char * &cat,
-                           char * &sch,
-                           char * &tab,
-                           char * ansiNameBuf);
-
   // extract parts from 'objectName' and fixes up delimited names.
   Lng32 extractParts
   (char * objectName,
diff --git a/core/sql/executor/ExExeUtilCommon.cpp b/core/sql/executor/ExExeUtilCommon.cpp
index 6566f91..fa28fd5 100644
--- a/core/sql/executor/ExExeUtilCommon.cpp
+++ b/core/sql/executor/ExExeUtilCommon.cpp
@@ -286,41 +286,6 @@ short ExExeUtilTcb::work()
   return -1;
 }
 
-short ExExeUtilTcb::extractObjectParts(
-     char * objectName,
-     char * sys,
-     char * &cat,
-     char * &sch,
-     char * &tab,
-     char * ansiNameBuf)
-{
-  Lng32 error = 0;
-
-  error = ComRtGetOSClusterName(sys, 10, NULL);
-  if (error <= 0)
-    {
-      return -1;
-    }
-
-  char * parts[3];
-  Lng32 numParts;
-  if (LateNameInfo::extractParts(objectName,
-				 ansiNameBuf,
-				 numParts,
-				 parts,
-				 FALSE) ||
-      (numParts != 3))
-    {
-      return -1;
-    }
-
-  cat = parts[0];
-  sch = parts[1];
-  tab = parts[2];
-
-  return 0;
-}
-
 NABoolean ExExeUtilTcb::isUpQueueFull(short size)
 {
   if ((qparent_.up->getSize() - qparent_.up->getLength()) < size)
diff --git a/core/sql/executor/ExUdrServer.cpp b/core/sql/executor/ExUdrServer.cpp
index 07c8009..7d57639 100644
--- a/core/sql/executor/ExUdrServer.cpp
+++ b/core/sql/executor/ExUdrServer.cpp
@@ -272,17 +272,6 @@ ExUdrServer::ExUdrServerStatus ExUdrServer::start(ComDiagsArea **diags,
 #endif
     UdrDebug1("  Using a nowait depth of %d", nowaitDepth);
 
-    // If everything is successful, nodeName is not deallocated
-    // because allocateServerProcess() creates IpcGuardianServer
-    // instance which stores nodeName pointer.
-    char *nodeName = new (myIpcHeap()) char[9];
-    nodeName[0] = '\\';
-    if (ComRtGetOSClusterName(&nodeName[1], 8, NULL) <= 0)
-    {
-      myIpcHeap()->deallocateMemory(nodeName);
-      nodeName = NULL;
-    }
-
     NABoolean waitedCreation = TRUE;
     // co-locate the tdm_udrserv with the executor process (master or ESP)
     // This is done for a couple of reasons: One is that since the ESPs
@@ -298,7 +287,7 @@ ExUdrServer::ExUdrServerStatus ExUdrServer::start(ComDiagsArea **diags,
     ipcServer_ =
       udrServerClass_->allocateServerProcess(diags,
                                              diagsHeap,
-                                             nodeName,
+                                             NULL,
                                              collocatedCPU,
                                              IPC_PRIORITY_DONT_CARE,
                                              1,   // espLevel (not relevant for UDR servers) 
@@ -957,14 +946,6 @@ ExUdrServerManager::ExUdrServerManager(IpcEnvironment* env,
     , traceFile_(NULL)
 #endif
 {
-  char *nodeName = new (myIpcHeap()) char[9];
-  nodeName[0] = '\\';
-  if (ComRtGetOSClusterName(&nodeName[1], 8, NULL) <= 0)
-  {
-    myIpcHeap()->deallocateMemory(nodeName);
-    nodeName = NULL;
-  }
-
   //
   // Create the UDR server class. This does not actually
   // start any processes. Use allocateServerProcess() to
diff --git a/core/sql/optimizer/NodeMap.cpp b/core/sql/optimizer/NodeMap.cpp
index 451e653..90f8270 100644
--- a/core/sql/optimizer/NodeMap.cpp
+++ b/core/sql/optimizer/NodeMap.cpp
@@ -41,8 +41,9 @@
 #include "exp_function.h"
 
 #include "CliSemaphore.h"
+#include "trafconf/trafconfig.h"
 
-static const int nodeNameLen = 256;
+static const int nodeNameLen = TC_PROCESSOR_NAME_MAX;//defined in trafconf/trafconfig.h
 //<pb>
 //==============================================================================
 //  Helper functions called only by NodeMap member functions.
@@ -1856,6 +1857,7 @@ short NodeMap::codeGen(const PartitioningFunction *partFunc,
 		       const Lng32 numESPs,
 		       Generator *generator)
 {
+  Int32 rc = 0;
   if (partFunc == NULL)
     {
       generator->setGenObj(NULL, NULL);
@@ -1866,35 +1868,20 @@ short NodeMap::codeGen(const PartitioningFunction *partFunc,
   const NodeMap *compNodeMap = partFunc->getNodeMap();
   ExEspNodeMap *exeNodeMap = new(space) ExEspNodeMap;
   ExEspNodeMapEntry *mapEntries = new (space) ExEspNodeMapEntry[numESPs];
-  char clusterNameTemp[256];
-  NABoolean result;
   
   assert(numESPs == compNodeMap->getNumEntries());
-  assert(IPC_CPU_DONT_CARE == ANY_NODE);
-
+  
+  char *clusterName =  new (space) char[nodeNameLen]; 
+  strcpy(clusterName,"NODE");
+ 
   exeNodeMap->setMapArray(numESPs, mapEntries);
-
+  MS_Mon_Node_Info_Type nodeInfo;
   for (Lng32 i = 0; i < numESPs; i++)
-    {
+    {    
       const NodeMapEntry *ne = compNodeMap->getNodeMapEntry(i); 
-      short actualClusterNameLen = 0;
-      char *clusterName;
-
-      result = gpClusterInfo->NODE_ID_TO_NAME(ne->getClusterNumber(), 
-                                                                                              clusterNameTemp, 
-                                                                                              sizeof(clusterNameTemp)-1, 
-                                                                                              &actualClusterNameLen);
-      if (!result || actualClusterNameLen == 0)
-	clusterName = NULL; // error, don't have a node name
-      else
-	{
-	  clusterName = new (space) char[9-1];
-	  // copy the name over into the generated space, but leave
-	  // the leading backslash off
-	  str_cpy_all(clusterName,&clusterNameTemp[1],actualClusterNameLen-1);
-	  clusterName[actualClusterNameLen-1] = 0; // add a NUL terminator
-	}
-      exeNodeMap->setEntry(i,clusterName,ne->getNodeNumber());
+      rc = msg_mon_get_node_info_detail(ne->getNodeNumber(), &nodeInfo);
+      strcpy(clusterName, nodeInfo.node[0].node_name);
+      exeNodeMap->setEntry(i,clusterName,ne->getNodeNumber(),space);
     }
 
   generator->setGenObj(NULL, (ComTdb*) exeNodeMap);
diff --git a/core/sql/runtimestats/ssmpipc.cpp b/core/sql/runtimestats/ssmpipc.cpp
index e56c761..64b23dd 100755
--- a/core/sql/runtimestats/ssmpipc.cpp
+++ b/core/sql/runtimestats/ssmpipc.cpp
@@ -81,8 +81,7 @@ IpcServer *ExSsmpManager::getSsmpServer(NAHeap *heap, char *nodeName, short cpuN
 
    char *tmpProcessName;
 
-   tmpProcessName = ssmpServerClass_->getProcessName(nodeName,
-             (short) str_len(nodeName), cpuNum, ssmpProcessName);
+   tmpProcessName = ssmpServerClass_->getProcessName(cpuNum, ssmpProcessName);
    ex_assert(tmpProcessName != NULL, "ProcessName can't be null");
 
    processNameLen = str_len(tmpProcessName);
@@ -146,8 +145,7 @@ void ExSsmpManager::removeSsmpServer(char *nodeName, short cpuNum)
    Int32 processNameLen = 0;
 
    char *tmpProcessName;
-   tmpProcessName = ssmpServerClass_->getProcessName(nodeName,
-             (short) str_len(nodeName), cpuNum, ssmpProcessName);
+   tmpProcessName = ssmpServerClass_->getProcessName(cpuNum, ssmpProcessName);
    ex_assert(tmpProcessName != NULL, "ProcessName can't be null");
 
    processNameLen = str_len(tmpProcessName);
@@ -432,8 +430,7 @@ ULng32 SsmpGlobals::deAllocateServer(char *nodeName, short nodeNameLen,  short c
   serverId.nodeName_[0] = '\0';
   serverId.cpuNum_ = cpuNum;
   char *tmpProcessName;
-  tmpProcessName = sscpServerClass_->getProcessName(serverId.nodeName_,
-            (short) str_len(serverId.nodeName_), cpuNum, sscpProcessName);
+  tmpProcessName = sscpServerClass_->getProcessName(cpuNum, sscpProcessName);
   ex_assert(tmpProcessName != NULL, "ProcessName can't be null");
 
   sscps_->position(tmpProcessName, str_len(tmpProcessName));
@@ -500,8 +497,7 @@ void SsmpGlobals::allocateServerOnNextRequest(char *nodeName,
   // we will pretend that we got a NodeDown and NodeUp message and
   // issue an EMS event.
   char *tmpProcessName;
-  tmpProcessName = sscpServerClass_->getProcessName(serverId.nodeName_,
-            (short) str_len(serverId.nodeName_), cpuNum, sscpProcessName);
+  tmpProcessName = sscpServerClass_->getProcessName(cpuNum, sscpProcessName);
   ex_assert(tmpProcessName != NULL, "ProcessName can't be null");
 
   sscps_->position(tmpProcessName, str_len(tmpProcessName));
diff --git a/docs/messages_guide/src/asciidoc/_chapters/compiler_msgs.adoc b/docs/messages_guide/src/asciidoc/_chapters/compiler_msgs.adoc
index 20c6ea9..fb553be 100644
--- a/docs/messages_guide/src/asciidoc/_chapters/compiler_msgs.adoc
+++ b/docs/messages_guide/src/asciidoc/_chapters/compiler_msgs.adoc
@@ -79,36 +79,44 @@ correct the problem.
 == SQL 2012
 
 ```
-Server process <name> could not be created - error <number> <number-1>, TPCError = <number-2>, error detail = <text>.
+Server process <name> could not be created on <node> - Operating system error <OSerror>, TPCError = <Msgerror>, error detail = <detail>. <reason>
 ```
 
 Where <name> is the name of the server process.
 
-Where <number-1> is the error number.
+Where <node> is the node where {project-name} attempted to create the process.
 
-Where <number-2> is the TPCError.
+Where <OSerror> is the error number returned by the {project-name} monitor layer.
 
-Where <text> is the error message text.
+Where <Msgerror> is the error number returned by the {project-name} message layer.
+
+Where <detail> is additional error information from the message layer.
+
+Where <reason> is text that interprets the error information.
 
 *Cause:* {project-name} was unable to create server
 process <name> because of the process control procedure error <number>
-it received. More information appears in detail <text>.
+it received on the program file. More information appears in <reason>.
 
 *Effect:* The operation fails.
 
-*Recovery:* Use the process control procedure error to diagnose and correct the problem.
+*Recovery:* Use the error information to diagnose and correct the problem. For example, if the <reason> is "Could not access executable file", it may
+be that there is a file system problem on the executable file or the directory it resides in. Execute permission may have
+been removed, or the file itself may no longer be there.
 
 <<<
 [[SQL-2013]]
 == SQL 2013
 
 ```
-Server process <name> could not be created - error <number> on program file.
+Server process <name> could not be created on <node> - Operating system error <OSerror>.
 ```
 
 Where <name> is the name of the server process.
 
-Where <number> is the error number.
+Where <node> is the node where {project-name} attempted to create the process.
+
+Where <OSerror> is the error number returned by the {project-name} monitor layer.
 
 *Cause:* {project-name} was unable to create server
 process <name> because of the process control procedure error <number>
diff --git a/docs/messages_guide/src/asciidoc/_chapters/sqlstate.adoc b/docs/messages_guide/src/asciidoc/_chapters/sqlstate.adoc
index 500bd88..9356d73 100644
--- a/docs/messages_guide/src/asciidoc/_chapters/sqlstate.adoc
+++ b/docs/messages_guide/src/asciidoc/_chapters/sqlstate.adoc
@@ -216,8 +216,8 @@ numbers) and error messages (negative SQLCODE numbers).
 | 01609    | 2009    | The user transaction must be rolled back (or committed, if that makes sense in the application) before MXCMP can be restarted and proceed.
 | 0160A    | 2010    | Internal IPC error.
 | 0160B    | 2011    | Unable to create server process.  error <num> while resolving program file name <name>.
-| 0160C    | 2012    | Unable to create server process <name>.  error <num>, TPC error = <num>, error detail = <num>. (See  procedure PROCESS_LAUNCH_ for details).
-| 0160D    | 2013    | Unable to create server process <name>.  error <num> on program file.
+| 0160C    | 2012    | Server process <name> could not be created on <node> - Operating system error <OSerror>, TPCError = <Msgerror>, error detail = <detail>. <reason>
+| 0160D    | 2013    | Server process <name> could not be created on <node> - Operating system error <OSerror>.
 | 0160E    | 2014    | Unable to create server process <name>.  error <num> on swap file.
 | 0160F    | 2015    | Unable to create server process <name>. CPU is unavailable ( error <num>).
 | 0160G    | 2016    | Server process <name> was started but had undefined externals.
@@ -1663,8 +1663,8 @@ Suggestion: a) Inspect the CQS in effect; or b) Raise the optimization level to
 | X0208    | -2008   | Internal error: out of virtual memory.
 | X020A    | -2010   | Internal IPC error.
 | X020B    | -2011   | Unable to create server process. Error <num> while resolving program file name <name>.
-| X020C    | -2012   | Unable to create server process <name>. Error <num>, TPC Error = <num>, error detail = <text>. (See  procedure PROCESS_LAUNCH_ for details).
-| X020D    | -2013   | Unable to create server process <name>.  error <num> on program file.
+| X020C    | -2012   | Server process <name> could not be created on <node> - Operating system error <OSerror>, TPCError = <Msgerror>, error detail = <detail>. <reason>
+| X020D    | -2013   | Server process <name> could not be created on <node> - Operating system error <OSerror>.
 | X020E    | -2014   | Unable to create server process <name>.  error <num> on swap file.
 | X020F    | -2015   | Unable to create server process <name>. CPU is unavailable ( error <num>).
 | X020G    | -2016   | Server process <name> was started but had undefined externals.