From 8178861dd94c8ebda6d2410bbb54565af162d568 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.(none)" <>
Date: Thu, 9 Sep 2004 13:55:14 +0000
Subject: [PATCH] improved show command fixed some mutex locks for Ndb objects
 moved TranspoterFacade::stop_instance to cluster connection moved Socket
 Server::start_server outside the TransporterFacade::start_instance thread

---
 ndb/include/mgmapi/mgmapi.h               |   2 +
 ndb/src/mgmapi/mgmapi.cpp                 |  24 ++-
 ndb/src/mgmclient/CommandInterpreter.cpp  | 184 +++++++++++-----------
 ndb/src/mgmsrv/MgmtSrvr.cpp               |   9 +-
 ndb/src/mgmsrv/MgmtSrvr.hpp               |   2 +
 ndb/src/mgmsrv/Services.cpp               |   1 +
 ndb/src/ndbapi/Ndbinit.cpp                |  20 ++-
 ndb/src/ndbapi/TransporterFacade.cpp      |  18 +--
 ndb/src/ndbapi/TransporterFacade.hpp      |   1 +
 ndb/src/ndbapi/ndb_cluster_connection.cpp |   1 +
 10 files changed, 144 insertions(+), 118 deletions(-)

diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h
index a745688561..b5cbac5599 100644
--- a/ndb/include/mgmapi/mgmapi.h
+++ b/ndb/include/mgmapi/mgmapi.h
@@ -204,6 +204,7 @@ extern "C" {
     int version;                            ///< Internal version number
     int connect_count;                      ///< No of times node has connected
                                             ///< or disconnected to the mgm srv
+    char connect_address[sizeof("000.000.000.000")+1];
   };
 
   /**
@@ -214,6 +215,7 @@ extern "C" {
                                             ///< node_states array
     struct ndb_mgm_node_state               ///< An array with node_states
     node_states[1];
+    const char *hostname;
   };
 
   /**
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index 0f65d9425a..ec88d9c29c 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -509,6 +509,9 @@ status_ackumulate(struct ndb_mgm_node_state * state,
     state->version = atoi(value);
   } else if(strcmp("connect_count", field) == 0){
     state->connect_count = atoi(value);    
+  } else if(strcmp("address", field) == 0){
+    strncpy(state->connect_address, value, sizeof(state->connect_address));
+    state->connect_address[sizeof(state->connect_address)-1]= 0;
   } else {
     ndbout_c("Unknown field: %s", field);
   }
@@ -575,22 +578,27 @@ ndb_mgm_get_status(NdbMgmHandle handle)
 
   ndb_mgm_cluster_state *state = (ndb_mgm_cluster_state*)
     malloc(sizeof(ndb_mgm_cluster_state)+
-	   noOfNodes*sizeof(ndb_mgm_node_state));
+	   noOfNodes*(sizeof(ndb_mgm_node_state)+sizeof("000.000.000.000#")));
 
-  state->no_of_nodes = noOfNodes;
+  state->hostname= 0;
+  state->no_of_nodes= noOfNodes;
   ndb_mgm_node_state * ptr = &state->node_states[0];
   int nodeId = 0;
-  int i = -1; ptr--;
+  int i;
+  for (i= 0; i < noOfNodes; i++) {
+    state->node_states[i].connect_address[0]= 0;
+  }
+  i = -1; ptr--;
   for(; i<noOfNodes; ){
     in.gets(buf, sizeof(buf));
     tmp.assign(buf);
-    
+
     if(tmp.trim() == ""){
       break;
     }
     
     Vector<BaseString> split;
-    tmp.split(split, ":.");
+    tmp.split(split, ":.", 4);
     if(split.size() != 4)
       break;
     
@@ -1512,8 +1520,10 @@ extern "C"
 void
 ndb_mgm_destroy_configuration(struct ndb_mgm_configuration *cfg)
 {
-  if (cfg)
-    delete (ConfigValues *)cfg;
+  if (cfg) {
+    ((ConfigValues *)cfg)->~ConfigValues();
+    free((void *)cfg);
+  }
 }
 
 extern "C"
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index 5496f18bd2..f07fe44dd2 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -19,6 +19,7 @@
 #include <mgmapi.h>
 #include <mgmapi_debug.h>
 #include <version.h>
+#include <NdbAutoPtr.hpp>
 #include <NdbOut.hpp>
 #include <NdbSleep.h>
 #include <EventLogger.hpp>
@@ -692,6 +693,79 @@ CommandInterpreter::executeShutdown(char* parameters)
  * SHOW
  *****************************************************************************/
 
+
+static
+const char *status_string(ndb_mgm_node_status status)
+{
+  switch(status){
+  case NDB_MGM_NODE_STATUS_NO_CONTACT:
+    return "not connected";
+  case NDB_MGM_NODE_STATUS_NOT_STARTED:
+    return "not started";
+  case NDB_MGM_NODE_STATUS_STARTING:
+    return "starting";
+  case NDB_MGM_NODE_STATUS_STARTED:
+    return "started";
+  case NDB_MGM_NODE_STATUS_SHUTTING_DOWN:
+    return "shutting down";
+  case NDB_MGM_NODE_STATUS_RESTARTING:
+    return "restarting";
+  case NDB_MGM_NODE_STATUS_SINGLEUSER:
+    return "single user mode";
+  default:
+    return "unknown state";
+  }
+}
+
+static void
+print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it,
+	    const char *proc_name, int no_proc, ndb_mgm_node_type type, int master_id)
+{ 
+  int i;
+  ndbout << "[" << proc_name
+	 << "(" << ndb_mgm_get_node_type_string(type) << ")]\t" << no_proc << " node(s)" << endl;
+  for(i=0; i < state->no_of_nodes; i++) {
+    struct ndb_mgm_node_state *node_state= &(state->node_states[i]);
+    if(node_state->node_type == type) {
+      int node_id= node_state->node_id;
+      ndbout << "id=" << node_id;
+      if(node_state->version != 0) {
+	const char *hostname= node_state->connect_address;
+	if (hostname == 0 || strlen(hostname) == 0 || strcmp(hostname,"0.0.0.0") == 0)
+	  ndbout << " ";
+	else
+	  ndbout << "\t@" << hostname;
+	ndbout << "  (Version: "
+	       << getMajor(node_state->version) << "."
+	       << getMinor(node_state->version) << "."
+	       << getBuild(node_state->version);
+	if (type == NDB_MGM_NODE_TYPE_NDB) {
+	  if (node_state->node_status != NDB_MGM_NODE_STATUS_STARTED) {
+	    ndbout << ", " << status_string(node_state->node_status);
+	  }
+	  if (node_state->node_group >= 0) {
+	    ndbout << ", Nodegroup: " << node_state->node_group;
+	    if (node_state->dynamic_id == master_id)
+	      ndbout << ", Master";
+	  }
+	}
+	ndbout << ")" << endl;
+      } else {
+	if(ndb_mgm_find(it, CFG_NODE_ID, node_id) != 0){
+	  ndbout_c("Unable to find node with id: %d", node_id);
+	  return;
+	}
+	const char *config_hostname= 0;
+	ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &config_hostname);
+	if (config_hostname == 0 || config_hostname[0] == 0)
+	  config_hostname= "any host";
+	ndbout << " (not connected, accepting connect from " << config_hostname << ")" << endl;
+      }
+    }
+  }
+  ndbout << endl;
+}
+
 void
 CommandInterpreter::executeShow(char* parameters) 
 { 
@@ -708,6 +782,22 @@ CommandInterpreter::executeShow(char* parameters)
       return;
     }
 
+    ndb_mgm_configuration * conf = ndb_mgm_get_configuration(m_mgmsrv,0);
+    if(conf == 0){
+      ndbout_c("Could not get configuration");
+      printError();
+      return;
+    }
+
+    ndb_mgm_configuration_iterator * it;
+    it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf, CFG_SECTION_NODE);
+
+    if(it == 0){
+      ndbout_c("Unable to create config iterator");
+      return;
+    }
+    NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it);
+
     int
       master_id= 0,
       ndb_nodes= 0,
@@ -741,73 +831,9 @@ CommandInterpreter::executeShow(char* parameters)
       }
     }
 
-    ndbout << ndb_nodes
-	   << " [ndbd] node(s)" 
-	   << endl;
-
-    for(i=0; i < state->no_of_nodes; i++) {
-      if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_NDB) {
-	ndbout << "[ndbd]\t\tid=" << state->node_states[i].node_id;
-	if(state->node_states[i].version != 0) {
-	  ndbout << "  (Version: "
-		 << getMajor(state->node_states[i].version) << "."
-		 << getMinor(state->node_states[i].version) << "."
-		 << getBuild(state->node_states[i].version) << ","
-		 << " Nodegroup: " << state->node_states[i].node_group;
-	  if (state->node_states[i].dynamic_id == master_id)
-	    ndbout << ", Master";
-	  ndbout << ")" << endl;
-	} else
-	  {
-	    ndbout << "  (not connected) " << endl;
-	  }
-
-      }
-    }
-    ndbout << endl;
-    
-    ndbout << mgm_nodes
-	   << " [ndb_mgmd] node(s)" 
-	   << endl;
-
-    for(i=0; i < state->no_of_nodes; i++) {
-      if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_MGM) {
-	ndbout << "[ndb_mgmd]\tid=" << state->node_states[i].node_id;
-	if(state->node_states[i].version != 0) {
-	  ndbout << "  (Version: "
-		 << getMajor(state->node_states[i].version) << "."
-		 << getMinor(state->node_states[i].version) << "."
-		 << getBuild(state->node_states[i].version) << ")" << endl;
-	  
-	} else
-	  {
-	    ndbout << "  (no version information available) " << endl;
-	  }
-      }
-    }
-    ndbout << endl;
-
-    ndbout << api_nodes
-	   << " [mysqld] node(s)" 
-	   << endl;
-
-    for(i=0; i < state->no_of_nodes; i++) {
-      if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_API) {
-	ndbout << "[mysqld]\tid=" << state->node_states[i].node_id;
-	if(state->node_states[i].version != 0) {
-	  ndbout << "  (Version: "
-		 << getMajor(state->node_states[i].version) << "."
-		 << getMinor(state->node_states[i].version) << "."
-		 << getBuild(state->node_states[i].version) << ")" << endl;
-	  
-	} else
-	  {
-	    ndbout << "  (not connected) " << endl;
-	  }
-      }
-    }
-    ndbout << endl;
-    
+    print_nodes(state, it, "ndbd",     ndb_nodes, NDB_MGM_NODE_TYPE_NDB, master_id);
+    print_nodes(state, it, "ndb_mgmd", mgm_nodes, NDB_MGM_NODE_TYPE_MGM, 0);
+    print_nodes(state, it, "mysqld",   api_nodes, NDB_MGM_NODE_TYPE_API, 0);
     //    ndbout << helpTextShow;
     return;
   } else if (strcmp(parameters, "PROPERTIES") == 0 ||
@@ -1184,33 +1210,15 @@ CommandInterpreter::executeStatus(int processId,
   startPhase = cl->node_states[i].start_phase;
   version = cl->node_states[i].version;
 
-  ndbout << "Node " << processId << ": ";
+  ndbout << "Node " << processId << ": " << status_string(status);
   switch(status){
-  case NDB_MGM_NODE_STATUS_NO_CONTACT:
-    ndbout << "No contact" << endl;
-    break;
-  case NDB_MGM_NODE_STATUS_NOT_STARTED:
-    ndbout << "Not started" ;
-    break;
   case NDB_MGM_NODE_STATUS_STARTING:
-    ndbout << "Starting (Start phase " << startPhase << ")" ;
-    break;
-  case NDB_MGM_NODE_STATUS_STARTED:
-    ndbout << "Started" ;
+    ndbout << " (Phase " << startPhase << ")" ;
     break;
   case NDB_MGM_NODE_STATUS_SHUTTING_DOWN:
-    ndbout << "Shutting down " << (system == false ? "node" : "system")
-	   << " (Phase " << startPhase << ")"
-	   ;
-    break;
-  case NDB_MGM_NODE_STATUS_RESTARTING:
-    ndbout << "Restarting" ;
-    break;
-  case NDB_MGM_NODE_STATUS_SINGLEUSER:
-    ndbout << "Single user mode" ;
+    ndbout << " (Phase " << startPhase << ")";
     break;
   default:
-    ndbout << "Unknown state" ;
     break;
   }
   if(status != NDB_MGM_NODE_STATUS_NO_CONTACT)
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index 0f50fd6c59..53778ded7d 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -543,9 +543,10 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
   /**
    * Fill the nodeTypes array
    */
-  for(Uint32 i = 0; i<MAX_NODES; i++)
+  for(Uint32 i = 0; i<MAX_NODES; i++) {
     nodeTypes[i] = (enum ndb_mgm_node_type)-1;
-
+    m_connect_address[i].s_addr= 0;
+  }
   {
     ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator
       (config->m_configValues, CFG_SECTION_NODE);
@@ -2387,6 +2388,10 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
       }
     }
     *nodeId= tmp;
+    if (client_addr)
+      m_connect_address[tmp]= ((struct sockaddr_in *)client_addr)->sin_addr;
+    else
+      Ndb_getInAddr(&(m_connect_address[tmp]), "localhost");
     m_reserved_nodes.set(tmp);
 #if 0
     ndbout << "MgmtSrvr::getFreeNodeId found type=" << type
diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp
index e910fb6744..c9622fb8c1 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -520,6 +520,7 @@ public:
 
   int setDbParameter(int node, int parameter, const char * value, BaseString&);
   
+  const char *get_connect_address(Uint32 node_id) { return inet_ntoa(m_connect_address[node_id]); }
   //**************************************************************************
 private:
   //**************************************************************************
@@ -559,6 +560,7 @@ private:
   
   NodeBitmask m_reserved_nodes;
   Allocated_resources m_allocated_resources;
+  struct in_addr m_connect_address[MAX_NODES];
 
   int _setVarReqResult; // The result of the SET_VAR_REQ response
   Statistics _statistics; // handleSTATISTICS_CONF store the result here, 
diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp
index 0f54a15c20..b85b8dfd53 100644
--- a/ndb/src/mgmsrv/Services.cpp
+++ b/ndb/src/mgmsrv/Services.cpp
@@ -943,6 +943,7 @@ printNodeStatus(OutputStream *output,
     output->println("node.%d.dynamic_id: %d", nodeId, dynamicId);
     output->println("node.%d.node_group: %d", nodeId, nodeGroup);
     output->println("node.%d.connect_count: %d", nodeId, connectCount);
+    output->println("node.%d.address: %s", nodeId, mgmsrv.get_connect_address(nodeId));
   }
 
 }
diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp
index 9ec500b2a4..2a00bc67c2 100644
--- a/ndb/src/ndbapi/Ndbinit.cpp
+++ b/ndb/src/ndbapi/Ndbinit.cpp
@@ -20,8 +20,6 @@
 
 #include "NdbApiSignal.hpp"
 #include "NdbImpl.hpp"
-//#include "NdbSchemaOp.hpp"
-//#include "NdbSchemaCon.hpp" 
 #include "NdbOperation.hpp"
 #include "NdbConnection.hpp"
 #include "NdbRecAttr.hpp"
@@ -59,13 +57,16 @@ Parameters:    aDataBase : Name of the database.
 Remark:        Connect to the database.
 ***************************************************************************/
 Ndb::Ndb( const char* aDataBase , const char* aSchema) {
+  NdbMutex_Lock(&createNdbMutex);
+  if (theNoOfNdbObjects < 0)
+    abort(); // old and new Ndb constructor used mixed
+  theNoOfNdbObjects++;
   if (global_ndb_cluster_connection == 0) {
-    if (theNoOfNdbObjects > 0)
-      abort(); // old and new Ndb constructor used mixed
     my_init();
     global_ndb_cluster_connection= new Ndb_cluster_connection(ndbConnectString);
     global_ndb_cluster_connection->connect();
   }
+  NdbMutex_Unlock(&createNdbMutex);
   setup(global_ndb_cluster_connection, aDataBase, aSchema);
 }
 
@@ -75,6 +76,7 @@ Ndb::Ndb( Ndb_cluster_connection *ndb_cluster_connection,
   if (global_ndb_cluster_connection != 0 &&
       global_ndb_cluster_connection != ndb_cluster_connection)
     abort(); // old and new Ndb constructor used mixed
+  theNoOfNdbObjects= -1;
   setup(ndb_cluster_connection, aDataBase, aSchema);
 }
 
@@ -168,9 +170,6 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection,
   
   theWaiter.m_mutex =  TransporterFacade::instance()->theMutexPtr;
 
-  // For keeping track of how many Ndb objects that exists.
-  theNoOfNdbObjects += 1;
-  
   // Signal that the constructor has finished OK
   if (theInitState == NotConstructed)
     theInitState = NotInitialised;
@@ -229,10 +228,9 @@ Ndb::~Ndb()
   
   NdbMutex_Lock(&createNdbMutex);
 
-  theNoOfNdbObjects -= 1;
-  if(theNoOfNdbObjects == 0){
-    TransporterFacade::stop_instance();
-    if (global_ndb_cluster_connection != 0) {
+  if (global_ndb_cluster_connection != 0) {
+    theNoOfNdbObjects--;
+    if(theNoOfNdbObjects == 0){
       delete global_ndb_cluster_connection;
       global_ndb_cluster_connection= 0;
     }
diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp
index 4a7ad8a687..f0b0bfe2de 100644
--- a/ndb/src/ndbapi/TransporterFacade.cpp
+++ b/ndb/src/ndbapi/TransporterFacade.cpp
@@ -413,20 +413,13 @@ runSendRequest_C(void * me)
 
 void TransporterFacade::threadMainSend(void)
 {
-  SocketServer socket_server;
-
   theTransporterRegistry->startSending();
-  if (!theTransporterRegistry->start_service(socket_server)){
-    ndbout_c("Unable to start theTransporterRegistry->start_service");
-    exit(0);
-  }
-
   if (!theTransporterRegistry->start_clients()){
     ndbout_c("Unable to start theTransporterRegistry->start_clients");
     exit(0);
   }
 
-  socket_server.startServer();
+  m_socket_server.startServer();
 
   while(!theStopReceive) {
     NdbSleep_MilliSleep(10);
@@ -439,8 +432,8 @@ void TransporterFacade::threadMainSend(void)
   }
   theTransporterRegistry->stopSending();
 
-  socket_server.stopServer();
-  socket_server.stopSessions();
+  m_socket_server.stopServer();
+  m_socket_server.stopSessions();
 
   theTransporterRegistry->stop_clients();
 }
@@ -558,6 +551,11 @@ TransporterFacade::init(Uint32 nodeId, const ndb_mgm_configuration* props)
   }
 #endif
   
+  if (!theTransporterRegistry->start_service(m_socket_server)){
+    ndbout_c("Unable to start theTransporterRegistry->start_service");
+    return false;
+  }
+
   theReceiveThread = NdbThread_Create(runReceiveResponse_C,
                                       (void**)this,
                                       32768,
diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp
index 130a24345b..76beaa708f 100644
--- a/ndb/src/ndbapi/TransporterFacade.hpp
+++ b/ndb/src/ndbapi/TransporterFacade.hpp
@@ -138,6 +138,7 @@ private:
   void doStop();
   
   TransporterRegistry* theTransporterRegistry;
+  SocketServer m_socket_server;
   int sendPerformedLastInterval;
   int theOwnId;
 
diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp
index bd0ea246a0..27695cec18 100644
--- a/ndb/src/ndbapi/ndb_cluster_connection.cpp
+++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp
@@ -145,6 +145,7 @@ int Ndb_cluster_connection::connect(int reconnect)
 
 Ndb_cluster_connection::~Ndb_cluster_connection()
 {
+  TransporterFacade::stop_instance();
   if (m_connect_thread)
   {
     void *status;
-- 
2.30.9