Commit 1860613c authored by tomas@poseidon.ndb.mysql.com's avatar tomas@poseidon.ndb.mysql.com

Merge

parents 146d6887 11bd3eed
...@@ -7,69 +7,30 @@ Discless: CHOOSE_Discless ...@@ -7,69 +7,30 @@ Discless: CHOOSE_Discless
[COMPUTER] [COMPUTER]
Id: 1 Id: 1
ByteOrder: Little
HostName: CHOOSE_HOSTNAME_1 HostName: CHOOSE_HOSTNAME_1
[COMPUTER] [COMPUTER]
Id: 2 Id: 2
ByteOrder: Little
HostName: CHOOSE_HOSTNAME_2 HostName: CHOOSE_HOSTNAME_2
[COMPUTER] [DB]
Id: 3
ByteOrder: Little
HostName: CHOOSE_HOSTNAME_3
[COMPUTER]
Id: 4
ByteOrder: Little
HostName: CHOOSE_HOSTNAME_4
[COMPUTER]
Id: 5
ByteOrder: Little
HostName: CHOOSE_HOSTNAME_5
[COMPUTER]
Id: 6
ByteOrder: Little
HostName: CHOOSE_HOSTNAME_6
[COMPUTER]
Id: 7
ByteOrder: Little
HostName: CHOOSE_HOSTNAME_7
[MGM]
Id: 1
ExecuteOnComputer: 1 ExecuteOnComputer: 1
PortNumber: CHOOSE_PORT_MGM FileSystemPath: CHOOSE_FILESYSTEM_NODE_1
[DB] [DB]
Id: 2
ExecuteOnComputer: 2 ExecuteOnComputer: 2
FileSystemPath: CHOOSE_FILESYSTEM_NODE_2 FileSystemPath: CHOOSE_FILESYSTEM_NODE_2
[DB] [MGM]
Id: 3 PortNumber: CHOOSE_PORT_MGM
ExecuteOnComputer: 3
FileSystemPath: CHOOSE_FILESYSTEM_NODE_3
[API] [API]
Id: 11
ExecuteOnComputer: 4
[API] [API]
Id: 12
ExecuteOnComputer: 5
[API] [API]
Id: 13
ExecuteOnComputer: 6
[API] [API]
Id: 14
ExecuteOnComputer: 7
[TCP DEFAULT] [TCP DEFAULT]
PortNumber: CHOOSE_PORT_TRANSPORTER PortNumber: CHOOSE_PORT_TRANSPORTER
...@@ -82,11 +82,8 @@ while test $# -gt 0; do ...@@ -82,11 +82,8 @@ while test $# -gt 0; do
done done
fs_ndb=$fsdir/ndbcluster fs_ndb=$fsdir/ndbcluster
fs_mgm_1=$fs_ndb/1.ndb_mgm fs_name_1=$fs_ndb/node-1-fs-$port_base
fs_ndb_2=$fs_ndb/2.ndb_db
fs_ndb_3=$fs_ndb/3.ndb_db
fs_name_2=$fs_ndb/node-2-fs-$port_base fs_name_2=$fs_ndb/node-2-fs-$port_base
fs_name_3=$fs_ndb/node-3-fs-$port_base
NDB_HOME= NDB_HOME=
export NDB_CONNECTSTRING export NDB_CONNECTSTRING
...@@ -111,13 +108,10 @@ NDB_CONNECTSTRING= ...@@ -111,13 +108,10 @@ NDB_CONNECTSTRING=
if [ $initial_ndb ] ; then if [ $initial_ndb ] ; then
[ -d $fs_ndb ] || mkdir $fs_ndb [ -d $fs_ndb ] || mkdir $fs_ndb
[ -d $fs_mgm_1 ] || mkdir $fs_mgm_1 [ -d $fs_name_1 ] || mkdir $fs_name_1
[ -d $fs_ndb_2 ] || mkdir $fs_ndb_2
[ -d $fs_ndb_3 ] || mkdir $fs_ndb_3
[ -d $fs_name_2 ] || mkdir $fs_name_2 [ -d $fs_name_2 ] || mkdir $fs_name_2
[ -d $fs_name_3 ] || mkdir $fs_name_3
fi fi
if [ -d "$fs_ndb" -a -d "$fs_mgm_1" -a -d "$fs_ndb_2" -a -d "$fs_ndb_3" -a -d "$fs_name_2" -a -d "$fs_name_3" ]; then :; else if [ -d "$fs_ndb" -a -d "$fs_name_1" -a -d "$fs_name_2" ]; then :; else
echo "$fs_ndb filesystem directory does not exist" echo "$fs_ndb filesystem directory does not exist"
exit 1 exit 1
fi fi
...@@ -127,14 +121,11 @@ fi ...@@ -127,14 +121,11 @@ fi
ndb_host="localhost" ndb_host="localhost"
ndb_mgmd_port=$port_base ndb_mgmd_port=$port_base
port_transporter=`expr $ndb_mgmd_port + 2` port_transporter=`expr $ndb_mgmd_port + 2`
NDB_CONNECTSTRING_BASE="host=$ndb_host:$ndb_mgmd_port;nodeid=" export NDB_CONNECTSTRING="host=$ndb_host:$ndb_mgmd_port"
# Start management server as deamon # Start management server as deamon
NDB_ID="1"
NDB_CONNECTSTRING=$NDB_CONNECTSTRING_BASE$NDB_ID
# Edit file system path and ports in config file # Edit file system path and ports in config file
if [ $initial_ndb ] ; then if [ $initial_ndb ] ; then
...@@ -144,60 +135,54 @@ sed \ ...@@ -144,60 +135,54 @@ sed \
-e s,"CHOOSE_IndexMemory",$ndb_imem,g \ -e s,"CHOOSE_IndexMemory",$ndb_imem,g \
-e s,"CHOOSE_Discless",$ndb_discless,g \ -e s,"CHOOSE_Discless",$ndb_discless,g \
-e s,"CHOOSE_HOSTNAME_".*,"$ndb_host",g \ -e s,"CHOOSE_HOSTNAME_".*,"$ndb_host",g \
-e s,"CHOOSE_FILESYSTEM_NODE_1","$fs_name_1",g \
-e s,"CHOOSE_FILESYSTEM_NODE_2","$fs_name_2",g \ -e s,"CHOOSE_FILESYSTEM_NODE_2","$fs_name_2",g \
-e s,"CHOOSE_FILESYSTEM_NODE_3","$fs_name_3",g \
-e s,"CHOOSE_PORT_MGM",$ndb_mgmd_port,g \ -e s,"CHOOSE_PORT_MGM",$ndb_mgmd_port,g \
-e s,"CHOOSE_PORT_TRANSPORTER",$port_transporter,g \ -e s,"CHOOSE_PORT_TRANSPORTER",$port_transporter,g \
< ndb/ndb_config_2_node.ini \ < ndb/ndb_config_2_node.ini \
> "$fs_mgm_1/config.ini" > "$fs_ndb/config.ini"
fi fi
if ( cd $fs_mgm_1 ; echo $NDB_CONNECTSTRING > $cfgfile ; $exec_mgmtsrvr -d -c config.ini ) ; then :; else rm -f Ndb.cfg
rm -f $fs_ndb/Ndb.cfg
if ( cd $fs_ndb ; $exec_mgmtsrvr -d -c config.ini ) ; then :; else
echo "Unable to start $exec_mgmtsrvr from `pwd`" echo "Unable to start $exec_mgmtsrvr from `pwd`"
exit 1 exit 1
fi fi
cat `find $fs_ndb -name 'node*.pid'` > $pidfile cat `find $fs_ndb -name 'ndb_*.pid'` > $pidfile
# Start database node # Start database node
NDB_ID="2" echo "Starting ndbd"
NDB_CONNECTSTRING=$NDB_CONNECTSTRING_BASE$NDB_ID ( cd $fs_ndb ; $exec_ndb -d $flags_ndb & )
echo "Starting ndbd connectstring=\""$NDB_CONNECTSTRING\"
( cd $fs_ndb_2 ; echo $NDB_CONNECTSTRING > $cfgfile ; $exec_ndb -d $flags_ndb & )
cat `find $fs_ndb -name 'node*.pid'` > $pidfile cat `find $fs_ndb -name 'ndb_*.pid'` > $pidfile
# Start database node # Start database node
NDB_ID="3" echo "Starting ndbd"
NDB_CONNECTSTRING=$NDB_CONNECTSTRING_BASE$NDB_ID ( cd $fs_ndb ; $exec_ndb -d $flags_ndb & )
echo "Starting ndbd connectstring=\""$NDB_CONNECTSTRING\"
( cd $fs_ndb_3 ; echo $NDB_CONNECTSTRING > $cfgfile ; $exec_ndb -d $flags_ndb & )
cat `find $fs_ndb -name 'node*.pid'` > $pidfile cat `find $fs_ndb -name 'ndb_*.pid'` > $pidfile
# test if Ndb Cluster starts properly # test if Ndb Cluster starts properly
echo "Waiting for started..." echo "Waiting for started..."
NDB_ID="11"
NDB_CONNECTSTRING=$NDB_CONNECTSTRING_BASE$NDB_ID
if ( $exec_waiter ) | grep "NDBT_ProgramExit: 0 - OK"; then :; else if ( $exec_waiter ) | grep "NDBT_ProgramExit: 0 - OK"; then :; else
echo "Ndbcluster startup failed" echo "Ndbcluster startup failed"
exit 1 exit 1
fi fi
echo $NDB_CONNECTSTRING > $cfgfile cat `find $fs_ndb -name 'ndb_*.pid'` > $pidfile
cat `find $fs_ndb -name 'node*.pid'` > $pidfile
status_ndbcluster status_ndbcluster
} }
status_ndbcluster() { status_ndbcluster() {
# Start management client # Start management client
echo "show" | $exec_mgmtclient $ndb_host $ndb_mgmd_port
echo "show" | $exec_mgmtclient $ndb_host $ndb_mgmd_port
} }
stop_default_ndbcluster() { stop_default_ndbcluster() {
......
...@@ -72,13 +72,6 @@ public: ...@@ -72,13 +72,6 @@ public:
*/ */
~EventLogger(); ~EventLogger();
/**
* Open/create the eventlog, the default name is 'cluster.log'.
*
* @return true if successful.
*/
bool open();
/** /**
* Opens/creates the eventlog with the specified filename. * Opens/creates the eventlog with the specified filename.
* *
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#define NODE_INFO_HPP #define NODE_INFO_HPP
#include <NdbOut.hpp> #include <NdbOut.hpp>
#include <mgmapi_config_parameters.h>
class NodeInfo { class NodeInfo {
public: public:
...@@ -27,10 +28,10 @@ public: ...@@ -27,10 +28,10 @@ public:
* NodeType * NodeType
*/ */
enum NodeType { enum NodeType {
DB = 0, ///< Database node DB = NODE_TYPE_DB, ///< Database node
API = 1, ///< NDB API node API = NODE_TYPE_API, ///< NDB API node
MGM = 2, ///< Management node (incl. NDB API) MGM = NODE_TYPE_MGM, ///< Management node (incl. NDB API)
REP = 3, ///< Replication node (incl. NDB API) REP = NODE_TYPE_REP, ///< Replication node (incl. NDB API)
INVALID = 255 ///< Invalid type INVALID = 255 ///< Invalid type
}; };
NodeType getType() const; NodeType getType() const;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#define NODE_STATE_HPP #define NODE_STATE_HPP
#include <NdbOut.hpp> #include <NdbOut.hpp>
#include <NodeBitmask.hpp>
class NodeState { class NodeState {
public: public:
...@@ -99,7 +100,7 @@ public: ...@@ -99,7 +100,7 @@ public:
/** /**
* Length in 32-bit words * Length in 32-bit words
*/ */
static const Uint32 DataLength = 8; static const Uint32 DataLength = 8 + NdbNodeBitmask::Size;
/** /**
* Constructor(s) * Constructor(s)
...@@ -146,6 +147,8 @@ public: ...@@ -146,6 +147,8 @@ public:
Uint32 singleUserMode; Uint32 singleUserMode;
Uint32 singleUserApi; //the single user node Uint32 singleUserApi; //the single user node
BitmaskPOD<NdbNodeBitmask::Size> m_connected_nodes;
void setDynamicId(Uint32 dynamic); void setDynamicId(Uint32 dynamic);
void setNodeGroup(Uint32 group); void setNodeGroup(Uint32 group);
void setSingleUser(Uint32 s); void setSingleUser(Uint32 s);
...@@ -182,6 +185,7 @@ NodeState::NodeState(){ ...@@ -182,6 +185,7 @@ NodeState::NodeState(){
dynamicId = 0xFFFFFFFF; dynamicId = 0xFFFFFFFF;
singleUserMode = 0; singleUserMode = 0;
singleUserApi = 0xFFFFFFFF; singleUserApi = 0xFFFFFFFF;
m_connected_nodes.clear();
} }
inline inline
......
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
* @{ * @{
*/ */
#include "mgmapi_config_parameters.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
...@@ -81,10 +83,10 @@ extern "C" { ...@@ -81,10 +83,10 @@ extern "C" {
*/ */
enum ndb_mgm_node_type { enum ndb_mgm_node_type {
NDB_MGM_NODE_TYPE_UNKNOWN = -1, /*/< Node type not known*/ NDB_MGM_NODE_TYPE_UNKNOWN = -1, /*/< Node type not known*/
NDB_MGM_NODE_TYPE_API = 0, /*/< An application node (API)*/ NDB_MGM_NODE_TYPE_API = NODE_TYPE_API, /*/< An application node (API)*/
NDB_MGM_NODE_TYPE_NDB = 1, /*/< A database node (DB)*/ NDB_MGM_NODE_TYPE_NDB = NODE_TYPE_DB, /*/< A database node (DB)*/
NDB_MGM_NODE_TYPE_MGM = 2, /*/< A management server node (MGM)*/ NDB_MGM_NODE_TYPE_MGM = NODE_TYPE_MGM, /*/< A management server node (MGM)*/
NDB_MGM_NODE_TYPE_REP = 3, ///< A replication node NDB_MGM_NODE_TYPE_REP = NODE_TYPE_REP, ///< A replication node
NDB_MGM_NODE_TYPE_MIN = 0, /*/< Min valid value*/ NDB_MGM_NODE_TYPE_MIN = 0, /*/< Min valid value*/
NDB_MGM_NODE_TYPE_MAX = 3 /*/< Max valid value*/ NDB_MGM_NODE_TYPE_MAX = 3 /*/< Max valid value*/
...@@ -666,6 +668,11 @@ extern "C" { ...@@ -666,6 +668,11 @@ extern "C" {
*/ */
struct ndb_mgm_configuration * ndb_mgm_get_configuration(NdbMgmHandle handle, struct ndb_mgm_configuration * ndb_mgm_get_configuration(NdbMgmHandle handle,
unsigned version); unsigned version);
int ndb_mgm_alloc_nodeid(NdbMgmHandle handle,
unsigned version,
unsigned *pnodeid,
int nodetype);
/** /**
* Config iterator * Config iterator
*/ */
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CFG_SYS_PRIMARY_MGM_NODE 1 #define CFG_SYS_PRIMARY_MGM_NODE 1
#define CFG_SYS_CONFIG_GENERATION 2 #define CFG_SYS_CONFIG_GENERATION 2
#define CFG_SYS_REPLICATION_ROLE 7 #define CFG_SYS_REPLICATION_ROLE 7
#define CFG_SYS_PORT_BASE 8
#define CFG_NODE_ID 3 #define CFG_NODE_ID 3
#define CFG_NODE_BYTE_ORDER 4 #define CFG_NODE_BYTE_ORDER 4
......
...@@ -77,7 +77,7 @@ public: ...@@ -77,7 +77,7 @@ public:
* Get config using socket * Get config using socket
*/ */
struct ndb_mgm_configuration * getConfig(const char * mgmhost, short port, struct ndb_mgm_configuration * getConfig(const char * mgmhost, short port,
int versionId); int versionId, int nodetype);
/** /**
* Get config from file * Get config from file
*/ */
...@@ -99,6 +99,8 @@ private: ...@@ -99,6 +99,8 @@ private:
char * m_connectString; char * m_connectString;
char * m_defaultConnectString; char * m_defaultConnectString;
NdbMgmHandle m_handle;
/** /**
* Verify config * Verify config
*/ */
......
...@@ -21,11 +21,14 @@ ...@@ -21,11 +21,14 @@
extern "C" { extern "C" {
#endif #endif
const char* NdbConfig_HomePath(char* buf, int buflen); char* NdbConfig_NdbCfgName(int with_ndb_home);
char* NdbConfig_ErrorFileName(int node_id);
const char* NdbConfig_NdbCfgName(char* buf, int buflen, int with_ndb_home); char* NdbConfig_ClusterLogFileName(int node_id);
const char* NdbConfig_ErrorFileName(char* buf, int buflen); char* NdbConfig_SignalLogFileName(int node_id);
const char* NdbConfig_ClusterLogFileName(char* buf, int buflen); char* NdbConfig_TraceFileName(int node_id, int file_no);
char* NdbConfig_NextTraceFileName(int node_id);
char* NdbConfig_PidFileName(int node_id);
char* NdbConfig_StdoutFileName(int node_id);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include <my_global.h> #include <my_global.h>
#define NDB_BASE_PORT 2200
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
#define NDB_WIN32 #define NDB_WIN32
#else #else
......
...@@ -64,7 +64,7 @@ typedef int socklen_t; ...@@ -64,7 +64,7 @@ typedef int socklen_t;
#define NDB_NONBLOCK O_NONBLOCK #define NDB_NONBLOCK O_NONBLOCK
#define NDB_SOCKET_TYPE int #define NDB_SOCKET_TYPE int
#define NDB_INVALID_SOCKET -1 #define NDB_INVALID_SOCKET -1
#define NDB_CLOSE_SOCKET(x) close(x) #define NDB_CLOSE_SOCKET(x) ::close(x)
#define InetErrno errno #define InetErrno errno
......
...@@ -29,20 +29,10 @@ ...@@ -29,20 +29,10 @@
#define TransporterRegistry_H #define TransporterRegistry_H
#include "TransporterDefinitions.hpp" #include "TransporterDefinitions.hpp"
#include <SocketServer.hpp>
#include <NdbTCP.h> #include <NdbTCP.h>
// A transporter is always in a PerformState.
// PerformIO is used initially and as long as any of the events
// PerformConnect, ...
enum PerformState {
PerformNothing = 4, // Does nothing
PerformIO = 0, // Is connected
PerformConnect = 1, // Is trying to connect
PerformDisconnect = 2, // Trying to disconnect
RemoveTransporter = 3 // Will be removed
};
// A transporter is always in an IOState. // A transporter is always in an IOState.
// NoHalt is used initially and as long as it is no restrictions on // NoHalt is used initially and as long as it is no restrictions on
// sending or receiving. // sending or receiving.
...@@ -60,18 +50,45 @@ enum TransporterType { ...@@ -60,18 +50,45 @@ enum TransporterType {
tt_OSE_TRANSPORTER = 4 tt_OSE_TRANSPORTER = 4
}; };
static const char *performStateString[] =
{ "is connected",
"is trying to connect",
"does nothing",
"is trying to disconnect" };
class Transporter; class Transporter;
class TCP_Transporter; class TCP_Transporter;
class SCI_Transporter; class SCI_Transporter;
class SHM_Transporter; class SHM_Transporter;
class OSE_Transporter; class OSE_Transporter;
class TransporterRegistry;
class SocketAuthenticator;
class TransporterService : public SocketServer::Service {
SocketAuthenticator * m_auth;
TransporterRegistry * m_transporter_registry;
public:
TransporterService(SocketAuthenticator *auth= 0)
{
m_auth= auth;
m_transporter_registry= 0;
}
void setTransporterRegistry(TransporterRegistry *t)
{
m_transporter_registry= t;
}
SocketServer::Session * newSession(NDB_SOCKET_TYPE socket);
};
/** /**
* @class TransporterRegistry * @class TransporterRegistry
* @brief ... * @brief ...
*/ */
class TransporterRegistry { class TransporterRegistry {
friend class OSE_Receiver; friend class OSE_Receiver;
friend class Transporter;
friend class TransporterService;
public: public:
/** /**
* Constructor * Constructor
...@@ -98,6 +115,12 @@ public: ...@@ -98,6 +115,12 @@ public:
*/ */
~TransporterRegistry(); ~TransporterRegistry();
bool start_service(SocketServer& server);
bool start_clients();
bool stop_clients();
void start_clients_thread();
void update_connections();
/** /**
* Start/Stop receiving * Start/Stop receiving
*/ */
...@@ -110,16 +133,26 @@ public: ...@@ -110,16 +133,26 @@ public:
void startSending(); void startSending();
void stopSending(); void stopSending();
/** // A transporter is always in a PerformState.
* Get and set methods for PerformState // PerformIO is used initially and as long as any of the events
*/ // PerformConnect, ...
PerformState performState(NodeId nodeId); enum PerformState {
void setPerformState(NodeId nodeId, PerformState state); CONNECTED = 0,
CONNECTING = 1,
DISCONNECTED = 2,
DISCONNECTING = 3
};
const char *getPerformStateString(NodeId nodeId) const
{ return performStateString[(unsigned)performStates[nodeId]]; };
/** /**
* Set perform state for all transporters * Get and set methods for PerformState
*/ */
void setPerformState(PerformState state); void do_connect(NodeId node_id);
void do_disconnect(NodeId node_id);
bool is_connected(NodeId node_id) { return performStates[node_id] == CONNECTED; };
void report_connect(NodeId node_id);
void report_disconnect(NodeId node_id, int errnum);
/** /**
* Get and set methods for IOState * Get and set methods for IOState
...@@ -174,8 +207,6 @@ public: ...@@ -174,8 +207,6 @@ public:
void performReceive(); void performReceive();
void performSend(); void performSend();
void checkConnections();
/** /**
* Force sending if more than or equal to sendLimit * Force sending if more than or equal to sendLimit
* number have asked for send. Returns 0 if not sending * number have asked for send. Returns 0 if not sending
...@@ -187,11 +218,18 @@ public: ...@@ -187,11 +218,18 @@ public:
void printState(); void printState();
#endif #endif
unsigned short m_service_port;
protected: protected:
private: private:
void * callbackObj; void * callbackObj;
TransporterService *m_transporter_service;
char *m_interface_name;
struct NdbThread *m_start_clients_thread;
bool m_run_start_clients_thread;
int sendCounter; int sendCounter;
NodeId localNodeId; NodeId localNodeId;
bool nodeIdSpecified; bool nodeIdSpecified;
...@@ -202,11 +240,6 @@ private: ...@@ -202,11 +240,6 @@ private:
int nSHMTransporters; int nSHMTransporters;
int nOSETransporters; int nOSETransporters;
int m_ccCount;
int m_ccIndex;
int m_ccStep;
int m_nTransportersPerformConnect;
bool m_ccReady;
/** /**
* Arrays holding all transporters in the order they are created * Arrays holding all transporters in the order they are created
*/ */
......
This diff is collapsed.
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef SOCKET_AUTHENTICATOR_HPP
#define SOCKET_AUTHENTICATOR_HPP
class SocketAuthenticator
{
public:
virtual ~SocketAuthenticator() {};
virtual bool client_authenticate(int sockfd) = 0;
virtual bool server_authenticate(int sockfd) = 0;
};
class SocketAuthSimple : public SocketAuthenticator
{
const char *m_passwd;
const char *m_username;
public:
SocketAuthSimple(const char *username, const char *passwd);
virtual ~SocketAuthSimple();
virtual bool client_authenticate(int sockfd);
virtual bool server_authenticate(int sockfd);
};
#endif // SOCKET_AUTHENTICATOR_HPP
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef SOCKET_CLIENT_HPP
#define SOCKET_CLIENT_HPP
#include <NdbTCP.h>
class SocketAuthenticator;
class SocketClient
{
NDB_SOCKET_TYPE m_sockfd;
struct sockaddr_in m_servaddr;
unsigned short m_port;
char *m_server_name;
SocketAuthenticator *m_auth;
public:
SocketClient(const char *server_name, unsigned short port, SocketAuthenticator *sa = 0);
~SocketClient();
bool init();
NDB_SOCKET_TYPE connect();
bool close();
};
#endif // SOCKET_ClIENT_HPP
...@@ -1350,15 +1350,6 @@ EventLogger::EventLogger() : Logger(), m_logLevel(), m_filterLevel(15) ...@@ -1350,15 +1350,6 @@ EventLogger::EventLogger() : Logger(), m_logLevel(), m_filterLevel(15)
EventLogger::~EventLogger() EventLogger::~EventLogger()
{ {
}
bool
EventLogger::open()
{
char clusterLog[128];
NdbConfig_ClusterLogFileName(clusterLog, 128);
return open(clusterLog);
} }
bool bool
......
...@@ -83,9 +83,6 @@ ConfigInfo::m_SectionRules[] = { ...@@ -83,9 +83,6 @@ ConfigInfo::m_SectionRules[] = {
{ "SCI", transformConnection, 0 }, { "SCI", transformConnection, 0 },
{ "OSE", transformConnection, 0 }, { "OSE", transformConnection, 0 },
{ "TCP", fixPortNumber, 0 },
//{ "SHM", fixShmKey, 0 },
{ "DB", fixNodeHostname, 0 }, { "DB", fixNodeHostname, 0 },
{ "API", fixNodeHostname, 0 }, { "API", fixNodeHostname, 0 },
{ "MGM", fixNodeHostname, 0 }, { "MGM", fixNodeHostname, 0 },
...@@ -106,6 +103,9 @@ ConfigInfo::m_SectionRules[] = { ...@@ -106,6 +103,9 @@ ConfigInfo::m_SectionRules[] = {
{ "OSE", fixHostname, "HostName1" }, { "OSE", fixHostname, "HostName1" },
{ "OSE", fixHostname, "HostName2" }, { "OSE", fixHostname, "HostName2" },
{ "TCP", fixPortNumber, 0 }, // has to come after fixHostName
//{ "SHM", fixShmKey, 0 },
/** /**
* fixExtConnection must be after fixNodeId * fixExtConnection must be after fixNodeId
*/ */
...@@ -146,13 +146,17 @@ const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule); ...@@ -146,13 +146,17 @@ const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule);
/**************************************************************************** /****************************************************************************
* Config Rules declarations * Config Rules declarations
****************************************************************************/ ****************************************************************************/
bool addNodeConnections(Vector<ConfigInfo::ConfigRuleSection>&sections, bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx,
const char * rule_data);
bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx, struct InitConfigFileParser::Context &ctx,
const char * ruleData); const char * rule_data);
const ConfigInfo::ConfigRule const ConfigInfo::ConfigRule
ConfigInfo::m_ConfigRules[] = { ConfigInfo::m_ConfigRules[] = {
{ addNodeConnections, 0 }, { add_node_connections, 0 },
{ add_server_ports, 0 },
{ 0, 0 } { 0, 0 }
}; };
...@@ -325,6 +329,18 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ...@@ -325,6 +329,18 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0, 0,
0x7FFFFFFF }, 0x7FFFFFFF },
{
CFG_SYS_PORT_BASE,
"PortBase",
"SYSTEM",
"Base port for system",
ConfigInfo::USED,
false,
ConfigInfo::INT,
NDB_BASE_PORT+2,
0,
0x7FFFFFFF },
/*************************************************************************** /***************************************************************************
* DB * DB
***************************************************************************/ ***************************************************************************/
...@@ -376,6 +392,18 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ...@@ -376,6 +392,18 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
1, 1,
(MAX_NODES - 1) }, (MAX_NODES - 1) },
{
KEY_INTERNAL,
"ServerPort",
"DB",
"Port used to setup transporter",
ConfigInfo::USED,
false,
ConfigInfo::INT,
UNDEFINED,
1,
65535 },
{ {
CFG_DB_NO_REPLICAS, CFG_DB_NO_REPLICAS,
"NoOfReplicas", "NoOfReplicas",
...@@ -1231,7 +1259,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ...@@ -1231,7 +1259,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
ConfigInfo::USED, ConfigInfo::USED,
false, false,
ConfigInfo::STRING, ConfigInfo::STRING,
MANDATORY, 0,
0, 0,
0x7FFFFFFF }, 0x7FFFFFFF },
...@@ -1330,7 +1358,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ...@@ -1330,7 +1358,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
ConfigInfo::USED, ConfigInfo::USED,
false, false,
ConfigInfo::STRING, ConfigInfo::STRING,
MANDATORY, 0,
0, 0,
0x7FFFFFFF }, 0x7FFFFFFF },
...@@ -1354,7 +1382,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ...@@ -1354,7 +1382,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
ConfigInfo::USED, ConfigInfo::USED,
false, false,
ConfigInfo::INT, ConfigInfo::INT,
2200, NDB_BASE_PORT,
0, 0,
0x7FFFFFFF }, 0x7FFFFFFF },
...@@ -1538,7 +1566,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ...@@ -1538,7 +1566,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
ConfigInfo::USED, ConfigInfo::USED,
false, false,
ConfigInfo::INT, ConfigInfo::INT,
2202, NDB_BASE_PORT+2,
0, 0,
0x7FFFFFFF }, 0x7FFFFFFF },
...@@ -2489,11 +2517,27 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2489,11 +2517,27 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){
Uint32 id; Uint32 id;
if(!ctx.m_currentSection->get("Id", &id)){ if(!ctx.m_currentSection->get("Id", &id)){
Uint32 nextNodeId= 1;
ctx.m_userProperties.get("NextNodeId", &nextNodeId);
id= nextNodeId;
while (ctx.m_userProperties.get("AllocatedNodeId_", id, &id))
id++;
ctx.m_userProperties.put("NextNodeId", id+1, true);
ctx.m_currentSection->put("Id", id);
#if 0
ctx.reportError("Mandatory parameter Id missing from section " ctx.reportError("Mandatory parameter Id missing from section "
"[%s] starting at line: %d", "[%s] starting at line: %d",
ctx.fname, ctx.m_sectionLineno); ctx.fname, ctx.m_sectionLineno);
return false; return false;
#endif
} else if(ctx.m_userProperties.get("AllocatedNodeId_", id, &id)) {
ctx.reportError("Duplicate Id in section "
"[%s] starting at line: %d",
ctx.fname, ctx.m_sectionLineno);
return false;
} }
ctx.m_userProperties.put("AllocatedNodeId_", id, id);
snprintf(ctx.pname, sizeof(ctx.pname), "Node_%d", id); snprintf(ctx.pname, sizeof(ctx.pname), "Node_%d", id);
ctx.m_currentSection->put("Type", ctx.fname); ctx.m_currentSection->put("Type", ctx.fname);
...@@ -2510,10 +2554,25 @@ fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2510,10 +2554,25 @@ fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data){
const char * compId; const char * compId;
if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId)){ if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId)){
require(ctx.m_currentSection->put("HostName", ""));
const char * type;
if(ctx.m_currentSection->get("Type", &type) &&
strcmp(type,"DB") == 0)
{
ctx.reportError("Parameter \"ExecuteOnComputer\" missing from DB section "
"[%s] starting at line: %d",
ctx.fname, ctx.m_sectionLineno);
return false;
}
return true;
#if 0
ctx.reportError("Parameter \"ExecuteOnComputer\" missing from section " ctx.reportError("Parameter \"ExecuteOnComputer\" missing from section "
"[%s] starting at line: %d", "[%s] starting at line: %d",
ctx.fname, ctx.m_sectionLineno); ctx.fname, ctx.m_sectionLineno);
return false; return false;
#endif
} }
const Properties * computer; const Properties * computer;
...@@ -2870,18 +2929,44 @@ fixHostname(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2870,18 +2929,44 @@ fixHostname(InitConfigFileParser::Context & ctx, const char * data){
bool bool
fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){
if(!ctx.m_currentSection->contains("PortNumber")){ Uint32 id1= 0, id2= 0;
Uint32 adder = 0; require(ctx.m_currentSection->get("NodeId1", &id1));
ctx.m_userProperties.get("PortNumberAdder", &adder); require(ctx.m_currentSection->get("NodeId2", &id2));
id1 = id1 < id2 ? id1 : id2;
const Properties * node;
require(ctx.m_config->get("Node", id1, &node));
BaseString hostname;
require(node->get("HostName", hostname));
if (hostname.c_str()[0] == 0) {
ctx.reportError("Hostname required on nodeid %d since it will act as server.", id1);
return false;
}
Uint32 port= 0;
if (!node->get("ServerPort", &port) && !ctx.m_userProperties.get("ServerPort_", id1, &port)) {
hostname.append("_ServerPortAdder");
Uint32 adder= 0;
ctx.m_userProperties.get(hostname.c_str(), &adder);
ctx.m_userProperties.put(hostname.c_str(), adder+1, true);
Uint32 base = 0; Uint32 base = 0;
if(!(ctx.m_userDefaults && ctx.m_userDefaults->get("PortNumber", &base)) && if(!(ctx.m_userDefaults && ctx.m_userDefaults->get("PortNumber", &base)) &&
!ctx.m_systemDefaults->get("PortNumber", &base)){ !ctx.m_systemDefaults->get("PortNumber", &base)){
return false; return false;
} }
ctx.m_currentSection->put("PortNumber", base + adder); port= base + adder;
adder++; ctx.m_userProperties.put("ServerPort_", id1, port);
ctx.m_userProperties.put("PortNumberAdder", adder, true);
} }
if(ctx.m_currentSection->contains("PortNumber")) {
ndbout << "PortNumber should no longer be specificied per connection, please remove from config. Will be changed to " << port << endl;
}
ctx.m_currentSection->put("PortNumber", port);
return true; return true;
} }
...@@ -3158,9 +3243,9 @@ saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -3158,9 +3243,9 @@ saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){
} }
bool bool
addNodeConnections(Vector<ConfigInfo::ConfigRuleSection>&sections, add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx, struct InitConfigFileParser::Context &ctx,
const char * ruleData) const char * rule_data)
{ {
Properties * props= ctx.m_config; Properties * props= ctx.m_config;
Properties p_connections; Properties p_connections;
...@@ -3241,3 +3326,42 @@ addNodeConnections(Vector<ConfigInfo::ConfigRuleSection>&sections, ...@@ -3241,3 +3326,42 @@ addNodeConnections(Vector<ConfigInfo::ConfigRuleSection>&sections,
return true; return true;
} }
bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx,
const char * rule_data)
{
#if 0
Properties * props= ctx.m_config;
Properties computers;
Uint32 port_base = NDB_BASE_PORT+2;
Uint32 nNodes;
ctx.m_userProperties.get("NoOfNodes", &nNodes);
for (Uint32 i= 0, n= 0; n < nNodes; i++){
Properties * tmp;
if(!props->get("Node", i, &tmp)) continue;
n++;
const char * type;
if(!tmp->get("Type", &type)) continue;
Uint32 port;
if (tmp->get("ServerPort", &port)) continue;
Uint32 computer;
if (!tmp->get("ExecuteOnComputer", &computer)) continue;
Uint32 adder= 0;
computers.get("",computer, &adder);
if (strcmp(type,"DB") == 0) {
adder++;
tmp->put("ServerPort", port_base+adder);
computers.put("",computer, adder);
}
}
#endif
return true;
}
...@@ -45,13 +45,15 @@ ...@@ -45,13 +45,15 @@
ConfigRetriever::ConfigRetriever() { ConfigRetriever::ConfigRetriever() {
_localConfigFileName = NULL; _localConfigFileName = 0;
m_defaultConnectString = NULL; m_defaultConnectString = 0;
errorString = 0; errorString = 0;
_localConfig = new LocalConfig(); _localConfig = new LocalConfig();
m_connectString = NULL; m_connectString = 0;
m_handle= 0;
} }
ConfigRetriever::~ConfigRetriever(){ ConfigRetriever::~ConfigRetriever(){
...@@ -68,6 +70,11 @@ ConfigRetriever::~ConfigRetriever(){ ...@@ -68,6 +70,11 @@ ConfigRetriever::~ConfigRetriever(){
free(errorString); free(errorString);
delete _localConfig; delete _localConfig;
if (m_handle) {
ndb_mgm_disconnect(m_handle);
ndb_mgm_destroy_handle(&m_handle);
}
} }
...@@ -114,7 +121,8 @@ ConfigRetriever::getConfig(int verId, int nodeType) { ...@@ -114,7 +121,8 @@ ConfigRetriever::getConfig(int verId, int nodeType) {
struct ndb_mgm_configuration * p = 0; struct ndb_mgm_configuration * p = 0;
switch(m->type){ switch(m->type){
case MgmId_TCP: case MgmId_TCP:
p = getConfig(m->data.tcp.remoteHost, m->data.tcp.port, verId); p = getConfig(m->data.tcp.remoteHost, m->data.tcp.port,
verId, nodeType);
break; break;
case MgmId_File: case MgmId_File:
p = getConfig(m->data.file.filename, verId); p = getConfig(m->data.file.filename, verId);
...@@ -155,30 +163,52 @@ ConfigRetriever::getConfig(int verId, int nodeType) { ...@@ -155,30 +163,52 @@ ConfigRetriever::getConfig(int verId, int nodeType) {
ndb_mgm_configuration * ndb_mgm_configuration *
ConfigRetriever::getConfig(const char * mgmhost, ConfigRetriever::getConfig(const char * mgmhost,
short port, short port,
int versionId){ int versionId,
int nodetype){
if (m_handle) {
ndb_mgm_disconnect(m_handle);
ndb_mgm_destroy_handle(&m_handle);
}
m_handle = ndb_mgm_create_handle();
NdbMgmHandle h; if (m_handle == 0) {
h = ndb_mgm_create_handle();
if (h == NULL) {
setError(CR_ERROR, "Unable to allocate mgm handle"); setError(CR_ERROR, "Unable to allocate mgm handle");
return 0; return 0;
} }
BaseString tmp; BaseString tmp;
tmp.assfmt("%s:%d", mgmhost, port); tmp.assfmt("%s:%d", mgmhost, port);
if (ndb_mgm_connect(h, tmp.c_str()) != 0) { if (ndb_mgm_connect(m_handle, tmp.c_str()) != 0) {
setError(CR_RETRY, ndb_mgm_get_latest_error_desc(h)); setError(CR_RETRY, ndb_mgm_get_latest_error_desc(m_handle));
ndb_mgm_destroy_handle(&h); ndb_mgm_destroy_handle(&m_handle);
m_handle= 0;
return 0; return 0;
} }
ndb_mgm_configuration * conf = ndb_mgm_get_configuration(h, versionId); ndb_mgm_configuration * conf = ndb_mgm_get_configuration(m_handle, versionId);
if(conf == 0){ if(conf == 0){
setError(CR_ERROR, ndb_mgm_get_latest_error_desc(h)); setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
ndb_mgm_disconnect(m_handle);
ndb_mgm_destroy_handle(&m_handle);
m_handle= 0;
return 0;
}
{
unsigned nodeid= getOwnNodeId();
int res= ndb_mgm_alloc_nodeid(m_handle, versionId, &nodeid, nodetype);
if(res != 0) {
setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
ndb_mgm_disconnect(m_handle);
ndb_mgm_destroy_handle(&m_handle);
m_handle= 0;
return 0;
} }
ndb_mgm_disconnect(h); _ownNodeId= nodeid;
ndb_mgm_destroy_handle(&h); }
return conf; return conf;
#if 0 #if 0
...@@ -329,6 +359,9 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, ...@@ -329,6 +359,9 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf,
} }
do { do {
if(strlen(hostname) == 0)
break;
if(strcasecmp(hostname, localhost) == 0) if(strcasecmp(hostname, localhost) == 0)
break; break;
......
...@@ -339,12 +339,13 @@ IPCConfig::getNodeType(NodeId id) const { ...@@ -339,12 +339,13 @@ IPCConfig::getNodeType(NodeId id) const {
return out; return out;
} }
#include <mgmapi.h>
Uint32 Uint32
IPCConfig::configureTransporters(Uint32 nodeId, IPCConfig::configureTransporters(Uint32 nodeId,
const class ndb_mgm_configuration & config, const class ndb_mgm_configuration & config,
class TransporterRegistry & tr){ class TransporterRegistry & tr){
Uint32 noOfTransportersCreated = 0; Uint32 noOfTransportersCreated= 0, server_port= 0;
ndb_mgm_configuration_iterator iter(config, CFG_SECTION_CONNECTION); ndb_mgm_configuration_iterator iter(config, CFG_SECTION_CONNECTION);
for(iter.first(); iter.valid(); iter.next()){ for(iter.first(); iter.valid(); iter.next()){
...@@ -440,6 +441,14 @@ IPCConfig::configureTransporters(Uint32 nodeId, ...@@ -440,6 +441,14 @@ IPCConfig::configureTransporters(Uint32 nodeId,
} }
} }
if (nodeId <= nodeId1 && nodeId <= nodeId2) {
if (server_port && server_port != conf.port) {
ndbout << "internal error in config setup of server ports line= " << __LINE__ << endl;
exit(-1);
}
server_port= conf.port;
}
conf.localNodeId = nodeId; conf.localNodeId = nodeId;
conf.remoteNodeId = remoteNodeId; conf.remoteNodeId = remoteNodeId;
conf.localHostName = (nodeId == nodeId1 ? host1 : host2); conf.localHostName = (nodeId == nodeId1 ? host1 : host2);
...@@ -490,6 +499,8 @@ IPCConfig::configureTransporters(Uint32 nodeId, ...@@ -490,6 +499,8 @@ IPCConfig::configureTransporters(Uint32 nodeId,
} }
} }
tr.m_service_port= server_port;
return noOfTransportersCreated; return noOfTransportersCreated;
} }
...@@ -17,10 +17,12 @@ ...@@ -17,10 +17,12 @@
#include "LocalConfig.hpp" #include "LocalConfig.hpp"
#include <NdbEnv.h> #include <NdbEnv.h>
#include <NdbConfig.h> #include <NdbConfig.h>
#include <NdbAutoPtr.hpp>
LocalConfig::LocalConfig(){ LocalConfig::LocalConfig(){
ids = 0; size = 0; items = 0; ids = 0; size = 0; items = 0;
error_line = 0; error_msg[0] = 0; error_line = 0; error_msg[0] = 0;
_ownNodeId= 0;
} }
bool bool
...@@ -68,10 +70,10 @@ LocalConfig::init(bool onlyNodeId, ...@@ -68,10 +70,10 @@ LocalConfig::init(bool onlyNodeId,
//4. Check Ndb.cfg in NDB_HOME //4. Check Ndb.cfg in NDB_HOME
{ {
bool fopenError; bool fopenError;
char buf[256]; char *buf= NdbConfig_NdbCfgName(1 /*true*/);
if(readFile(NdbConfig_NdbCfgName(buf, sizeof(buf), 1 /*true*/), fopenError, onlyNodeId)){ NdbAutoPtr<char> tmp_aptr(buf);
if(readFile(buf, fopenError, onlyNodeId))
return true; return true;
}
if (!fopenError) if (!fopenError)
return false; return false;
} }
...@@ -79,22 +81,29 @@ LocalConfig::init(bool onlyNodeId, ...@@ -79,22 +81,29 @@ LocalConfig::init(bool onlyNodeId,
//5. Check Ndb.cfg in cwd //5. Check Ndb.cfg in cwd
{ {
bool fopenError; bool fopenError;
char buf[256]; char *buf= NdbConfig_NdbCfgName(0 /*false*/);
if(readFile(NdbConfig_NdbCfgName(buf, sizeof(buf), 0 /*false*/), fopenError, onlyNodeId)){ NdbAutoPtr<char> tmp_aptr(buf);
if(readFile(buf, fopenError, onlyNodeId))
return true; return true;
}
if (!fopenError) if (!fopenError)
return false; return false;
} }
//6. Check defaultConnectString //6. Check defaultConnectString
if(defaultConnectString != 0) { if(defaultConnectString != 0) {
if(readConnectString(defaultConnectString, onlyNodeId)){ if(readConnectString(defaultConnectString, onlyNodeId))
return true; return true;
}
return false; return false;
} }
//7. Check
{
char buf[256];
snprintf(buf, sizeof(buf), "host=localhost:%u", NDB_BASE_PORT);
if(readConnectString(buf, onlyNodeId))
return true;
}
setError(0, ""); setError(0, "");
return false; return false;
...@@ -144,12 +153,12 @@ void LocalConfig::printUsage() const { ...@@ -144,12 +153,12 @@ void LocalConfig::printUsage() const {
ndbout << "1. Put a Ndb.cfg file in the directory where you start"<<endl ndbout << "1. Put a Ndb.cfg file in the directory where you start"<<endl
<< " the node. "<< endl << " the node. "<< endl
<< " Ex: Ndb.cfg" << endl << " Ex: Ndb.cfg" << endl
<< " | nodeid=11;host=localhost:2200"<<endl<<endl; << " | host=localhost:"<<NDB_BASE_PORT<<endl;
ndbout << "2. Use the environment variable NDB_CONNECTSTRING to "<<endl ndbout << "2. Use the environment variable NDB_CONNECTSTRING to "<<endl
<< " provide this information." <<endl << " provide this information." <<endl
<< " Ex: " << endl << " Ex: " << endl
<< " >export NDB_CONNECTSTRING=\"nodeid=11;host=localhost:2200\"" << " >export NDB_CONNECTSTRING=\"host=localhost:"<<NDB_BASE_PORT<<"\""
<<endl<<endl; <<endl<<endl;
} }
......
...@@ -18,43 +18,92 @@ ...@@ -18,43 +18,92 @@
#include <NdbConfig.h> #include <NdbConfig.h>
#include <NdbEnv.h> #include <NdbEnv.h>
const char* static char*
NdbConfig_HomePath(char* buf, int buflen){ NdbConfig_AllocHomePath(int _len)
const char* p; {
p = NdbEnv_GetEnv("NDB_HOME", buf, buflen); const char *path= NdbEnv_GetEnv("NDB_HOME", 0, 0);
if (p == NULL){ int len= _len;
strlcpy(buf, "", buflen); int path_len= 0;
p = buf;
} else { if (path)
const int len = strlen(buf); path_len= strlen(path);
if(len != 0 && buf[len-1] != '/'){
buf[len] = '/'; len+= path_len;
buf[len+1] = 0; char *buf= malloc(len);
} if (path_len > 0)
} snprintf(buf, len, "%s%c", path, DIR_SEPARATOR);
return p;
}
const char*
NdbConfig_NdbCfgName(char* buf, int buflen, int with_ndb_home){
if (with_ndb_home)
NdbConfig_HomePath(buf, buflen);
else else
buf[0] = 0; buf[0]= 0;
strlcat(buf, "Ndb.cfg", buflen);
return buf;
}
char*
NdbConfig_NdbCfgName(int with_ndb_home){
char *buf;
int len= 0;
if (with_ndb_home) {
buf= NdbConfig_AllocHomePath(128);
len= strlen(buf);
} else
buf= malloc(128);
snprintf(buf+len, 128, "Ndb.cfg");
return buf;
}
char*
NdbConfig_ErrorFileName(int node_id){
char *buf= NdbConfig_AllocHomePath(128);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_error.log", node_id);
return buf;
}
char*
NdbConfig_ClusterLogFileName(int node_id){
char *buf= NdbConfig_AllocHomePath(128);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_cluster.log", node_id);
return buf;
}
char*
NdbConfig_SignalLogFileName(int node_id){
char *buf= NdbConfig_AllocHomePath(128);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_signal.log", node_id);
return buf;
}
char*
NdbConfig_TraceFileName(int node_id, int file_no){
char *buf= NdbConfig_AllocHomePath(128);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_trace.log.%u", node_id, file_no);
return buf;
}
char*
NdbConfig_NextTraceFileName(int node_id){
char *buf= NdbConfig_AllocHomePath(128);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_trace.log.next", node_id);
return buf; return buf;
} }
const char* char*
NdbConfig_ErrorFileName(char* buf, int buflen){ NdbConfig_PidFileName(int node_id){
NdbConfig_HomePath(buf, buflen); char *buf= NdbConfig_AllocHomePath(128);
strlcat(buf, "error.log", buflen); int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u.pid", node_id);
return buf; return buf;
} }
const char* char*
NdbConfig_ClusterLogFileName(char* buf, int buflen){ NdbConfig_StdoutFileName(int node_id){
NdbConfig_HomePath(buf, buflen); char *buf= NdbConfig_AllocHomePath(128);
strlcat(buf, "cluster.log", buflen); int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_out.log", node_id);
return buf; return buf;
} }
...@@ -63,27 +63,23 @@ ndbstrerror::~ndbstrerror(void) ...@@ -63,27 +63,23 @@ ndbstrerror::~ndbstrerror(void)
#define ndbstrerror strerror #define ndbstrerror strerror
#endif #endif
TCP_Transporter::TCP_Transporter(int sendBufSize, int maxRecvSize, TCP_Transporter::TCP_Transporter(TransporterRegistry &t_reg,
int portNo, int sendBufSize, int maxRecvSize,
const char *rHostName,
const char *lHostName, const char *lHostName,
NodeId rNodeId, NodeId lNodeId, const char *rHostName,
int r_port,
NodeId lNodeId,
NodeId rNodeId,
int byte_order, int byte_order,
bool compr, bool chksm, bool signalId, bool compr, bool chksm, bool signalId,
Uint32 _reportFreq) : Uint32 _reportFreq) :
Transporter(lNodeId, rNodeId, byte_order, compr, chksm, signalId), Transporter(t_reg, lHostName, rHostName, r_port, lNodeId, rNodeId,
m_sendBuffer(sendBufSize), byte_order, compr, chksm, signalId),
isServer(lNodeId < rNodeId), m_sendBuffer(sendBufSize)
port(portNo)
{ {
maxReceiveSize = maxRecvSize; maxReceiveSize = maxRecvSize;
strncpy(remoteHostName, rHostName, sizeof(remoteHostName));
// Initialize member variables // Initialize member variables
Ndb_getInAddr(&remoteHostAddress, rHostName);
Ndb_getInAddr(&localHostAddress, lHostName);
theSocket = NDB_INVALID_SOCKET; theSocket = NDB_INVALID_SOCKET;
sendCount = receiveCount = 0; sendCount = receiveCount = 0;
...@@ -108,6 +104,24 @@ TCP_Transporter::~TCP_Transporter() { ...@@ -108,6 +104,24 @@ TCP_Transporter::~TCP_Transporter() {
receiveBuffer.destroy(); receiveBuffer.destroy();
} }
bool TCP_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd)
{
return connect_common(sockfd);
}
bool TCP_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd)
{
return connect_common(sockfd);
}
bool TCP_Transporter::connect_common(NDB_SOCKET_TYPE sockfd)
{
theSocket = sockfd;
setSocketOptions();
setSocketNonBlocking(theSocket);
return true;
}
bool bool
TCP_Transporter::initTransporter() { TCP_Transporter::initTransporter() {
...@@ -316,7 +330,7 @@ TCP_Transporter::doSend() { ...@@ -316,7 +330,7 @@ TCP_Transporter::doSend() {
sendCount ++; sendCount ++;
sendSize += nBytesSent; sendSize += nBytesSent;
if(sendCount == reportFreq){ if(sendCount == reportFreq){
reportSendLen(callbackObj,remoteNodeId, sendCount, sendSize); reportSendLen(get_callback_obj(), remoteNodeId, sendCount, sendSize);
sendCount = 0; sendCount = 0;
sendSize = 0; sendSize = 0;
} }
...@@ -331,7 +345,7 @@ TCP_Transporter::doSend() { ...@@ -331,7 +345,7 @@ TCP_Transporter::doSend() {
#endif #endif
if(DISCONNECT_ERRNO(InetErrno, nBytesSent)){ if(DISCONNECT_ERRNO(InetErrno, nBytesSent)){
doDisconnect(); doDisconnect();
reportDisconnect(callbackObj, remoteNodeId, InetErrno); report_disconnect(InetErrno);
} }
return false; return false;
...@@ -361,14 +375,15 @@ TCP_Transporter::doReceive() { ...@@ -361,14 +375,15 @@ TCP_Transporter::doReceive() {
#endif #endif
ndbout_c("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)", ndbout_c("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)",
receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer); receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer);
reportError(callbackObj, remoteNodeId, TE_INVALID_MESSAGE_LENGTH); report_error(TE_INVALID_MESSAGE_LENGTH);
return 0; return 0;
} }
receiveCount ++; receiveCount ++;
receiveSize += nBytesRead; receiveSize += nBytesRead;
if(receiveCount == reportFreq){ if(receiveCount == reportFreq){
reportReceiveLen(callbackObj, remoteNodeId, receiveCount, receiveSize); reportReceiveLen(get_callback_obj(), remoteNodeId, receiveCount, receiveSize);
receiveCount = 0; receiveCount = 0;
receiveSize = 0; receiveSize = 0;
} }
...@@ -384,60 +399,17 @@ TCP_Transporter::doReceive() { ...@@ -384,60 +399,17 @@ TCP_Transporter::doReceive() {
if(DISCONNECT_ERRNO(InetErrno, nBytesRead)){ if(DISCONNECT_ERRNO(InetErrno, nBytesRead)){
// The remote node has closed down // The remote node has closed down
doDisconnect(); doDisconnect();
reportDisconnect(callbackObj, remoteNodeId,InetErrno); report_disconnect(InetErrno);
} }
} }
return nBytesRead; return nBytesRead;
} }
bool
TCP_Transporter::connectImpl(Uint32 timeOutMillis){
struct timeval timeout = {0, 0};
timeout.tv_sec = timeOutMillis / 1000;
timeout.tv_usec = (timeOutMillis % 1000)*1000;
bool retVal = false;
if(isServer){
if(theSocket == NDB_INVALID_SOCKET){
startTCPServer();
}
if(theSocket == NDB_INVALID_SOCKET)
{
NdbSleep_MilliSleep(timeOutMillis);
return false;
}
retVal = acceptClient(&timeout);
} else {
// Is client
retVal = connectClient(&timeout);
}
if(!retVal) {
NdbSleep_MilliSleep(timeOutMillis);
return false;
}
#if defined NDB_OSE || defined NDB_SOFTOSE
if(setsockopt(theSocket, SOL_SOCKET, SO_OSEOWNER,
&theReceiverPid, sizeof(PROCESS)) != 0){
ndbout << "Failed to transfer ownership of socket" << endl;
NDB_CLOSE_SOCKET(theSocket);
theSocket = -1;
return false;
}
#endif
return true;
}
void void
TCP_Transporter::disconnectImpl() { TCP_Transporter::disconnectImpl() {
if(theSocket != NDB_INVALID_SOCKET){ if(theSocket != NDB_INVALID_SOCKET){
if(NDB_CLOSE_SOCKET(theSocket) < 0){ if(NDB_CLOSE_SOCKET(theSocket) < 0){
reportError(callbackObj, remoteNodeId, TE_ERROR_CLOSING_SOCKET); report_error(TE_ERROR_CLOSING_SOCKET);
} }
} }
...@@ -447,155 +419,3 @@ TCP_Transporter::disconnectImpl() { ...@@ -447,155 +419,3 @@ TCP_Transporter::disconnectImpl() {
theSocket = NDB_INVALID_SOCKET; theSocket = NDB_INVALID_SOCKET;
} }
bool
TCP_Transporter::startTCPServer() {
int bindResult, listenResult;
// The server variable is the remote server when we are a client
// htonl and htons returns the parameter in network byte order
// INADDR_ANY tells the OS kernel to choose the IP address
struct sockaddr_in server;
memset((void*)&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = localHostAddress.s_addr;
server.sin_port = htons(port);
if (theSocket != NDB_INVALID_SOCKET) {
return true; // Server socket is already initialized
}
// Create the socket
theSocket = socket(AF_INET, SOCK_STREAM, 0);
if (theSocket == NDB_INVALID_SOCKET) {
reportThreadError(remoteNodeId, TE_COULD_NOT_CREATE_SOCKET);
return false;
}
// Set the socket reuse addr to true, so we are sure we can bind the
// socket
int reuseAddr = 1;
setsockopt(theSocket, SOL_SOCKET, SO_REUSEADDR,
(char*)&reuseAddr, sizeof(reuseAddr));
// Set the TCP_NODELAY option so also small packets are sent
// as soon as possible
int nodelay = 1;
setsockopt(theSocket, IPPROTO_TCP, TCP_NODELAY,
(char*)&nodelay, sizeof(nodelay));
// Bind the socket
bindResult = bind(theSocket, (struct sockaddr *) &server,
sizeof(server));
if (bindResult < 0) {
reportThreadError(remoteNodeId, TE_COULD_NOT_BIND_SOCKET);
NDB_CLOSE_SOCKET(theSocket);
theSocket = NDB_INVALID_SOCKET;
return false;
}
// Perform listen.
listenResult = listen(theSocket, 1);
if (listenResult == 1) {
reportThreadError(remoteNodeId, TE_LISTEN_FAILED);
NDB_CLOSE_SOCKET(theSocket);
theSocket = NDB_INVALID_SOCKET;
return false;
}
return true;
}
bool
TCP_Transporter::acceptClient (struct timeval * timeout){
struct sockaddr_in clientAddress;
fd_set readset;
FD_ZERO(&readset);
FD_SET(theSocket, &readset);
const int res = select(theSocket + 1, &readset, 0, 0, timeout);
if(res == 0)
return false;
if(res < 0){
reportThreadError(remoteNodeId, TE_ERROR_IN_SELECT_BEFORE_ACCEPT);
return false;
}
NDB_SOCKLEN_T clientAddressLen = sizeof(clientAddress);
const NDB_SOCKET_TYPE clientSocket = accept(theSocket,
(struct sockaddr*)&clientAddress,
&clientAddressLen);
if (clientSocket == NDB_INVALID_SOCKET) {
reportThreadError(remoteNodeId, TE_ACCEPT_RETURN_ERROR);
return false;
}
if (clientAddress.sin_addr.s_addr != remoteHostAddress.s_addr) {
ndbout_c("Wrong client connecting!");
ndbout_c("connecting address: %s", inet_ntoa(clientAddress.sin_addr));
ndbout_c("expecting address: %s", inet_ntoa(remoteHostAddress));
// The newly connected host is not the remote host
// we wanted to connect to. Disconnect it.
// XXX This is not valid. We cannot disconnect it.
NDB_CLOSE_SOCKET(clientSocket);
return false;
} else {
NDB_CLOSE_SOCKET(theSocket);
theSocket = clientSocket;
setSocketOptions();
setSocketNonBlocking(theSocket);
return true;
}
}
bool
TCP_Transporter::connectClient (struct timeval * timeout){
// Create the socket
theSocket = socket(AF_INET, SOCK_STREAM, 0);
if (theSocket == NDB_INVALID_SOCKET) {
reportThreadError(remoteNodeId, TE_COULD_NOT_CREATE_SOCKET);
return false;
}
struct sockaddr_in server;
memset((void*)&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr = remoteHostAddress;
server.sin_port = htons(port);
struct sockaddr_in client;
memset((void*)&client, 0, sizeof(client));
client.sin_family = AF_INET;
client.sin_addr = localHostAddress;
client.sin_port = 0; // Any port
// Bind the socket
const int bindResult = bind(theSocket, (struct sockaddr *) &client,
sizeof(client));
if (bindResult < 0) {
reportThreadError(remoteNodeId, TE_COULD_NOT_BIND_SOCKET);
NDB_CLOSE_SOCKET(theSocket);
theSocket = NDB_INVALID_SOCKET;
return false;
}
const int connectRes = ::connect(theSocket, (struct sockaddr *) &server,
sizeof(server));
if(connectRes == 0){
setSocketOptions();
setSocketNonBlocking(theSocket);
return true;
}
NDB_CLOSE_SOCKET(theSocket);
theSocket = NDB_INVALID_SOCKET;
return false;
}
...@@ -14,24 +14,8 @@ ...@@ -14,24 +14,8 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
//**************************************************************************** #ifndef TCP_TRANSPORTER_HPP
// #define TCP_TRANSPORTER_HPP
// AUTHOR
// sa Fransson
//
// NAME
// TCP_Transporter
//
// DESCRIPTION
// A TCP_Transporter instance is created when TCP/IP-communication
// shall be used (user specified). It handles connect, disconnect,
// send and receive.
//
//
//
//***************************************************************************/
#ifndef TCP_Transporter_H
#define TCP_Transporter_H
#include "Transporter.hpp" #include "Transporter.hpp"
#include "SendBuffer.hpp" #include "SendBuffer.hpp"
...@@ -61,11 +45,13 @@ class TCP_Transporter : public Transporter { ...@@ -61,11 +45,13 @@ class TCP_Transporter : public Transporter {
friend class TransporterRegistry; friend class TransporterRegistry;
private: private:
// Initialize member variables // Initialize member variables
TCP_Transporter(int sendBufferSize, int maxReceiveSize, TCP_Transporter(TransporterRegistry&,
int port, int sendBufferSize, int maxReceiveSize,
const char *rHostName,
const char *lHostName, const char *lHostName,
NodeId rHostId, NodeId lHostId, const char *rHostName,
int r_port,
NodeId lHostId,
NodeId rHostId,
int byteorder, int byteorder,
bool compression, bool checksum, bool signalId, bool compression, bool checksum, bool signalId,
Uint32 reportFreq = 4096); Uint32 reportFreq = 4096);
...@@ -121,12 +107,14 @@ protected: ...@@ -121,12 +107,14 @@ protected:
* A client connects to the remote server * A client connects to the remote server
* A server accepts any new connections * A server accepts any new connections
*/ */
bool connectImpl(Uint32 timeOutMillis); virtual bool connect_server_impl(NDB_SOCKET_TYPE sockfd);
virtual bool connect_client_impl(NDB_SOCKET_TYPE sockfd);
bool connect_common(NDB_SOCKET_TYPE sockfd);
/** /**
* Disconnects a TCP/IP node. Empty send and receivebuffer. * Disconnects a TCP/IP node. Empty send and receivebuffer.
*/ */
void disconnectImpl(); virtual void disconnectImpl();
private: private:
/** /**
...@@ -134,21 +122,11 @@ private: ...@@ -134,21 +122,11 @@ private:
*/ */
SendBuffer m_sendBuffer; SendBuffer m_sendBuffer;
const bool isServer;
const unsigned int port;
// Sending/Receiving socket used by both client and server // Sending/Receiving socket used by both client and server
NDB_SOCKET_TYPE theSocket; NDB_SOCKET_TYPE theSocket;
Uint32 maxReceiveSize; Uint32 maxReceiveSize;
/**
* Remote host name/and address
*/
char remoteHostName[256];
struct in_addr remoteHostAddress;
struct in_addr localHostAddress;
/** /**
* Socket options * Socket options
*/ */
...@@ -163,43 +141,6 @@ private: ...@@ -163,43 +141,6 @@ private:
bool sendIsPossible(struct timeval * timeout); bool sendIsPossible(struct timeval * timeout);
/**
* startTCPServer - None blocking
*
* create a server socket
* bind
* listen
*
* Note: Does not call accept
*/
bool startTCPServer();
/**
* acceptClient - Blocking
*
* Accept a connection
* checks if "right" client has connected
* if so
* close server socket
* else
* close newly created socket and goto begin
*/
bool acceptClient(struct timeval * timeout);
/**
* Creates a client socket
*
* Note does not call connect
*/
bool createClientSocket();
/**
* connectClient - Blocking
*
* connects to remote host
*/
bool connectClient(struct timeval * timeout);
/** /**
* Statistics * Statistics
*/ */
......
...@@ -15,132 +15,122 @@ ...@@ -15,132 +15,122 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <TransporterRegistry.hpp>
#include <TransporterCallback.hpp>
#include "Transporter.hpp" #include "Transporter.hpp"
#include "TransporterInternalDefinitions.hpp" #include "TransporterInternalDefinitions.hpp"
#include <NdbSleep.h> #include <NdbSleep.h>
#include <SocketAuthenticator.hpp>
Transporter::Transporter(NodeId lNodeId, NodeId rNodeId, #include <InputStream.hpp>
#include <OutputStream.hpp>
Transporter::Transporter(TransporterRegistry &t_reg,
const char *lHostName,
const char *rHostName,
int r_port,
NodeId lNodeId,
NodeId rNodeId,
int _byteorder, int _byteorder,
bool _compression, bool _checksum, bool _signalId) bool _compression, bool _checksum, bool _signalId)
: localNodeId(lNodeId), remoteNodeId(rNodeId), : m_r_port(r_port), localNodeId(lNodeId), remoteNodeId(rNodeId),
m_packer(_signalId, _checksum) isServer(lNodeId < rNodeId),
m_packer(_signalId, _checksum),
m_transporter_registry(t_reg)
{ {
if (rHostName && strlen(rHostName) > 0){
strncpy(remoteHostName, rHostName, sizeof(remoteHostName));
Ndb_getInAddr(&remoteHostAddress, rHostName);
}
else
{
if (!isServer) {
ndbout << "Unable to setup transporter. Node " << rNodeId
<< " must have hostname. Update configuration." << endl;
exit(-1);
}
remoteHostName[0]= 0;
}
strncpy(localHostName, lHostName, sizeof(localHostName));
if (strlen(lHostName) > 0)
Ndb_getInAddr(&localHostAddress, lHostName);
byteOrder = _byteorder; byteOrder = _byteorder;
compressionUsed = _compression; compressionUsed = _compression;
checksumUsed = _checksum; checksumUsed = _checksum;
signalIdUsed = _signalId; signalIdUsed = _signalId;
_threadError = TE_NO_ERROR; m_connected = false;
m_timeOutMillis = 1000;
_connecting = false; if (isServer)
_disconnecting = false; m_socket_client= 0;
_connected = false; else
_timeOutMillis = 1000; m_socket_client= new SocketClient(remoteHostName, r_port,
theThreadPtr = NULL; new SocketAuthSimple("ndbd", "ndbd passwd"));
theMutexPtr = NdbMutex_Create();
} }
Transporter::~Transporter(){ Transporter::~Transporter(){
NdbMutex_Destroy(theMutexPtr); if (m_socket_client)
delete m_socket_client;
if(theThreadPtr != 0){
void * retVal;
NdbThread_WaitFor(theThreadPtr, &retVal);
NdbThread_Destroy(&theThreadPtr);
}
}
extern "C"
void *
runConnect_C(void * me)
{
runConnect(me);
NdbThread_Exit(0);
return NULL;
} }
void * bool
runConnect(void * me){ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
Transporter * t = (Transporter *) me; if(m_connected)
return true; // TODO assert(0);
DEBUG("Connect thread to " << t->remoteNodeId << " started");
while(true){
NdbMutex_Lock(t->theMutexPtr);
if(t->_disconnecting){
t->_connecting = false;
NdbMutex_Unlock(t->theMutexPtr);
DEBUG("Connect Thread " << t->remoteNodeId << " stop due to disconnect");
return 0;
}
NdbMutex_Unlock(t->theMutexPtr);
bool res = t->connectImpl(t->_timeOutMillis); // 1000 ms bool res = connect_server_impl(sockfd);
DEBUG("Waiting for " << t->remoteNodeId << "...");
if(res){ if(res){
t->_connected = true; m_connected = true;
t->_connecting = false; m_errorCount = 0;
t->_errorCount = 0;
t->_threadError = TE_NO_ERROR;
DEBUG("Connect Thread " << t->remoteNodeId << " stop due to connect");
return 0;
} }
}
}
void
Transporter::doConnect() {
NdbMutex_Lock(theMutexPtr); return res;
if(_connecting || _disconnecting || _connected){ }
NdbMutex_Unlock(theMutexPtr);
return;
}
_connecting = true; bool
Transporter::connect_client() {
if(m_connected)
return true;
_threadError = TE_NO_ERROR; NDB_SOCKET_TYPE sockfd = m_socket_client->connect();
// Start thread if (sockfd < 0)
return false;
char buf[16]; // send info about own id
snprintf(buf, sizeof(buf), "ndb_con_%d", remoteNodeId); SocketOutputStream s_output(sockfd);
s_output.println("%d", localNodeId);
if(theThreadPtr != 0){ // get remote id
void * retVal; int nodeId;
NdbThread_WaitFor(theThreadPtr, &retVal); SocketInputStream s_input(sockfd);
NdbThread_Destroy(&theThreadPtr); char buf[256];
if (s_input.gets(buf, 256) == 0) {
NDB_CLOSE_SOCKET(sockfd);
return false;
}
if (sscanf(buf, "%d", &nodeId) != 1) {
NDB_CLOSE_SOCKET(sockfd);
return false;
} }
theThreadPtr = NdbThread_Create(runConnect_C, bool res = connect_client_impl(sockfd);
(void**)this, if(res){
32768, m_connected = true;
buf, m_errorCount = 0;
NDB_THREAD_PRIO_LOW); }
return res;
NdbSleep_MilliSleep(100); // Let thread start
NdbMutex_Unlock(theMutexPtr);
} }
void void
Transporter::doDisconnect() { Transporter::doDisconnect() {
NdbMutex_Lock(theMutexPtr); if(!m_connected)
_disconnecting = true; return; //assert(0); TODO will fail
while(_connecting){
DEBUG("Waiting for connect to finish...");
NdbMutex_Unlock(theMutexPtr);
NdbSleep_MilliSleep(500);
NdbMutex_Lock(theMutexPtr);
}
_connected = false;
disconnectImpl(); disconnectImpl();
_threadError = TE_NO_ERROR;
_disconnecting = false;
NdbMutex_Unlock(theMutexPtr); m_connected= false;
} }
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
#include <ndb_global.h> #include <ndb_global.h>
#include <SocketClient.hpp>
#include <TransporterRegistry.hpp>
#include <TransporterCallback.hpp> #include <TransporterCallback.hpp>
#include "TransporterDefinitions.hpp" #include "TransporterDefinitions.hpp"
#include "Packer.hpp" #include "Packer.hpp"
...@@ -40,7 +43,8 @@ public: ...@@ -40,7 +43,8 @@ public:
* None blocking * None blocking
* Use isConnected() to check status * Use isConnected() to check status
*/ */
virtual void doConnect(); bool connect_client();
bool connect_server(NDB_SOCKET_TYPE socket);
/** /**
* Blocking * Blocking
...@@ -60,14 +64,17 @@ public: ...@@ -60,14 +64,17 @@ public:
*/ */
NodeId getRemoteNodeId() const; NodeId getRemoteNodeId() const;
/** /**
* Set callback object * Local (own) Node Id
*/ */
void setCallbackObject(void * callback); NodeId getLocalNodeId() const;
protected: protected:
Transporter(NodeId lNodeId, Transporter(TransporterRegistry &,
const char *lHostName,
const char *rHostName,
int r_port,
NodeId lNodeId,
NodeId rNodeId, NodeId rNodeId,
int byteorder, int byteorder,
bool compression, bool compression,
...@@ -78,15 +85,28 @@ protected: ...@@ -78,15 +85,28 @@ protected:
* Blocking, for max timeOut milli seconds * Blocking, for max timeOut milli seconds
* Returns true if connect succeded * Returns true if connect succeded
*/ */
virtual bool connectImpl(Uint32 timeOut) = 0; virtual bool connect_server_impl(NDB_SOCKET_TYPE sockfd) = 0;
virtual bool connect_client_impl(NDB_SOCKET_TYPE sockfd) = 0;
/** /**
* Blocking * Blocking
*/ */
virtual void disconnectImpl() = 0; virtual void disconnectImpl() = 0;
const NodeId localNodeId; /**
* Remote host name/and address
*/
char remoteHostName[256];
char localHostName[256];
struct in_addr remoteHostAddress;
struct in_addr localHostAddress;
const unsigned int m_r_port;
const NodeId remoteNodeId; const NodeId remoteNodeId;
const NodeId localNodeId;
const bool isServer;
unsigned createIndex; unsigned createIndex;
...@@ -96,40 +116,28 @@ protected: ...@@ -96,40 +116,28 @@ protected:
bool signalIdUsed; bool signalIdUsed;
Packer m_packer; Packer m_packer;
private: private:
/**
* Thread and mutex for connect SocketClient *m_socket_client;
*/
NdbThread* theThreadPtr;
friend void* runConnect(void * me);
protected: protected:
/**
* Error reporting from connect thread(s)
*/
void reportThreadError(NodeId nodeId,
TransporterError errorCode);
Uint32 getErrorCount(); Uint32 getErrorCount();
TransporterError getThreadError(); Uint32 m_errorCount;
void resetThreadError(); Uint32 m_timeOutMillis;
TransporterError _threadError;
Uint32 _timeOutMillis;
Uint32 _errorCount;
protected: protected:
NdbMutex* theMutexPtr; bool m_connected; // Are we connected
bool _connected; // Are we connected
bool _connecting; // Connect thread is running
bool _disconnecting; // We are disconnecting
void * callbackObj; TransporterRegistry &m_transporter_registry;
void *get_callback_obj() { return m_transporter_registry.callbackObj; };
void report_disconnect(int err){m_transporter_registry.report_disconnect(remoteNodeId,err);};
void report_error(enum TransporterError err){reportError(get_callback_obj(),remoteNodeId,err);};
}; };
inline inline
bool bool
Transporter::isConnected() const { Transporter::isConnected() const {
return _connected; return m_connected;
} }
inline inline
...@@ -139,41 +147,16 @@ Transporter::getRemoteNodeId() const { ...@@ -139,41 +147,16 @@ Transporter::getRemoteNodeId() const {
} }
inline inline
void NodeId
Transporter::reportThreadError(NodeId nodeId, TransporterError errorCode) Transporter::getLocalNodeId() const {
{ return remoteNodeId;
#if 0
ndbout_c("Transporter::reportThreadError (NodeId: %d, Error code: %d)",
nodeId, errorCode);
#endif
_threadError = errorCode;
_errorCount++;
}
inline
TransporterError
Transporter::getThreadError(){
return _threadError;
} }
inline inline
Uint32 Uint32
Transporter::getErrorCount() Transporter::getErrorCount()
{ {
return _errorCount; return m_errorCount;
}
inline
void
Transporter::resetThreadError()
{
_threadError = TE_NO_ERROR;
}
inline
void
Transporter::setCallbackObject(void * callback) {
callbackObj = callback;
} }
#endif // Define of Transporter_H #endif // Define of Transporter_H
...@@ -3,7 +3,8 @@ noinst_LTLIBRARIES = libgeneral.la ...@@ -3,7 +3,8 @@ noinst_LTLIBRARIES = libgeneral.la
libgeneral_la_SOURCES = \ libgeneral_la_SOURCES = \
File.cpp md5_hash.cpp Properties.cpp socket_io.cpp \ File.cpp md5_hash.cpp Properties.cpp socket_io.cpp \
SimpleProperties.cpp Parser.cpp InputStream.cpp SocketServer.cpp \ SimpleProperties.cpp Parser.cpp InputStream.cpp \
SocketServer.cpp SocketClient.cpp SocketAuthenticator.cpp\
OutputStream.cpp NdbOut.cpp BaseString.cpp Base64.cpp \ OutputStream.cpp NdbOut.cpp BaseString.cpp Base64.cpp \
NdbSqlUtil.cpp new.cpp \ NdbSqlUtil.cpp new.cpp \
uucode.c random.c getarg.c version.c \ uucode.c random.c getarg.c version.c \
......
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <ndb_global.h>
#include <SocketClient.hpp>
#include <SocketAuthenticator.hpp>
#include <InputStream.hpp>
#include <OutputStream.hpp>
#include <NdbOut.hpp>
SocketAuthSimple::SocketAuthSimple(const char *username, const char *passwd) {
if (username)
m_username= strdup(username);
else
m_username= 0;
if (passwd)
m_passwd= strdup(passwd);
else
m_passwd= 0;
}
SocketAuthSimple::~SocketAuthSimple()
{
if (m_passwd)
free((void*)m_passwd);
if (m_username)
free((void*)m_username);
}
bool SocketAuthSimple::client_authenticate(int sockfd)
{
SocketOutputStream s_output(sockfd);
SocketInputStream s_input(sockfd);
if (m_username)
s_output.println("%s", m_username);
else
s_output.println("");
if (m_passwd)
s_output.println("%s", m_passwd);
else
s_output.println("");
char buf[16];
if (s_input.gets(buf, 16) == 0) return false;
if (strncmp("ok", buf, 2) == 0)
return true;
return false;
}
bool SocketAuthSimple::server_authenticate(int sockfd)
{
SocketOutputStream s_output(sockfd);
SocketInputStream s_input(sockfd);
char buf[256];
if (s_input.gets(buf, 256) == 0) return false;
buf[255]= 0;
if (m_username)
free((void*)m_username);
m_username= strdup(buf);
if (s_input.gets(buf, 256) == 0) return false;
buf[255]= 0;
if (m_passwd)
free((void*)m_passwd);
m_passwd= strdup(buf);
s_output.println("ok");
return true;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <ndb_global.h>
#include <NdbOut.hpp>
#include <SocketClient.hpp>
#include <SocketAuthenticator.hpp>
SocketClient::SocketClient(const char *server_name, unsigned short port, SocketAuthenticator *sa)
{
m_auth= sa;
m_port= port;
m_server_name= strdup(server_name);
m_sockfd= -1;
}
SocketClient::~SocketClient()
{
if (m_server_name)
free(m_server_name);
if (m_sockfd >= 0)
NDB_CLOSE_SOCKET(m_sockfd);
if (m_auth)
delete m_auth;
}
bool
SocketClient::init()
{
if (m_sockfd >= 0)
NDB_CLOSE_SOCKET(m_sockfd);
memset(&m_servaddr, 0, sizeof(m_servaddr));
m_servaddr.sin_family = AF_INET;
m_servaddr.sin_port = htons(m_port);
// Convert ip address presentation format to numeric format
if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name))
return false;
m_sockfd= socket(AF_INET, SOCK_STREAM, 0);
if (m_sockfd == NDB_INVALID_SOCKET) {
return false;
}
return true;
}
NDB_SOCKET_TYPE
SocketClient::connect()
{
if (m_sockfd < 0)
{
if (!init()) {
ndbout << "SocketClient::connect() failed " << m_server_name << " " << m_port << endl;
return -1;
}
}
const int r = ::connect(m_sockfd, (struct sockaddr*) &m_servaddr, sizeof(m_servaddr));
if (r == -1)
return -1;
if (m_auth)
if (!m_auth->client_authenticate(m_sockfd))
{
NDB_CLOSE_SOCKET(m_sockfd);
m_sockfd= -1;
return -1;
}
NDB_SOCKET_TYPE sockfd= m_sockfd;
m_sockfd= -1;
return sockfd;
}
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <ndb_global.h> #include <ndb_global.h>
#include "SocketServer.hpp" #include <SocketServer.hpp>
#include <NdbTCP.h> #include <NdbTCP.h>
#include <NdbOut.hpp> #include <NdbOut.hpp>
......
...@@ -4,7 +4,7 @@ include $(top_srcdir)/ndb/config/common.mk.am ...@@ -4,7 +4,7 @@ include $(top_srcdir)/ndb/config/common.mk.am
ndbbin_PROGRAMS = ndbd ndbbin_PROGRAMS = ndbd
ndbd_SOURCES = Main.cpp SimBlockList.cpp ndbd_SOURCES = main.cpp SimBlockList.cpp
include $(top_srcdir)/ndb/config/type_kernel.mk.am include $(top_srcdir)/ndb/config/type_kernel.mk.am
......
...@@ -362,7 +362,7 @@ void Cmvmi::execCLOSE_COMREQ(Signal* signal) ...@@ -362,7 +362,7 @@ void Cmvmi::execCLOSE_COMREQ(Signal* signal)
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
globalTransporterRegistry.setIOState(i, HaltIO); globalTransporterRegistry.setIOState(i, HaltIO);
globalTransporterRegistry.setPerformState(i, PerformDisconnect); globalTransporterRegistry.do_disconnect(i);
/** /**
* Cancel possible event subscription * Cancel possible event subscription
...@@ -390,7 +390,7 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal) ...@@ -390,7 +390,7 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal)
const Uint32 len = signal->getLength(); const Uint32 len = signal->getLength();
if(len == 2){ if(len == 2){
globalTransporterRegistry.setPerformState(tStartingNode, PerformConnect); globalTransporterRegistry.do_connect(tStartingNode);
globalTransporterRegistry.setIOState(tStartingNode, HaltIO); globalTransporterRegistry.setIOState(tStartingNode, HaltIO);
//----------------------------------------------------- //-----------------------------------------------------
...@@ -405,7 +405,7 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal) ...@@ -405,7 +405,7 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal)
jam(); jam();
if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2){ if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2){
jam(); jam();
globalTransporterRegistry.setPerformState(i, PerformConnect); globalTransporterRegistry.do_connect(i);
globalTransporterRegistry.setIOState(i, HaltIO); globalTransporterRegistry.setIOState(i, HaltIO);
signal->theData[0] = EventReport::CommunicationOpened; signal->theData[0] = EventReport::CommunicationOpened;
...@@ -456,14 +456,6 @@ void Cmvmi::execDISCONNECT_REP(Signal *signal) ...@@ -456,14 +456,6 @@ void Cmvmi::execDISCONNECT_REP(Signal *signal)
const NodeInfo::NodeType type = getNodeInfo(hostId).getType(); const NodeInfo::NodeType type = getNodeInfo(hostId).getType();
ndbrequire(type != NodeInfo::INVALID); ndbrequire(type != NodeInfo::INVALID);
if (globalTransporterRegistry.performState(hostId) != PerformDisconnect) {
jam();
// -------------------------------------------------------------------
// We do not report the disconnection when disconnection is already ongoing.
// This reporting should be looked into but this secures that we avoid
// crashes due to too quick re-reporting of disconnection.
// -------------------------------------------------------------------
if(type == NodeInfo::DB || globalData.theStartLevel == NodeState::SL_STARTED){ if(type == NodeInfo::DB || globalData.theStartLevel == NodeState::SL_STARTED){
jam(); jam();
DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0]; DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0];
...@@ -471,19 +463,14 @@ void Cmvmi::execDISCONNECT_REP(Signal *signal) ...@@ -471,19 +463,14 @@ void Cmvmi::execDISCONNECT_REP(Signal *signal)
rep->err = errNo; rep->err = errNo;
sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal, sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal,
DisconnectRep::SignalLength, JBA); DisconnectRep::SignalLength, JBA);
globalTransporterRegistry.setPerformState(hostId, PerformDisconnect); } else if((globalData.theStartLevel == NodeState::SL_CMVMI ||
} else if(globalData.theStartLevel == NodeState::SL_CMVMI || globalData.theStartLevel == NodeState::SL_STARTING)
globalData.theStartLevel == NodeState::SL_STARTING) { && type == NodeInfo::MGM) {
/** /**
* Someone disconnected during cmvmi period * Someone disconnected during cmvmi period
*/ */
if(type == NodeInfo::MGM){
jam(); jam();
globalTransporterRegistry.setPerformState(hostId, PerformConnect); globalTransporterRegistry.do_connect(hostId);
} else {
globalTransporterRegistry.setPerformState(hostId, PerformDisconnect);
}
}
} }
signal->theData[0] = EventReport::Disconnected; signal->theData[0] = EventReport::Disconnected;
...@@ -522,7 +509,8 @@ void Cmvmi::execCONNECT_REP(Signal *signal){ ...@@ -522,7 +509,8 @@ void Cmvmi::execCONNECT_REP(Signal *signal){
/** /**
* Dont allow api nodes to connect * Dont allow api nodes to connect
*/ */
globalTransporterRegistry.setPerformState(hostId, PerformDisconnect); abort();
globalTransporterRegistry.do_disconnect(hostId);
} }
} }
...@@ -756,8 +744,8 @@ Cmvmi::execSTART_ORD(Signal* signal) { ...@@ -756,8 +744,8 @@ Cmvmi::execSTART_ORD(Signal* signal) {
*/ */
for(unsigned int i = 1; i < MAX_NODES; i++ ){ for(unsigned int i = 1; i < MAX_NODES; i++ ){
if (getNodeInfo(i).m_type == NodeInfo::MGM){ if (getNodeInfo(i).m_type == NodeInfo::MGM){
if(globalTransporterRegistry.performState(i) != PerformIO){ if(!globalTransporterRegistry.is_connected(i)){
globalTransporterRegistry.setPerformState(i, PerformConnect); globalTransporterRegistry.do_connect(i);
globalTransporterRegistry.setIOState(i, NoHalt); globalTransporterRegistry.setIOState(i, NoHalt);
} }
} }
...@@ -783,7 +771,7 @@ Cmvmi::execSTART_ORD(Signal* signal) { ...@@ -783,7 +771,7 @@ Cmvmi::execSTART_ORD(Signal* signal) {
// without any connected nodes. // without any connected nodes.
for(unsigned int i = 1; i < MAX_NODES; i++ ){ for(unsigned int i = 1; i < MAX_NODES; i++ ){
if (i != getOwnNodeId() && getNodeInfo(i).m_type != NodeInfo::MGM){ if (i != getOwnNodeId() && getNodeInfo(i).m_type != NodeInfo::MGM){
globalTransporterRegistry.setPerformState(i, PerformDisconnect); globalTransporterRegistry.do_disconnect(i);
globalTransporterRegistry.setIOState(i, HaltIO); globalTransporterRegistry.setIOState(i, HaltIO);
} }
} }
...@@ -1062,29 +1050,10 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) ...@@ -1062,29 +1050,10 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal)
if(nodeTypeStr == 0) if(nodeTypeStr == 0)
continue; continue;
const char* actionStr = "";
switch (globalTransporterRegistry.performState(i)){
case PerformNothing:
actionStr = "does nothing";
break;
case PerformIO:
actionStr = "is connected";
break;
case PerformConnect:
actionStr = "is trying to connect";
break;
case PerformDisconnect:
actionStr = "is trying to disconnect";
break;
case RemoveTransporter:
actionStr = "will be removed";
break;
}
infoEvent("Connection to %d (%s) %s", infoEvent("Connection to %d (%s) %s",
i, i,
nodeTypeStr, nodeTypeStr,
actionStr); globalTransporterRegistry.getPerformStateString(i));
} }
} }
......
...@@ -1704,6 +1704,7 @@ void Qmgr::sendApiFailReq(Signal* signal, Uint16 failedNodeNo) ...@@ -1704,6 +1704,7 @@ void Qmgr::sendApiFailReq(Signal* signal, Uint16 failedNodeNo)
sendSignal(DBTC_REF, GSN_API_FAILREQ, signal, 2, JBA); sendSignal(DBTC_REF, GSN_API_FAILREQ, signal, 2, JBA);
sendSignal(DBDICT_REF, GSN_API_FAILREQ, signal, 2, JBA); sendSignal(DBDICT_REF, GSN_API_FAILREQ, signal, 2, JBA);
sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA); sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA);
/** /**
* GREP also need the information that an API node * GREP also need the information that an API node
* (actually a REP node) has failed. * (actually a REP node) has failed.
...@@ -1978,6 +1979,8 @@ void Qmgr::execAPI_REGREQ(Signal* signal) ...@@ -1978,6 +1979,8 @@ void Qmgr::execAPI_REGREQ(Signal* signal)
apiRegConf->nodeState.dynamicId = -dynamicId; apiRegConf->nodeState.dynamicId = -dynamicId;
} }
} }
apiRegConf->nodeState.m_connected_nodes.assign(c_connectedNodes);
sendSignal(ref, GSN_API_REGCONF, signal, ApiRegConf::SignalLength, JBB); sendSignal(ref, GSN_API_REGCONF, signal, ApiRegConf::SignalLength, JBB);
if ((getNodeState().startLevel == NodeState::SL_STARTED || if ((getNodeState().startLevel == NodeState::SL_STARTED ||
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <NdbConfig.h> #include <NdbConfig.h>
#include <Configuration.hpp> #include <Configuration.hpp>
#include <NdbAutoPtr.hpp>
#define MESSAGE_LENGTH 400 #define MESSAGE_LENGTH 400
const char* errorType[] = { const char* errorType[] = {
...@@ -66,23 +68,23 @@ ErrorReporter::formatTimeStampString(){ ...@@ -66,23 +68,23 @@ ErrorReporter::formatTimeStampString(){
return (const char *)&theDateTimeString; return (const char *)&theDateTimeString;
} }
void int
ErrorReporter::formatTraceFileName(char* theName, int maxLen){ ErrorReporter::get_trace_no(){
FILE *stream; FILE *stream;
unsigned int traceFileNo; unsigned int traceFileNo;
char fileNameBuf[255];
char buf[255];
NdbConfig_HomePath(fileNameBuf, 255); char *file_name= NdbConfig_NextTraceFileName(globalData.ownId);
strncat(fileNameBuf, "NextTraceFileNo.log", 255); NdbAutoPtr<char> tmp_aptr(file_name);
/* /*
* Read last number from tracefile * Read last number from tracefile
*/ */
stream = fopen(fileNameBuf, "r+"); stream = fopen(file_name, "r+");
if (stream == NULL){ if (stream == NULL){
traceFileNo = 1; traceFileNo = 1;
} else { } else {
char buf[255];
fgets(buf, 255, stream); fgets(buf, 255, stream);
const int scan = sscanf(buf, "%u", &traceFileNo); const int scan = sscanf(buf, "%u", &traceFileNo);
if(scan != 1){ if(scan != 1){
...@@ -103,16 +105,13 @@ ErrorReporter::formatTraceFileName(char* theName, int maxLen){ ...@@ -103,16 +105,13 @@ ErrorReporter::formatTraceFileName(char* theName, int maxLen){
/** /**
* Save new number to the file * Save new number to the file
*/ */
stream = fopen(fileNameBuf, "w"); stream = fopen(file_name, "w");
if(stream != NULL){ if(stream != NULL){
fprintf(stream, "%u", traceFileNo); fprintf(stream, "%u", traceFileNo);
fclose(stream); fclose(stream);
} }
/**
* Format trace file name return traceFileNo;
*/
snprintf(theName, maxLen, "%sNDB_TraceFile_%u.trace",
NdbConfig_HomePath(fileNameBuf, 255), traceFileNo);
} }
...@@ -214,16 +213,22 @@ WriteMessage(ErrorCategory thrdType, int thrdMessageID, ...@@ -214,16 +213,22 @@ WriteMessage(ErrorCategory thrdType, int thrdMessageID,
unsigned offset; unsigned offset;
unsigned long maxOffset; // Maximum size of file. unsigned long maxOffset; // Maximum size of file.
char theMessage[MESSAGE_LENGTH]; char theMessage[MESSAGE_LENGTH];
char theTraceFileName[255];
char theErrorFileName[255]; /**
ErrorReporter::formatTraceFileName(theTraceFileName, 255); * Format trace file name
*/
int file_no= ErrorReporter::get_trace_no();
char *theTraceFileName= NdbConfig_TraceFileName(globalData.ownId, file_no);
NdbAutoPtr<char> tmp_aptr1(theTraceFileName);
// The first 69 bytes is info about the current offset // The first 69 bytes is info about the current offset
Uint32 noMsg = globalEmulatorData.theConfiguration->maxNoOfErrorLogs(); Uint32 noMsg = globalEmulatorData.theConfiguration->maxNoOfErrorLogs();
maxOffset = (69 + (noMsg * MESSAGE_LENGTH)); maxOffset = (69 + (noMsg * MESSAGE_LENGTH));
NdbConfig_ErrorFileName(theErrorFileName, 255); char *theErrorFileName= (char *)NdbConfig_ErrorFileName(globalData.ownId);
NdbAutoPtr<char> tmp_aptr2(theErrorFileName);
stream = fopen(theErrorFileName, "r+"); stream = fopen(theErrorFileName, "r+");
if (stream == NULL) { /* If the file could not be opened. */ if (stream == NULL) { /* If the file could not be opened. */
......
...@@ -81,7 +81,7 @@ public: ...@@ -81,7 +81,7 @@ public:
const char* theNameOfTheTraceFile, const char* theNameOfTheTraceFile,
char* messptr); char* messptr);
static void formatTraceFileName(char* theName, int maxLen); static int get_trace_no();
static const char* formatTimeStampString(); static const char* formatTimeStampString();
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include "Configuration.hpp" #include "Configuration.hpp"
#include <TransporterRegistry.hpp> #include <TransporterRegistry.hpp>
#include "SimBlockList.hpp" #include "vm/SimBlockList.hpp"
#include "ThreadConfig.hpp" #include "ThreadConfig.hpp"
#include <SignalLoggerManager.hpp> #include <SignalLoggerManager.hpp>
#include <NdbOut.hpp> #include <NdbOut.hpp>
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
#include <LogLevel.hpp> #include <LogLevel.hpp>
#include <EventLogger.hpp> #include <EventLogger.hpp>
#include <NodeState.hpp>
#include <NdbAutoPtr.hpp>
#if defined NDB_SOLARIS // ok #if defined NDB_SOLARIS // ok
#include <sys/processor.h> // For system informatio #include <sys/processor.h> // For system informatio
...@@ -71,15 +72,12 @@ NDB_MAIN(ndb_kernel){ ...@@ -71,15 +72,12 @@ NDB_MAIN(ndb_kernel){
theConfig->setupConfiguration(); theConfig->setupConfiguration();
} }
// Get NDB_HOME path
char homePath[255];
NdbConfig_HomePath(homePath, 255);
if (theConfig->getDaemonMode()) { if (theConfig->getDaemonMode()) {
// Become a daemon // Become a daemon
char lockfile[255], logfile[255]; char *lockfile= NdbConfig_PidFileName(globalData.ownId);
snprintf(lockfile, 255, "%snode%d.pid", homePath, globalData.ownId); char *logfile= NdbConfig_StdoutFileName(globalData.ownId);
snprintf(logfile, 255, "%snode%d.out", homePath, globalData.ownId); NdbAutoPtr<char> tmp_aptr1(lockfile), tmp_aptr2(logfile);
if (NdbDaemon_Make(lockfile, logfile, 0) == -1) { if (NdbDaemon_Make(lockfile, logfile, 0) == -1) {
ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl; ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl;
return 1; return 1;
...@@ -90,6 +88,8 @@ NDB_MAIN(ndb_kernel){ ...@@ -90,6 +88,8 @@ NDB_MAIN(ndb_kernel){
/** /**
* Parent * Parent
*/ */
theConfig->closeConfiguration();
catchsigs(true); catchsigs(true);
int status = 0; int status = 0;
...@@ -147,9 +147,9 @@ NDB_MAIN(ndb_kernel){ ...@@ -147,9 +147,9 @@ NDB_MAIN(ndb_kernel){
#ifdef VM_TRACE #ifdef VM_TRACE
// Create a signal logger // Create a signal logger
char buf[255]; char *buf= NdbConfig_SignalLogFileName(globalData.ownId);
strcpy(buf, homePath); NdbAutoPtr<char> tmp_aptr(buf);
FILE * signalLog = fopen(strncat(buf,"Signal.log", 255), "a"); FILE * signalLog = fopen(buf, "a");
globalSignalLoggers.setOwnNodeId(globalData.ownId); globalSignalLoggers.setOwnNodeId(globalData.ownId);
globalSignalLoggers.setOutputStream(signalLog); globalSignalLoggers.setOutputStream(signalLog);
#endif #endif
...@@ -171,13 +171,31 @@ NDB_MAIN(ndb_kernel){ ...@@ -171,13 +171,31 @@ NDB_MAIN(ndb_kernel){
NDB_ASSERT(0, "Illegal state globalData.theRestartFlag"); NDB_ASSERT(0, "Illegal state globalData.theRestartFlag");
} }
SocketServer socket_server;
globalTransporterRegistry.startSending(); globalTransporterRegistry.startSending();
globalTransporterRegistry.startReceiving(); globalTransporterRegistry.startReceiving();
if (!globalTransporterRegistry.start_service(socket_server))
NDB_ASSERT(0, "globalTransporterRegistry.start_service() failed");
if (!globalTransporterRegistry.start_clients())
NDB_ASSERT(0, "globalTransporterRegistry.start_clients() failed");
globalEmulatorData.theWatchDog->doStart(); globalEmulatorData.theWatchDog->doStart();
socket_server.startServer();
// theConfig->closeConfiguration();
globalEmulatorData.theThreadConfig->ipControlLoop(); globalEmulatorData.theThreadConfig->ipControlLoop();
NdbShutdown(NST_Normal); NdbShutdown(NST_Normal);
socket_server.stopServer();
socket_server.stopSessions();
globalTransporterRegistry.stop_clients();
return NRT_Default; return NRT_Default;
} }
......
...@@ -138,6 +138,7 @@ Configuration::Configuration() ...@@ -138,6 +138,7 @@ Configuration::Configuration()
_fsPath = 0; _fsPath = 0;
_initialStart = false; _initialStart = false;
_daemonMode = false; _daemonMode = false;
m_config_retriever= 0;
} }
Configuration::~Configuration(){ Configuration::~Configuration(){
...@@ -146,6 +147,18 @@ Configuration::~Configuration(){ ...@@ -146,6 +147,18 @@ Configuration::~Configuration(){
if(_fsPath != NULL) if(_fsPath != NULL)
free(_fsPath); free(_fsPath);
if (m_config_retriever) {
delete m_config_retriever;
}
}
void
Configuration::closeConfiguration(){
if (m_config_retriever) {
delete m_config_retriever;
}
m_config_retriever= 0;
} }
void void
...@@ -153,7 +166,12 @@ Configuration::setupConfiguration(){ ...@@ -153,7 +166,12 @@ Configuration::setupConfiguration(){
/** /**
* Fetch configuration from management server * Fetch configuration from management server
*/ */
ConfigRetriever cr; if (m_config_retriever) {
delete m_config_retriever;
}
m_config_retriever= new ConfigRetriever();
ConfigRetriever &cr= *m_config_retriever;
cr.setConnectString(_connectString); cr.setConnectString(_connectString);
stopOnError(true); stopOnError(true);
ndb_mgm_configuration * p = cr.getConfig(NDB_VERSION, NODE_TYPE_DB); ndb_mgm_configuration * p = cr.getConfig(NDB_VERSION, NODE_TYPE_DB);
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <mgmapi.h> #include <mgmapi.h>
#include <ndb_types.h> #include <ndb_types.h>
class ConfigRetriever;
class Configuration { class Configuration {
public: public:
Configuration(); Configuration();
...@@ -31,6 +33,7 @@ public: ...@@ -31,6 +33,7 @@ public:
bool init(int argc, const char** argv); bool init(int argc, const char** argv);
void setupConfiguration(); void setupConfiguration();
void closeConfiguration();
bool lockPagesInMainMemory() const; bool lockPagesInMainMemory() const;
...@@ -78,6 +81,8 @@ private: ...@@ -78,6 +81,8 @@ private:
ndb_mgm_configuration_iterator * m_clusterConfigIter; ndb_mgm_configuration_iterator * m_clusterConfigIter;
ndb_mgm_configuration_iterator * m_ownConfigIterator; ndb_mgm_configuration_iterator * m_ownConfigIterator;
ConfigRetriever *m_config_retriever;
/** /**
* arguments to NDB process * arguments to NDB process
*/ */
......
...@@ -147,8 +147,8 @@ void ThreadConfig::ipControlLoop() ...@@ -147,8 +147,8 @@ void ThreadConfig::ipControlLoop()
// plus checking for any received messages. // plus checking for any received messages.
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if (i++ >= 20) { if (i++ >= 20) {
globalTransporterRegistry.update_connections();
globalData.incrementWatchDogCounter(5); globalData.incrementWatchDogCounter(5);
globalTransporterRegistry.checkConnections();
i = 0; i = 0;
}//if }//if
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <NdbOut.hpp> #include <NdbOut.hpp>
#include <SocketServer.hpp> #include <SocketServer.hpp>
#include <SocketClient.hpp>
#include <Parser.hpp> #include <Parser.hpp>
#include <OutputStream.hpp> #include <OutputStream.hpp>
#include <InputStream.hpp> #include <InputStream.hpp>
...@@ -318,8 +319,8 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply, ...@@ -318,8 +319,8 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
/** /**
* Print some info about why the parser returns NULL * Print some info about why the parser returns NULL
*/ */
// ndbout << " status=" << ctx.m_status << ", curr=" //ndbout << " status=" << ctx.m_status << ", curr="
// << ctx.m_currentToken << endl; //<< ctx.m_currentToken << endl;
} }
#ifdef MGMAPI_LOG #ifdef MGMAPI_LOG
else { else {
...@@ -362,30 +363,11 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv) ...@@ -362,30 +363,11 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv)
/** /**
* Do connect * Do connect
*/ */
const NDB_SOCKET_TYPE sockfd = socket(AF_INET, SOCK_STREAM, 0); SocketClient s(handle->hostname, handle->port);
if (sockfd == NDB_INVALID_SOCKET) { const NDB_SOCKET_TYPE sockfd = s.connect();
SET_ERROR(handle, NDB_MGM_ILLEGAL_SOCKET, ""); if (sockfd < 0) {
return -1; setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
} "Unable to connect to %s", mgmsrv);
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(handle->port);
// Convert ip address presentation format to numeric format
const int res1 = Ndb_getInAddr(&servaddr.sin_addr, handle->hostname);
if (res1 != 0) {
DEBUG("Ndb_getInAddr(...) == -1");
setError(handle, EINVAL, __LINE__, "Invalid hostname/address");
return -1;
}
const int res2 = connect(sockfd, (struct sockaddr*) &servaddr,
sizeof(servaddr));
if (res2 == -1) {
NDB_CLOSE_SOCKET(sockfd);
setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, "Unable to connect to %s",
mgmsrv);
return -1; return -1;
} }
...@@ -1523,6 +1505,55 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) { ...@@ -1523,6 +1505,55 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
return 0; return 0;
} }
extern "C"
int
ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, unsigned *pnodeid, int nodetype)
{
CHECK_HANDLE(handle, 0);
CHECK_CONNECTED(handle, 0);
Properties args;
args.put("version", version);
args.put("nodetype", nodetype);
args.put("nodeid", *pnodeid);
args.put("user", "mysqld");
args.put("password", "mysqld");
args.put("public key", "a public key");
const ParserRow<ParserDummy> reply[]= {
MGM_CMD("get nodeid reply", NULL, ""),
MGM_ARG("nodeid", Int, Optional, "Error message"),
MGM_ARG("result", String, Mandatory, "Error message"),
MGM_END()
};
const Properties *prop;
prop= ndb_mgm_call(handle, reply, "get nodeid", &args);
if(prop == NULL) {
SET_ERROR(handle, EIO, "Unable to alloc nodeid");
return -1;
}
int res= -1;
do {
const char * buf;
if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
ndbout_c("ERROR Message: %s\n", buf);
break;
}
if(!prop->get("nodeid", pnodeid) != 0){
ndbout_c("ERROR Message: <nodeid Unspecified>\n");
break;
}
res= 0;
}while(0);
delete prop;
return res;
}
/***************************************************************************** /*****************************************************************************
* Global Replication * Global Replication
******************************************************************************/ ******************************************************************************/
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <signal.h> #include <signal.h>
const char *progname = "mgmtclient"; const char *progname = "ndb_mgm";
static CommandInterpreter* com; static CommandInterpreter* com;
...@@ -47,7 +47,10 @@ handler(int sig){ ...@@ -47,7 +47,10 @@ handler(int sig){
int main(int argc, const char** argv){ int main(int argc, const char** argv){
int optind = 0; int optind = 0;
const char *_default_connectstring = "host=localhost:2200;nodeid=0"; char _default_connectstring_buf[256];
snprintf(_default_connectstring_buf, sizeof(_default_connectstring_buf),
"host=localhost:%u", NDB_BASE_PORT);
const char *_default_connectstring= _default_connectstring_buf;
const char *_host = 0; const char *_host = 0;
int _port = 0; int _port = 0;
int _help = 0; int _help = 0;
......
This diff is collapsed.
...@@ -68,6 +68,18 @@ public: ...@@ -68,6 +68,18 @@ public:
virtual void println_statistics(const BaseString &s) = 0; virtual void println_statistics(const BaseString &s) = 0;
}; };
class Allocated_resources {
public:
Allocated_resources(class MgmtSrvr &m);
~Allocated_resources();
// methods to reserve/allocate resources which
// will be freed when running destructor
void reserve_node(NodeId id);
private:
MgmtSrvr &m_mgmsrv;
NodeBitmask m_reserved_nodes;
};
/** /**
* Set a reference to the socket server. * Set a reference to the socket server.
*/ */
...@@ -150,10 +162,12 @@ public: ...@@ -150,10 +162,12 @@ public:
enum LogMode {In, Out, InOut, Off}; enum LogMode {In, Out, InOut, Off};
/* Constructor */ /* Constructor */
MgmtSrvr(NodeId nodeId, /* Local nodeid */ MgmtSrvr(NodeId nodeId, /* Local nodeid */
const BaseString &config_filename, /* Where to save config */ const BaseString &config_filename, /* Where to save config */
const BaseString &ndb_config_filename, /* Ndb.cfg filename */ const BaseString &ndb_config_filename, /* Ndb.cfg filename */
Config * config); Config * config);
NodeId getOwnNodeId() const {return _ownNodeId;};
/** /**
* Read (initial) config file, create TransporterFacade, * Read (initial) config file, create TransporterFacade,
...@@ -448,6 +462,8 @@ public: ...@@ -448,6 +462,8 @@ public:
* @return false if none found * @return false if none found
*/ */
bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ; bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ;
bool getFreeNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type,
struct sockaddr *client_addr, socklen_t *client_addr_len) const ;
/** /**
* *
...@@ -492,7 +508,11 @@ public: ...@@ -492,7 +508,11 @@ public:
* @return statistic port number. * @return statistic port number.
*/ */
int getStatPort() const; int getStatPort() const;
/**
* Returns the port number.
* @return port number.
*/
int getPort() const;
//************************************************************************** //**************************************************************************
private: private:
...@@ -531,12 +551,13 @@ private: ...@@ -531,12 +551,13 @@ private:
BaseString m_localNdbConfigFilename; BaseString m_localNdbConfigFilename;
Uint32 m_nextConfigGenerationNumber; Uint32 m_nextConfigGenerationNumber;
NodeBitmask m_reserved_nodes;
Allocated_resources m_allocated_resources;
int _setVarReqResult; // The result of the SET_VAR_REQ response int _setVarReqResult; // The result of the SET_VAR_REQ response
Statistics _statistics; // handleSTATISTICS_CONF store the result here, Statistics _statistics; // handleSTATISTICS_CONF store the result here,
// and getStatistics reads it. // and getStatistics reads it.
//************************************************************************** //**************************************************************************
// Specific signal handling methods // Specific signal handling methods
//************************************************************************** //**************************************************************************
......
...@@ -121,6 +121,15 @@ ParserRow<MgmApiSession> commands[] = { ...@@ -121,6 +121,15 @@ ParserRow<MgmApiSession> commands[] = {
MGM_ARG("version", Int, Mandatory, "Configuration version number"), MGM_ARG("version", Int, Mandatory, "Configuration version number"),
MGM_ARG("node", Int, Optional, "Node ID"), MGM_ARG("node", Int, Optional, "Node ID"),
MGM_CMD("get nodeid", &MgmApiSession::get_nodeid, ""),
MGM_ARG("version", Int, Mandatory, "Configuration version number"),
MGM_ARG("nodetype", Int, Mandatory, "Node type"),
MGM_ARG("transporter", String, Optional, "Transporter type"),
MGM_ARG("nodeid", Int, Optional, "Node ID"),
MGM_ARG("user", String, Mandatory, "Password"),
MGM_ARG("password", String, Mandatory, "Password"),
MGM_ARG("public key", String, Mandatory, "Public key"),
MGM_CMD("get version", &MgmApiSession::getVersion, ""), MGM_CMD("get version", &MgmApiSession::getVersion, ""),
MGM_CMD("get status", &MgmApiSession::getStatus, ""), MGM_CMD("get status", &MgmApiSession::getStatus, ""),
...@@ -224,6 +233,19 @@ MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock) ...@@ -224,6 +233,19 @@ MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock)
m_input = new SocketInputStream(sock); m_input = new SocketInputStream(sock);
m_output = new SocketOutputStream(sock); m_output = new SocketOutputStream(sock);
m_parser = new Parser_t(commands, *m_input, true, true, true); m_parser = new Parser_t(commands, *m_input, true, true, true);
m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv);
}
MgmApiSession::~MgmApiSession()
{
if (m_input)
delete m_input;
if (m_output)
delete m_output;
if (m_parser)
delete m_parser;
if (m_allocated_resources)
delete m_allocated_resources;
} }
void void
...@@ -332,6 +354,91 @@ backward(const char * base, const Properties* reply){ ...@@ -332,6 +354,91 @@ backward(const char * base, const Properties* reply){
return ret; return ret;
} }
void
MgmApiSession::get_nodeid(Parser_t::Context &,
const class Properties &args)
{
const char *cmd= "get nodeid reply";
Uint32 version, nodeid= 0, nodetype= 0xff;
const char * transporter;
const char * user;
const char * password;
const char * public_key;
args.get("version", &version);
args.get("nodetype", &nodetype);
args.get("transporter", &transporter);
args.get("nodeid", &nodeid);
args.get("user", &user);
args.get("password", &password);
args.get("public key", &public_key);
bool compatible;
switch (nodetype) {
case NODE_TYPE_MGM:
case NODE_TYPE_API:
compatible = ndbCompatible_mgmt_api(NDB_VERSION, version);
break;
case NODE_TYPE_DB:
compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version);
break;
default:
m_output->println(cmd);
m_output->println("result: unknown nodetype %d", nodetype);
m_output->println("");
return;
}
struct sockaddr addr;
socklen_t addrlen;
int r;
if (r= getsockname(m_socket, &addr, &addrlen)) {
m_output->println(cmd);
m_output->println("result: getsockname(%d) failed, err= %d", m_socket, r);
m_output->println("");
return;
}
NodeId free_id= 0;
NodeId tmp= nodeid;
if (m_mgmsrv.getFreeNodeId(&tmp, (enum ndb_mgm_node_type)nodetype, &addr, &addrlen))
free_id= tmp;
if (nodeid != 0 && free_id != nodeid){
m_output->println(cmd);
m_output->println("result: no free nodeid %d for nodetype %d",
nodeid, nodetype);
m_output->println("");
return;
}
if (free_id == 0){
m_output->println(cmd);
m_output->println("result: no free nodeid for nodetype %d", nodetype);
m_output->println("");
return;
}
#if 0
if (!compatible){
m_output->println(cmd);
m_output->println("result: incompatible version mgmt 0x%x and node 0x%x",
NDB_VERSION, version);
m_output->println("");
return;
}
#endif
m_output->println(cmd);
m_output->println("nodeid: %u", free_id);
m_output->println("result: Ok");
m_output->println("");
m_allocated_resources->reserve_node(free_id);
return;
}
void void
MgmApiSession::getConfig_common(Parser_t::Context &, MgmApiSession::getConfig_common(Parser_t::Context &,
const class Properties &args, const class Properties &args,
...@@ -432,7 +539,6 @@ MgmApiSession::getConfig_common(Parser_t::Context &, ...@@ -432,7 +539,6 @@ MgmApiSession::getConfig_common(Parser_t::Context &,
m_output->println("Content-Transfer-Encoding: base64"); m_output->println("Content-Transfer-Encoding: base64");
m_output->println(""); m_output->println("");
m_output->println(str.c_str()); m_output->println(str.c_str());
m_output->println("");
return; return;
} }
......
...@@ -36,6 +36,7 @@ private: ...@@ -36,6 +36,7 @@ private:
InputStream *m_input; InputStream *m_input;
OutputStream *m_output; OutputStream *m_output;
Parser_t *m_parser; Parser_t *m_parser;
MgmtSrvr::Allocated_resources *m_allocated_resources;
void getConfig_common(Parser_t::Context &ctx, void getConfig_common(Parser_t::Context &ctx,
const class Properties &args, const class Properties &args,
...@@ -43,6 +44,7 @@ private: ...@@ -43,6 +44,7 @@ private:
public: public:
MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock); MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock);
virtual ~MgmApiSession();
void runSession(); void runSession();
void getStatPort(Parser_t::Context &ctx, const class Properties &args); void getStatPort(Parser_t::Context &ctx, const class Properties &args);
...@@ -51,6 +53,7 @@ public: ...@@ -51,6 +53,7 @@ public:
void getConfig_old(Parser_t::Context &ctx); void getConfig_old(Parser_t::Context &ctx);
#endif /* MGM_GET_CONFIG_BACKWARDS_COMPAT */ #endif /* MGM_GET_CONFIG_BACKWARDS_COMPAT */
void get_nodeid(Parser_t::Context &ctx, const class Properties &args);
void getVersion(Parser_t::Context &ctx, const class Properties &args); void getVersion(Parser_t::Context &ctx, const class Properties &args);
void getStatus(Parser_t::Context &ctx, const class Properties &args); void getStatus(Parser_t::Context &ctx, const class Properties &args);
void getInfoClusterLog(Parser_t::Context &ctx, const class Properties &args); void getInfoClusterLog(Parser_t::Context &ctx, const class Properties &args);
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include "MgmtSrvr.hpp" #include "MgmtSrvr.hpp"
#include "EventLogger.hpp" #include "EventLogger.hpp"
#include "Config.hpp" #include <Config.hpp>
#include "InitConfigFileParser.hpp" #include "InitConfigFileParser.hpp"
#include <SocketServer.hpp> #include <SocketServer.hpp>
#include "Services.hpp" #include "Services.hpp"
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#include <mgmapi_config_parameters.h> #include <mgmapi_config_parameters.h>
#include <getarg.h> #include <getarg.h>
#include <NdbAutoPtr.hpp>
#if defined NDB_OSE || defined NDB_SOFTOSE #if defined NDB_OSE || defined NDB_SOFTOSE
#include <efs.h> #include <efs.h>
#else #else
...@@ -88,7 +90,6 @@ static MgmGlobals glob; ...@@ -88,7 +90,6 @@ static MgmGlobals glob;
******************************************************************************/ ******************************************************************************/
static bool readLocalConfig(); static bool readLocalConfig();
static bool readGlobalConfig(); static bool readGlobalConfig();
static bool setPortNo();
/** /**
* Global variables * Global variables
...@@ -146,7 +147,9 @@ NDB_MAIN(mgmsrv){ ...@@ -146,7 +147,9 @@ NDB_MAIN(mgmsrv){
exit(1); exit(1);
} }
glob.socketServer = new SocketServer(); glob.socketServer = new SocketServer();
MgmApiService * mapi = new MgmApiService(); MgmApiService * mapi = new MgmApiService();
MgmStatService * mstat = new MgmStatService(); MgmStatService * mstat = new MgmStatService();
/**************************** /****************************
...@@ -157,9 +160,27 @@ NDB_MAIN(mgmsrv){ ...@@ -157,9 +160,27 @@ NDB_MAIN(mgmsrv){
if (!readGlobalConfig()) if (!readGlobalConfig())
goto error_end; goto error_end;
if (!setPortNo()) glob.mgmObject = new MgmtSrvr(glob.localNodeId,
BaseString(glob.config_filename),
BaseString(glob.local_config_filename == 0 ?
"" : glob.local_config_filename),
glob.cluster_config);
glob.cluster_config = 0;
glob.localNodeId= glob.mgmObject->getOwnNodeId();
if (glob.localNodeId == 0) {
goto error_end;
}
glob.port= glob.mgmObject->getPort();
if (glob.port == 0)
goto error_end; goto error_end;
glob.interface_name = 0;
glob.use_specific_ip = false;
if(!glob.use_specific_ip){ if(!glob.use_specific_ip){
if(!glob.socketServer->tryBind(glob.port, glob.interface_name)){ if(!glob.socketServer->tryBind(glob.port, glob.interface_name)){
ndbout_c("Unable to setup port: %s:%d!\n" ndbout_c("Unable to setup port: %s:%d!\n"
...@@ -190,25 +211,18 @@ NDB_MAIN(mgmsrv){ ...@@ -190,25 +211,18 @@ NDB_MAIN(mgmsrv){
goto error_end; goto error_end;
} }
glob.mgmObject = new MgmtSrvr(glob.localNodeId,
BaseString(glob.config_filename),
BaseString(glob.local_config_filename == 0 ? "" : glob.local_config_filename),
glob.cluster_config);
glob.cluster_config = 0;
if(!glob.mgmObject->check_start()){ if(!glob.mgmObject->check_start()){
ndbout_c("Unable to start management server."); ndbout_c("Unable to check start management server.");
ndbout_c("Probably caused by illegal initial configuration file."); ndbout_c("Probably caused by illegal initial configuration file.");
goto error_end; goto error_end;
} }
if (glob.daemon) { if (glob.daemon) {
// Become a daemon // Become a daemon
char homePath[255],lockfile[255], logfile[255]; char *lockfile= NdbConfig_PidFileName(glob.localNodeId);
NdbConfig_HomePath(homePath, 255); char *logfile= NdbConfig_StdoutFileName(glob.localNodeId);
snprintf(lockfile, 255, "%snode%d.pid", homePath, glob.localNodeId); NdbAutoPtr<char> tmp_aptr1(lockfile), tmp_aptr2(logfile);
snprintf(logfile, 255, "%snode%d.out", homePath, glob.localNodeId);
if (NdbDaemon_Make(lockfile, logfile, 0) == -1) { if (NdbDaemon_Make(lockfile, logfile, 0) == -1) {
ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl; ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl;
return 1; return 1;
...@@ -233,8 +247,8 @@ NDB_MAIN(mgmsrv){ ...@@ -233,8 +247,8 @@ NDB_MAIN(mgmsrv){
ndbout_c(msg); ndbout_c(msg);
g_EventLogger.info(msg); g_EventLogger.info(msg);
snprintf(msg, 256, "Command port: %d, Statistics port: %d", snprintf(msg, 256, "Id: %d, Command port: %d, Statistics port: %d",
glob.port, glob.port_stats); glob.localNodeId, glob.port, glob.port_stats);
ndbout_c(msg); ndbout_c(msg);
g_EventLogger.info(msg); g_EventLogger.info(msg);
...@@ -343,108 +357,3 @@ readGlobalConfig() { ...@@ -343,108 +357,3 @@ readGlobalConfig() {
} }
return true; return true;
} }
/**
* @fn setPortNo
* @param glob : Global variables
* @return true if success, false otherwise.
*
* Port number:
* 2. Use port number from global configuration file
* 4. Use port number for statistics from global configuration file
*/
static bool
setPortNo(){
const Properties *mgmProps;
ndb_mgm_configuration_iterator * iter =
ndb_mgm_create_configuration_iterator(glob.cluster_config->m_configValues,
CFG_SECTION_NODE);
if(iter == 0)
return false;
if(ndb_mgm_find(iter, CFG_NODE_ID, glob.localNodeId) != 0){
ndbout << "Could not retrieve configuration for Node "
<< glob.localNodeId << " in config file." << endl
<< "Have you set correct NodeId for this node?" << endl;
ndb_mgm_destroy_iterator(iter);
return false;
}
unsigned type;
if(ndb_mgm_get_int_parameter(iter, CFG_TYPE_OF_SECTION, &type) != 0 ||
type != NODE_TYPE_MGM){
ndbout << "Local node id " << glob.localNodeId
<< " is not defined as management server" << endl
<< "Have you set correct NodeId for this node?" << endl;
return false;
}
/************
* Set Port *
************/
Uint32 tmp = 0;
if(ndb_mgm_get_int_parameter(iter, CFG_MGM_PORT, &tmp) != 0){
ndbout << "Could not find PortNumber in the configuration file." << endl;
return false;
}
glob.port = tmp;
/*****************
* Set Stat Port *
*****************/
#if 0
if (!mgmProps->get("PortNumberStats", &tmp)){
ndbout << "Could not find PortNumberStats in the configuration file."
<< endl;
return false;
}
glob.port_stats = tmp;
#endif
#if 0
const char * host;
if(ndb_mgm_get_string_parameter(iter, mgmProps->get("ExecuteOnComputer", host)){
ndbout << "Failed to find \"ExecuteOnComputer\" for my node" << endl;
ndbout << "Unable to verify own hostname" << endl;
return false;
}
const char * hostname;
{
const Properties * p;
char buf[255];
snprintf(buf, sizeof(buf), "Computer_%s", host.c_str());
if(!glob.cluster_config->get(buf, &p)){
ndbout << "Failed to find computer " << host << " in config" << endl;
ndbout << "Unable to verify own hostname" << endl;
return false;
}
if(!p->get("HostName", &hostname)){
ndbout << "Failed to find \"HostName\" for computer " << host
<< " in config" << endl;
ndbout << "Unable to verify own hostname" << endl;
return false;
}
if(NdbHost_GetHostName(buf) != 0){
ndbout << "Unable to get own hostname" << endl;
ndbout << "Unable to verify own hostname" << endl;
return false;
}
}
const char * ip_address;
if(mgmProps->get("IpAddress", &ip_address)){
glob.use_specific_ip = true;
glob.interface_name = strdup(ip_address);
return true;
}
glob.interface_name = strdup(hostname);
#endif
glob.interface_name = 0;
glob.use_specific_ip = false;
return true;
}
...@@ -295,6 +295,7 @@ ClusterMgr::execAPI_REGREQ(const Uint32 * theData){ ...@@ -295,6 +295,7 @@ ClusterMgr::execAPI_REGREQ(const Uint32 * theData){
} }
int global_mgmt_server_check = 0; // set to one in mgmtsrvr main; int global_mgmt_server_check = 0; // set to one in mgmtsrvr main;
void void
ClusterMgr::execAPI_REGCONF(const Uint32 * theData){ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0]; const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0];
...@@ -309,6 +310,7 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){ ...@@ -309,6 +310,7 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
Node & node = theNodes[nodeId]; Node & node = theNodes[nodeId];
assert(node.defined == true); assert(node.defined == true);
assert(node.connected == true); assert(node.connected == true);
if(node.m_info.m_version != apiRegConf->version){ if(node.m_info.m_version != apiRegConf->version){
node.m_info.m_version = apiRegConf->version; node.m_info.m_version = apiRegConf->version;
if (global_mgmt_server_check == 1) if (global_mgmt_server_check == 1)
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#endif #endif
//#define REPORT_TRANSPORTER //#define REPORT_TRANSPORTER
//#define API_TRACE;
#if defined DEBUG_TRANSPORTER #if defined DEBUG_TRANSPORTER
#define TRP_DEBUG(t) ndbout << __FILE__ << ":" << __LINE__ << ":" << t << endl; #define TRP_DEBUG(t) ndbout << __FILE__ << ":" << __LINE__ << ":" << t << endl;
...@@ -47,7 +48,7 @@ ...@@ -47,7 +48,7 @@
#endif #endif
TransporterFacade* TransporterFacade::theFacadeInstance = NULL; TransporterFacade* TransporterFacade::theFacadeInstance = NULL;
ConfigRetriever *TransporterFacade::s_config_retriever= 0;
/***************************************************************************** /*****************************************************************************
...@@ -332,11 +333,15 @@ atexit_stop_instance(){ ...@@ -332,11 +333,15 @@ atexit_stop_instance(){
* *
* Which is protected by a mutex * Which is protected by a mutex
*/ */
TransporterFacade* TransporterFacade*
TransporterFacade::start_instance(const char * connectString){ TransporterFacade::start_instance(const char * connectString){
// TransporterFacade used from API get config from mgmt srvr // TransporterFacade used from API get config from mgmt srvr
ConfigRetriever configRetriever; s_config_retriever= new ConfigRetriever;
ConfigRetriever &configRetriever= *s_config_retriever;
configRetriever.setConnectString(connectString); configRetriever.setConnectString(connectString);
ndb_mgm_configuration * props = configRetriever.getConfig(NDB_VERSION, ndb_mgm_configuration * props = configRetriever.getConfig(NDB_VERSION,
NODE_TYPE_API); NODE_TYPE_API);
...@@ -389,6 +394,14 @@ TransporterFacade::start_instance(int nodeId, ...@@ -389,6 +394,14 @@ TransporterFacade::start_instance(int nodeId,
return tf; return tf;
} }
void
TransporterFacade::close_configuration(){
if (s_config_retriever) {
delete s_config_retriever;
s_config_retriever= 0;
}
}
/** /**
* Note that this function need no locking since its * Note that this function need no locking since its
* only called from the destructor of Ndb (the NdbObject) * only called from the destructor of Ndb (the NdbObject)
...@@ -397,6 +410,9 @@ TransporterFacade::start_instance(int nodeId, ...@@ -397,6 +410,9 @@ TransporterFacade::start_instance(int nodeId,
*/ */
void void
TransporterFacade::stop_instance(){ TransporterFacade::stop_instance(){
close_configuration();
if(theFacadeInstance == NULL){ if(theFacadeInstance == NULL){
/** /**
* We are called from atexit function * We are called from atexit function
...@@ -440,7 +456,17 @@ runSendRequest_C(void * me) ...@@ -440,7 +456,17 @@ runSendRequest_C(void * me)
void TransporterFacade::threadMainSend(void) void TransporterFacade::threadMainSend(void)
{ {
SocketServer socket_server;
theTransporterRegistry->startSending(); theTransporterRegistry->startSending();
if (!theTransporterRegistry->start_service(socket_server))
NDB_ASSERT(0, "Unable to start theTransporterRegistry->start_service");
if (!theTransporterRegistry->start_clients())
NDB_ASSERT(0, "Unable to start theTransporterRegistry->start_clients");
socket_server.startServer();
while(!theStopReceive) { while(!theStopReceive) {
NdbSleep_MilliSleep(10); NdbSleep_MilliSleep(10);
NdbMutex_Lock(theMutexPtr); NdbMutex_Lock(theMutexPtr);
...@@ -451,6 +477,11 @@ void TransporterFacade::threadMainSend(void) ...@@ -451,6 +477,11 @@ void TransporterFacade::threadMainSend(void)
NdbMutex_Unlock(theMutexPtr); NdbMutex_Unlock(theMutexPtr);
} }
theTransporterRegistry->stopSending(); theTransporterRegistry->stopSending();
socket_server.stopServer();
socket_server.stopSessions();
theTransporterRegistry->stop_clients();
} }
extern "C" extern "C"
...@@ -466,7 +497,7 @@ void TransporterFacade::threadMainReceive(void) ...@@ -466,7 +497,7 @@ void TransporterFacade::threadMainReceive(void)
{ {
theTransporterRegistry->startReceiving(); theTransporterRegistry->startReceiving();
NdbMutex_Lock(theMutexPtr); NdbMutex_Lock(theMutexPtr);
theTransporterRegistry->checkConnections(); theTransporterRegistry->update_connections();
NdbMutex_Unlock(theMutexPtr); NdbMutex_Unlock(theMutexPtr);
while(!theStopReceive) { while(!theStopReceive) {
for(int i = 0; i<10; i++){ for(int i = 0; i<10; i++){
...@@ -478,7 +509,7 @@ void TransporterFacade::threadMainReceive(void) ...@@ -478,7 +509,7 @@ void TransporterFacade::threadMainReceive(void)
} }
} }
NdbMutex_Lock(theMutexPtr); NdbMutex_Lock(theMutexPtr);
theTransporterRegistry->checkConnections(); theTransporterRegistry->update_connections();
NdbMutex_Unlock(theMutexPtr); NdbMutex_Unlock(theMutexPtr);
}//while }//while
theTransporterRegistry->stopReceiving(); theTransporterRegistry->stopReceiving();
...@@ -875,13 +906,13 @@ TransporterFacade::sendFragmentedSignalUnCond(NdbApiSignal* aSignal, ...@@ -875,13 +906,13 @@ TransporterFacade::sendFragmentedSignalUnCond(NdbApiSignal* aSignal,
void void
TransporterFacade::doConnect(int aNodeId){ TransporterFacade::doConnect(int aNodeId){
theTransporterRegistry->setIOState(aNodeId, NoHalt); theTransporterRegistry->setIOState(aNodeId, NoHalt);
theTransporterRegistry->setPerformState(aNodeId, PerformConnect); theTransporterRegistry->do_connect(aNodeId);
} }
void void
TransporterFacade::doDisconnect(int aNodeId) TransporterFacade::doDisconnect(int aNodeId)
{ {
theTransporterRegistry->setPerformState(aNodeId, PerformDisconnect); theTransporterRegistry->do_disconnect(aNodeId);
} }
void void
...@@ -906,7 +937,7 @@ TransporterFacade::ownId() const ...@@ -906,7 +937,7 @@ TransporterFacade::ownId() const
bool bool
TransporterFacade::isConnected(NodeId aNodeId){ TransporterFacade::isConnected(NodeId aNodeId){
return theTransporterRegistry->performState(aNodeId) == PerformIO; return theTransporterRegistry->is_connected(aNodeId);
} }
NodeId NodeId
......
...@@ -29,6 +29,7 @@ class ClusterMgr; ...@@ -29,6 +29,7 @@ class ClusterMgr;
class ArbitMgr; class ArbitMgr;
class IPCConfig; class IPCConfig;
struct ndb_mgm_configuration; struct ndb_mgm_configuration;
class ConfigRetriever;
class Ndb; class Ndb;
class NdbApiSignal; class NdbApiSignal;
...@@ -56,6 +57,7 @@ public: ...@@ -56,6 +57,7 @@ public:
static TransporterFacade* instance(); static TransporterFacade* instance();
static TransporterFacade* start_instance(int, const ndb_mgm_configuration*); static TransporterFacade* start_instance(int, const ndb_mgm_configuration*);
static TransporterFacade* start_instance(const char *connectString); static TransporterFacade* start_instance(const char *connectString);
static void close_configuration();
static void stop_instance(); static void stop_instance();
/** /**
...@@ -110,7 +112,6 @@ public: ...@@ -110,7 +112,6 @@ public:
// Close this block number // Close this block number
int close_local(BlockNumber blockNumber); int close_local(BlockNumber blockNumber);
void setState(Uint32 aNodeId, PerformState aState);
private: private:
/** /**
...@@ -219,6 +220,7 @@ public: ...@@ -219,6 +220,7 @@ public:
NdbMutex* theMutexPtr; NdbMutex* theMutexPtr;
private: private:
static TransporterFacade* theFacadeInstance; static TransporterFacade* theFacadeInstance;
static ConfigRetriever *s_config_retriever;
public: public:
GlobalDictCache m_globalDictCache; GlobalDictCache m_globalDictCache;
......
...@@ -71,7 +71,7 @@ NdbBackup::getFileSystemPathForNode(int _node_id){ ...@@ -71,7 +71,7 @@ NdbBackup::getFileSystemPathForNode(int _node_id){
*/ */
ConfigRetriever cr; ConfigRetriever cr;
ndb_mgm_configuration * p = cr.getConfig(host, port, 0); ndb_mgm_configuration * p = cr.getConfig(host, port, 0, NODE_TYPE_API);
if(p == 0){ if(p == 0){
const char * s = cr.getErrorString(); const char * s = cr.getErrorString();
if(s == 0) if(s == 0)
...@@ -154,7 +154,7 @@ NdbBackup::execRestore(bool _restore_data, ...@@ -154,7 +154,7 @@ NdbBackup::execRestore(bool _restore_data,
#endif #endif
snprintf(buf, 255, "ndb_restore -c \"nodeid=%d;host=%s\" -n %d -b %d %s %s .", snprintf(buf, 255, "valgrind --leak-check=yes -v ndb_restore -c \"nodeid=%d;host=%s\" -n %d -b %d %s %s .",
ownNodeId, ownNodeId,
addr, addr,
_node_id, _node_id,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment