wl 1748

parent 6c58b9f4
......@@ -18,6 +18,7 @@
#define NODE_INFO_HPP
#include <NdbOut.hpp>
#include <mgmapi_config_parameters.h>
class NodeInfo {
public:
......@@ -27,10 +28,10 @@ public:
* NodeType
*/
enum NodeType {
DB = 0, ///< Database node
API = 1, ///< NDB API node
MGM = 2, ///< Management node (incl. NDB API)
REP = 3, ///< Replication node (incl. NDB API)
DB = NODE_TYPE_DB, ///< Database node
API = NODE_TYPE_API, ///< NDB API node
MGM = NODE_TYPE_MGM, ///< Management node (incl. NDB API)
REP = NODE_TYPE_REP, ///< Replication node (incl. NDB API)
INVALID = 255 ///< Invalid type
};
NodeType getType() const;
......
......@@ -18,6 +18,7 @@
#define NODE_STATE_HPP
#include <NdbOut.hpp>
#include <NodeBitmask.hpp>
class NodeState {
public:
......@@ -99,7 +100,7 @@ public:
/**
* Length in 32-bit words
*/
static const Uint32 DataLength = 8;
static const Uint32 DataLength = 8 + NdbNodeBitmask::Size;
/**
* Constructor(s)
......@@ -146,6 +147,8 @@ public:
Uint32 singleUserMode;
Uint32 singleUserApi; //the single user node
BitmaskPOD<NdbNodeBitmask::Size> m_connected_nodes;
void setDynamicId(Uint32 dynamic);
void setNodeGroup(Uint32 group);
void setSingleUser(Uint32 s);
......@@ -182,6 +185,7 @@ NodeState::NodeState(){
dynamicId = 0xFFFFFFFF;
singleUserMode = 0;
singleUserApi = 0xFFFFFFFF;
m_connected_nodes.clear();
}
inline
......
......@@ -80,15 +80,13 @@ class ApiRegConf {
friend class ClusterMgr;
public:
STATIC_CONST( SignalLength = 3 + NodeState::DataLength +
NdbNodeBitmask::Size );
STATIC_CONST( SignalLength = 3 + NodeState::DataLength );
private:
Uint32 qmgrRef;
Uint32 version; // Version of NDB node
Uint32 apiHeartbeatFrequency;
NodeState nodeState;
Bitmask<NdbNodeBitmask::Size>::Data connected_nodes;
};
#endif
......@@ -49,6 +49,8 @@
* @{
*/
#include "mgmapi_config_parameters.h"
#ifdef __cplusplus
extern "C" {
#endif
......@@ -81,10 +83,10 @@ extern "C" {
*/
enum ndb_mgm_node_type {
NDB_MGM_NODE_TYPE_UNKNOWN = -1, /*/< Node type not known*/
NDB_MGM_NODE_TYPE_API = 0, /*/< An application node (API)*/
NDB_MGM_NODE_TYPE_NDB = 1, /*/< A database node (DB)*/
NDB_MGM_NODE_TYPE_MGM = 2, /*/< A management server node (MGM)*/
NDB_MGM_NODE_TYPE_REP = 3, ///< A replication node
NDB_MGM_NODE_TYPE_API = NODE_TYPE_API, /*/< An application node (API)*/
NDB_MGM_NODE_TYPE_NDB = NODE_TYPE_DB, /*/< A database node (DB)*/
NDB_MGM_NODE_TYPE_MGM = NODE_TYPE_MGM, /*/< A management server node (MGM)*/
NDB_MGM_NODE_TYPE_REP = NODE_TYPE_REP, ///< A replication node
NDB_MGM_NODE_TYPE_MIN = 0, /*/< Min valid value*/
NDB_MGM_NODE_TYPE_MAX = 3 /*/< Max valid value*/
......
......@@ -6,6 +6,7 @@
#define CFG_SYS_PRIMARY_MGM_NODE 1
#define CFG_SYS_CONFIG_GENERATION 2
#define CFG_SYS_REPLICATION_ROLE 7
#define CFG_SYS_PORT_BASE 8
#define CFG_NODE_ID 3
#define CFG_NODE_BYTE_ORDER 4
......
......@@ -326,7 +326,7 @@ BitmaskImpl::getText(unsigned size, const Uint32 data[], char* buf)
* XXX replace size by length in bits
*/
template <unsigned size>
class Bitmask {
struct BitmaskPOD {
public:
/**
* POD data representation
......@@ -334,7 +334,7 @@ public:
struct Data {
Uint32 data[size];
#if 0
Data & operator=(const Bitmask<size> & src) {
Data & operator=(const BitmaskPOD<size> & src) {
src.copyto(size, data);
return *this;
}
......@@ -348,19 +348,17 @@ public:
STATIC_CONST( NotFound = BitmaskImpl::NotFound );
STATIC_CONST( TextLength = size * 8 );
Bitmask() { clear();}
/**
* assign - Set all bits in <em>dst</em> to corresponding in <em>src/<em>
*/
void assign(const typename Bitmask<size>::Data & src);
void assign(const typename BitmaskPOD<size>::Data & src);
/**
* assign - Set all bits in <em>dst</em> to corresponding in <em>src/<em>
*/
static void assign(Uint32 dst[], const Uint32 src[]);
static void assign(Uint32 dst[], const Bitmask<size> & src);
void assign(const Bitmask<size> & src);
static void assign(Uint32 dst[], const BitmaskPOD<size> & src);
void assign(const BitmaskPOD<size> & src);
/**
* copy this to <em>dst</em>
......@@ -432,43 +430,43 @@ public:
* equal - Bitwise equal.
*/
static bool equal(const Uint32 data[], const Uint32 data2[]);
bool equal(const Bitmask<size>& mask2) const;
bool equal(const BitmaskPOD<size>& mask2) const;
/**
* bitOR - Bitwise (x | y) into first operand.
*/
static void bitOR(Uint32 data[], const Uint32 data2[]);
Bitmask<size>& bitOR(const Bitmask<size>& mask2);
BitmaskPOD<size>& bitOR(const BitmaskPOD<size>& mask2);
/**
* bitAND - Bitwise (x & y) into first operand.
*/
static void bitAND(Uint32 data[], const Uint32 data2[]);
Bitmask<size>& bitAND(const Bitmask<size>& mask2);
BitmaskPOD<size>& bitAND(const BitmaskPOD<size>& mask2);
/**
* bitANDC - Bitwise (x & ~y) into first operand.
*/
static void bitANDC(Uint32 data[], const Uint32 data2[]);
Bitmask<size>& bitANDC(const Bitmask<size>& mask2);
BitmaskPOD<size>& bitANDC(const BitmaskPOD<size>& mask2);
/**
* bitXOR - Bitwise (x ^ y) into first operand.
*/
static void bitXOR(Uint32 data[], const Uint32 data2[]);
Bitmask<size>& bitXOR(const Bitmask<size>& mask2);
BitmaskPOD<size>& bitXOR(const BitmaskPOD<size>& mask2);
/**
* contains - Check if all bits set in data2 (that) are also set in data (this)
*/
static bool contains(Uint32 data[], const Uint32 data2[]);
bool contains(Bitmask<size> that);
bool contains(BitmaskPOD<size> that);
/**
* overlaps - Check if any bit set in this Bitmask (data) is also set in that (data2)
* overlaps - Check if any bit set in this BitmaskPOD (data) is also set in that (data2)
*/
static bool overlaps(Uint32 data[], const Uint32 data2[]);
bool overlaps(Bitmask<size> that);
bool overlaps(BitmaskPOD<size> that);
/**
* getText - Return as hex-digits (only for debug routines).
......@@ -479,196 +477,196 @@ public:
template <unsigned size>
inline void
Bitmask<size>::assign(Uint32 dst[], const Uint32 src[])
BitmaskPOD<size>::assign(Uint32 dst[], const Uint32 src[])
{
BitmaskImpl::assign(size, dst, src);
}
template <unsigned size>
inline void
Bitmask<size>::assign(Uint32 dst[], const Bitmask<size> & src)
BitmaskPOD<size>::assign(Uint32 dst[], const BitmaskPOD<size> & src)
{
BitmaskImpl::assign(size, dst, src.rep.data);
}
template <unsigned size>
inline void
Bitmask<size>::assign(const typename Bitmask<size>::Data & src)
BitmaskPOD<size>::assign(const typename BitmaskPOD<size>::Data & src)
{
assign(rep.data, src.data);
}
template <unsigned size>
inline void
Bitmask<size>::assign(const Bitmask<size> & src)
BitmaskPOD<size>::assign(const BitmaskPOD<size> & src)
{
assign(rep.data, src.rep.data);
}
template <unsigned size>
inline void
Bitmask<size>::copyto(unsigned sz, Uint32 dst[]) const
BitmaskPOD<size>::copyto(unsigned sz, Uint32 dst[]) const
{
BitmaskImpl::assign(sz, dst, rep.data);
}
template <unsigned size>
inline void
Bitmask<size>::assign(unsigned sz, const Uint32 src[])
BitmaskPOD<size>::assign(unsigned sz, const Uint32 src[])
{
BitmaskImpl::assign(sz, rep.data, src);
}
template <unsigned size>
inline bool
Bitmask<size>::get(const Uint32 data[], unsigned n)
BitmaskPOD<size>::get(const Uint32 data[], unsigned n)
{
return BitmaskImpl::get(size, data, n);
}
template <unsigned size>
inline bool
Bitmask<size>::get(unsigned n) const
BitmaskPOD<size>::get(unsigned n) const
{
return get(rep.data, n);
}
template <unsigned size>
inline void
Bitmask<size>::set(Uint32 data[], unsigned n, bool value)
BitmaskPOD<size>::set(Uint32 data[], unsigned n, bool value)
{
BitmaskImpl::set(size, data, n, value);
}
template <unsigned size>
inline void
Bitmask<size>::set(unsigned n, bool value)
BitmaskPOD<size>::set(unsigned n, bool value)
{
set(rep.data, n, value);
}
template <unsigned size>
inline void
Bitmask<size>::set(Uint32 data[], unsigned n)
BitmaskPOD<size>::set(Uint32 data[], unsigned n)
{
BitmaskImpl::set(size, data, n);
}
template <unsigned size>
inline void
Bitmask<size>::set(unsigned n)
BitmaskPOD<size>::set(unsigned n)
{
set(rep.data, n);
}
template <unsigned size>
inline void
Bitmask<size>::set(Uint32 data[])
BitmaskPOD<size>::set(Uint32 data[])
{
BitmaskImpl::set(size, data);
}
template <unsigned size>
inline void
Bitmask<size>::set()
BitmaskPOD<size>::set()
{
set(rep.data);
}
template <unsigned size>
inline void
Bitmask<size>::clear(Uint32 data[], unsigned n)
BitmaskPOD<size>::clear(Uint32 data[], unsigned n)
{
BitmaskImpl::clear(size, data, n);
}
template <unsigned size>
inline void
Bitmask<size>::clear(unsigned n)
BitmaskPOD<size>::clear(unsigned n)
{
clear(rep.data, n);
}
template <unsigned size>
inline void
Bitmask<size>::clear(Uint32 data[])
BitmaskPOD<size>::clear(Uint32 data[])
{
BitmaskImpl::clear(size, data);
}
template <unsigned size>
inline void
Bitmask<size>::clear()
BitmaskPOD<size>::clear()
{
clear(rep.data);
}
template <unsigned size>
inline bool
Bitmask<size>::isclear(const Uint32 data[])
BitmaskPOD<size>::isclear(const Uint32 data[])
{
return BitmaskImpl::isclear(size, data);
}
template <unsigned size>
inline bool
Bitmask<size>::isclear() const
BitmaskPOD<size>::isclear() const
{
return isclear(rep.data);
}
template <unsigned size>
unsigned
Bitmask<size>::count(const Uint32 data[])
BitmaskPOD<size>::count(const Uint32 data[])
{
return BitmaskImpl::count(size, data);
}
template <unsigned size>
inline unsigned
Bitmask<size>::count() const
BitmaskPOD<size>::count() const
{
return count(rep.data);
}
template <unsigned size>
unsigned
Bitmask<size>::find(const Uint32 data[], unsigned n)
BitmaskPOD<size>::find(const Uint32 data[], unsigned n)
{
return BitmaskImpl::find(size, data, n);
}
template <unsigned size>
inline unsigned
Bitmask<size>::find(unsigned n) const
BitmaskPOD<size>::find(unsigned n) const
{
return find(rep.data, n);
}
template <unsigned size>
inline bool
Bitmask<size>::equal(const Uint32 data[], const Uint32 data2[])
BitmaskPOD<size>::equal(const Uint32 data[], const Uint32 data2[])
{
return BitmaskImpl::equal(size, data, data2);
}
template <unsigned size>
inline bool
Bitmask<size>::equal(const Bitmask<size>& mask2) const
BitmaskPOD<size>::equal(const BitmaskPOD<size>& mask2) const
{
return equal(rep.data, mask2.rep.data);
}
template <unsigned size>
inline void
Bitmask<size>::bitOR(Uint32 data[], const Uint32 data2[])
BitmaskPOD<size>::bitOR(Uint32 data[], const Uint32 data2[])
{
BitmaskImpl::bitOR(size,data, data2);
}
template <unsigned size>
inline Bitmask<size>&
Bitmask<size>::bitOR(const Bitmask<size>& mask2)
inline BitmaskPOD<size>&
BitmaskPOD<size>::bitOR(const BitmaskPOD<size>& mask2)
{
bitOR(rep.data, mask2.rep.data);
return *this;
......@@ -676,14 +674,14 @@ Bitmask<size>::bitOR(const Bitmask<size>& mask2)
template <unsigned size>
inline void
Bitmask<size>::bitAND(Uint32 data[], const Uint32 data2[])
BitmaskPOD<size>::bitAND(Uint32 data[], const Uint32 data2[])
{
BitmaskImpl::bitAND(size,data, data2);
}
template <unsigned size>
inline Bitmask<size>&
Bitmask<size>::bitAND(const Bitmask<size>& mask2)
inline BitmaskPOD<size>&
BitmaskPOD<size>::bitAND(const BitmaskPOD<size>& mask2)
{
bitAND(rep.data, mask2.rep.data);
return *this;
......@@ -691,14 +689,14 @@ Bitmask<size>::bitAND(const Bitmask<size>& mask2)
template <unsigned size>
inline void
Bitmask<size>::bitANDC(Uint32 data[], const Uint32 data2[])
BitmaskPOD<size>::bitANDC(Uint32 data[], const Uint32 data2[])
{
BitmaskImpl::bitANDC(size,data, data2);
}
template <unsigned size>
inline Bitmask<size>&
Bitmask<size>::bitANDC(const Bitmask<size>& mask2)
inline BitmaskPOD<size>&
BitmaskPOD<size>::bitANDC(const BitmaskPOD<size>& mask2)
{
bitANDC(rep.data, mask2.rep.data);
return *this;
......@@ -706,14 +704,14 @@ Bitmask<size>::bitANDC(const Bitmask<size>& mask2)
template <unsigned size>
inline void
Bitmask<size>::bitXOR(Uint32 data[], const Uint32 data2[])
BitmaskPOD<size>::bitXOR(Uint32 data[], const Uint32 data2[])
{
BitmaskImpl::bitXOR(size,data, data2);
}
template <unsigned size>
inline Bitmask<size>&
Bitmask<size>::bitXOR(const Bitmask<size>& mask2)
inline BitmaskPOD<size>&
BitmaskPOD<size>::bitXOR(const BitmaskPOD<size>& mask2)
{
bitXOR(rep.data, mask2.rep.data);
return *this;
......@@ -721,44 +719,50 @@ Bitmask<size>::bitXOR(const Bitmask<size>& mask2)
template <unsigned size>
char *
Bitmask<size>::getText(const Uint32 data[], char* buf)
BitmaskPOD<size>::getText(const Uint32 data[], char* buf)
{
return BitmaskImpl::getText(size, data, buf);
}
template <unsigned size>
inline char *
Bitmask<size>::getText(char* buf) const
BitmaskPOD<size>::getText(char* buf) const
{
return getText(rep.data, buf);
}
template <unsigned size>
inline bool
Bitmask<size>::contains(Uint32 data[], const Uint32 data2[])
BitmaskPOD<size>::contains(Uint32 data[], const Uint32 data2[])
{
return BitmaskImpl::contains(size, data, data2);
}
template <unsigned size>
inline bool
Bitmask<size>::contains(Bitmask<size> that)
BitmaskPOD<size>::contains(BitmaskPOD<size> that)
{
return contains(this->rep.data, that.rep.data);
}
template <unsigned size>
inline bool
Bitmask<size>::overlaps(Uint32 data[], const Uint32 data2[])
BitmaskPOD<size>::overlaps(Uint32 data[], const Uint32 data2[])
{
return BitmaskImpl::overlaps(size, data, data2);
}
template <unsigned size>
inline bool
Bitmask<size>::overlaps(Bitmask<size> that)
BitmaskPOD<size>::overlaps(BitmaskPOD<size> that)
{
return overlaps(this->rep.data, that.rep.data);
}
template <unsigned size>
class Bitmask : public BitmaskPOD<size> {
public:
Bitmask() { clear();}
};
#endif
......@@ -28,9 +28,9 @@ public:
class SocketAuthSimple : public SocketAuthenticator
{
const char *m_passwd;
char *m_buf;
const char *m_username;
public:
SocketAuthSimple(const char *passwd);
SocketAuthSimple(const char *username, const char *passwd);
virtual ~SocketAuthSimple();
virtual bool client_authenticate(int sockfd);
virtual bool server_authenticate(int sockfd);
......
......@@ -149,14 +149,14 @@ const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule);
bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx,
const char * rule_data);
bool add_db_ports(Vector<ConfigInfo::ConfigRuleSection>&sections,
bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx,
const char * rule_data);
const ConfigInfo::ConfigRule
ConfigInfo::m_ConfigRules[] = {
{ add_node_connections, 0 },
{ add_db_ports, 0 },
{ add_server_ports, 0 },
{ 0, 0 }
};
......@@ -329,6 +329,18 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0,
0x7FFFFFFF },
{
CFG_SYS_PORT_BASE,
"PortBase",
"SYSTEM",
"Base port for system",
ConfigInfo::USED,
false,
ConfigInfo::INT,
2202,
0,
0x7FFFFFFF },
/***************************************************************************
* DB
***************************************************************************/
......@@ -2527,6 +2539,17 @@ fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data){
const char * 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 "
......@@ -3261,10 +3284,42 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
return true;
}
bool add_db_ports(Vector<ConfigInfo::ConfigRuleSection>&sections,
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 = 2202;
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;
}
......@@ -69,7 +69,7 @@ Transporter::Transporter(TransporterRegistry &t_reg,
{
unsigned short tmp_port= 3307+rNodeId;
m_socket_client= new SocketClient(remoteHostName, tmp_port,
new SocketAuthSimple("ndbd passwd"));
new SocketAuthSimple("ndbd", "ndbd passwd"));
}
}
......
......@@ -1180,7 +1180,7 @@ TransporterRegistry::start_service(SocketServer& socket_server)
}
#endif
m_transporter_service = new TransporterService(new SocketAuthSimple("ndbd passwd"));
m_transporter_service = new TransporterService(new SocketAuthSimple("ndbd", "ndbd passwd"));
if (nodeIdSpecified != true) {
ndbout_c("TransporterRegistry::startReceiving: localNodeId not specified");
......
......@@ -19,45 +19,73 @@
#include <SocketClient.hpp>
#include <SocketAuthenticator.hpp>
#include <InputStream.hpp>
#include <OutputStream.hpp>
#include <NdbOut.hpp>
SocketAuthSimple::SocketAuthSimple(const char *passwd) {
SocketAuthSimple::SocketAuthSimple(const char *username, const char *passwd) {
if (username)
m_username= strdup(username);
else
m_username= 0;
if (passwd)
m_passwd= strdup(passwd);
m_buf= (char*)malloc(strlen(passwd)+1);
else
m_passwd= 0;
}
SocketAuthSimple::~SocketAuthSimple()
{
if (m_passwd)
free((void*)m_passwd);
if (m_buf)
free(m_buf);
if (m_username)
free((void*)m_username);
}
bool SocketAuthSimple::client_authenticate(int sockfd)
{
if (!m_passwd)
return false;
SocketOutputStream s_output(sockfd);
SocketInputStream s_input(sockfd);
int len = strlen(m_passwd);
int r;
r= send(sockfd, m_passwd, len, 0);
if (m_username)
s_output.println("%s", m_username);
else
s_output.println("");
r= recv(sockfd, m_buf, len, 0);
m_buf[r]= '\0';
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)
{
if (!m_passwd)
return false;
int len = strlen(m_passwd), r;
r= recv(sockfd, m_buf, len, 0);
m_buf[r]= '\0';
r= send(sockfd, m_passwd, len, 0);
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;
}
......@@ -1979,8 +1979,7 @@ void Qmgr::execAPI_REGREQ(Signal* signal)
apiRegConf->nodeState.dynamicId = -dynamicId;
}
}
c_connectedNodes.copyto(NdbNodeBitmask::Size,
apiRegConf->connected_nodes.data);
apiRegConf->nodeState.m_connected_nodes.assign(c_connectedNodes);
sendSignal(ref, GSN_API_REGCONF, signal, ApiRegConf::SignalLength, JBB);
......
......@@ -506,7 +506,8 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
_ownReference(0),
theSignalIdleList(NULL),
theWaitState(WAIT_SUBSCRIBE_CONF),
theConfCount(0) {
theConfCount(0),
m_allocated_resources(*this) {
_config = NULL;
_isStatPortActive = false;
......@@ -578,11 +579,15 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
_props = NULL;
_ownNodeId= 0;
NodeId tmp= nodeId > 0 ? nodeId-1 : 0;
if (getNextFreeNodeId(&tmp, NDB_MGM_NODE_TYPE_MGM)){
NodeId tmp= nodeId;
if (getFreeNodeId(&tmp, NDB_MGM_NODE_TYPE_MGM, 0, 0)){
_ownNodeId= tmp;
if (nodeId != 0 && nodeId != tmp)
if (nodeId != 0 && nodeId != tmp) {
ndbout << "Unable to obtain requested nodeid " << nodeId
<< " nodeid " << tmp << " available\n";
_ownNodeId= 0; // did not get nodeid requested
}
m_allocated_resources.reserve_node(_ownNodeId);
} else
NDB_ASSERT(0, "Unable to retrieve own node id");
}
......@@ -671,8 +676,7 @@ MgmtSrvr::~MgmtSrvr()
stopEventLog();
NdbCondition_Destroy(theMgmtWaitForResponseCondPtr);
NdbMutex_Destroy(m_configMutex);
NdbCondition_Destroy(theMgmtWaitForResponseCondPtr); NdbMutex_Destroy(m_configMutex);
if(m_newConfig != NULL)
free(m_newConfig);
......@@ -916,7 +920,7 @@ MgmtSrvr::restart(bool nostart, bool initalStart, bool abort,
return 0;
}
TransporterFacade::instance()->lock_mutex();
theFacade->lock_mutex();
int waitTime = timeOut/m_stopRec.sentCount;
if (receiveOptimisedResponse(waitTime) != 0) {
m_stopRec.inUse = false;
......@@ -1091,8 +1095,7 @@ MgmtSrvr::version(int * stopCount, bool abort,
}
for(Uint32 i = 0; i<MAX_NODES; i++) {
if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
node =
TransporterFacade::instance()->theClusterMgr->getNodeInfo(i);
node = theFacade->theClusterMgr->getNodeInfo(i);
version = node.m_info.m_version;
if(theFacade->theClusterMgr->getNodeInfo(i).connected)
m_versionRec.callback(i, version, this,0);
......@@ -1246,7 +1249,7 @@ MgmtSrvr::stop(int * stopCount, bool abort, StopCallback callback,
if(m_stopRec.sentCount > 0){
if(callback == 0){
TransporterFacade::instance()->lock_mutex();
theFacade->lock_mutex();
receiveOptimisedResponse(timeOut / m_stopRec.sentCount);
} else {
return 0;
......@@ -1276,7 +1279,7 @@ MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId,
for(Uint32 i = 0; i<MAX_NODES; i++) {
if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
node = TransporterFacade::instance()->theClusterMgr->getNodeInfo(i);
node = theFacade->theClusterMgr->getNodeInfo(i);
if((node.m_state.startLevel != NodeState::SL_STARTED) &&
(node.m_state.startLevel != NodeState::SL_NOTHING)) {
return 5063;
......@@ -1435,7 +1438,7 @@ MgmtSrvr::status(int processId,
}
const ClusterMgr::Node node =
TransporterFacade::instance()->theClusterMgr->getNodeInfo(processId);
theFacade->theClusterMgr->getNodeInfo(processId);
if(!node.connected){
* _status = NDB_MGM_NODE_STATUS_NO_CONTACT;
......@@ -2099,8 +2102,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
req->senderData = 19;
req->backupDataLen = 0;
int i = TransporterFacade::instance()->sendSignalUnCond(&aSignal,
aNodeId);
int i = theFacade->sendSignalUnCond(&aSignal, aNodeId);
if(i == 0){
return;
}
......@@ -2182,7 +2184,7 @@ MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode)
bool failure = true;
for(Uint32 i = 0; i<MAX_NODES; i++) {
if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
node = TransporterFacade::instance()->theClusterMgr->getNodeInfo(i);
node = theFacade->theClusterMgr->getNodeInfo(i);
if((node.m_state.startLevel == NodeState::SL_NOTHING))
failure = true;
else
......@@ -2287,30 +2289,60 @@ MgmtSrvr::getNodeType(NodeId nodeId) const
}
bool
MgmtSrvr::getNextFreeNodeId(NodeId * nodeId,
enum ndb_mgm_node_type type) const
MgmtSrvr::getFreeNodeId(NodeId * nodeId, enum ndb_mgm_node_type type,
struct sockaddr *client_addr, socklen_t *client_addr_len) const
{
#if 0
ndbout << "MgmtSrvr::getNextFreeNodeId type=" << type
ndbout << "MgmtSrvr::getFreeNodeId type=" << type
<< " *nodeid=" << *nodeId << endl;
#endif
NodeId tmp= *nodeId;
NodeBitmask connected_nodes(m_reserved_nodes);
if (theFacade && theFacade->theClusterMgr) {
while(getNextNodeId(&tmp, type)){
if (theFacade->theClusterMgr->m_connected_nodes.get(tmp))
for(Uint32 i = 0; i < MAX_NODES; i++)
if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
const ClusterMgr::Node &node= theFacade->theClusterMgr->getNodeInfo(i);
if (node.connected)
connected_nodes.bitOR(node.m_state.m_connected_nodes);
}
}
ndb_mgm_configuration_iterator iter(*(ndb_mgm_configuration *)_config->m_configValues,
CFG_SECTION_NODE);
for(iter.first(); iter.valid(); iter.next()) {
unsigned tmp= 0;
if(iter.get(CFG_NODE_ID, &tmp)) abort();
if (connected_nodes.get(tmp))
continue;
if (*nodeId && *nodeId != tmp)
continue;
unsigned type_c;
if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) abort();
if(type_c != type)
continue;
const char *config_hostname = 0;
if(iter.get(CFG_NODE_HOST, &config_hostname)) abort();
// getsockname(int s, struct sockaddr *name, socklen_t *namelen);
if (config_hostname && config_hostname[0] != 0) {
// check hostname compatability
struct in_addr config_addr;
if(Ndb_getInAddr(&config_addr, config_hostname) != 0
|| memcmp(&config_addr, &(((sockaddr_in*)client_addr)->sin_addr),
sizeof(config_addr)) != 0) {
#if 0
ndbout << "MgmtSrvr::getNextFreeNodeId ret=" << tmp << endl;
ndbout << "MgmtSrvr::getFreeNodeId compare failed for \"" << config_hostname
<< "\" id=" << tmp << endl;
#endif
*nodeId= tmp;
return true;
continue;
}
}
} else if (getNextNodeId(&tmp, type)){
*nodeId= tmp;
#if 0
ndbout << "MgmtSrvr::getNextFreeNodeId (theFacade==0) ret=" << tmp << endl;
ndbout << "MgmtSrvr::getFreeNodeId found type=" << type
<< " *nodeid=" << *nodeId << endl;
#endif
*nodeId= tmp;
return true;
}
return false;
......@@ -2702,3 +2734,22 @@ MgmtSrvr::getPrimaryNode() const {
return 0;
#endif
}
MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m)
: m_mgmsrv(m)
{
}
MgmtSrvr::Allocated_resources::~Allocated_resources()
{
m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes);
}
void
MgmtSrvr::Allocated_resources::reserve_node(NodeId id)
{
m_reserved_nodes.set(id);
m_mgmsrv.m_reserved_nodes.set(id);
}
......@@ -68,6 +68,18 @@ public:
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.
*/
......@@ -450,7 +462,8 @@ public:
* @return false if none found
*/
bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ;
bool getNextFreeNodeId(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 ;
/**
*
......@@ -501,7 +514,6 @@ public:
*/
int getPort() const;
//**************************************************************************
private:
//**************************************************************************
......@@ -539,12 +551,13 @@ private:
BaseString m_localNdbConfigFilename;
Uint32 m_nextConfigGenerationNumber;
NodeBitmask m_reserved_nodes;
Allocated_resources m_allocated_resources;
int _setVarReqResult; // The result of the SET_VAR_REQ response
Statistics _statistics; // handleSTATISTICS_CONF store the result here,
// and getStatistics reads it.
//**************************************************************************
// Specific signal handling methods
//**************************************************************************
......
......@@ -232,6 +232,19 @@ MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock)
m_input = new SocketInputStream(sock);
m_output = new SocketOutputStream(sock);
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
......@@ -357,24 +370,14 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
args.get("password", &password);
args.get("public key", &public_key);
NodeId free_id= 0;
NodeId tmp= nodeid > 0 ? nodeid-1 : 0;
bool compatible;
switch (nodetype) {
case NODE_TYPE_MGM:
compatible = ndbCompatible_mgmt_api(NDB_VERSION, version);
if (m_mgmsrv.getNextFreeNodeId(&tmp, NDB_MGM_NODE_TYPE_MGM))
free_id= tmp;
break;
case NODE_TYPE_API:
compatible = ndbCompatible_mgmt_api(NDB_VERSION, version);
if (m_mgmsrv.getNextFreeNodeId(&tmp, NDB_MGM_NODE_TYPE_API))
free_id= tmp;
break;
case NODE_TYPE_DB:
compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version);
if (m_mgmsrv.getNextFreeNodeId(&tmp, NDB_MGM_NODE_TYPE_NDB))
free_id= tmp;
break;
default:
m_output->println(cmd);
......@@ -383,6 +386,20 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
return;
}
struct sockaddr addr;
socklen_t addrlen;
if (getsockname(m_socket, &addr, &addrlen)) {
m_output->println(cmd);
m_output->println("result: getsockname(%d)", m_socket);
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",
......@@ -413,6 +430,8 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
m_output->println("result: Ok");
m_output->println("");
m_allocated_resources->reserve_node(free_id);
return;
}
......
......@@ -36,6 +36,7 @@ private:
InputStream *m_input;
OutputStream *m_output;
Parser_t *m_parser;
MgmtSrvr::Allocated_resources *m_allocated_resources;
void getConfig_common(Parser_t::Context &ctx,
const class Properties &args,
......@@ -43,6 +44,7 @@ private:
public:
MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock);
virtual ~MgmApiSession();
void runSession();
void getStatPort(Parser_t::Context &ctx, const class Properties &args);
......
......@@ -167,8 +167,9 @@ NDB_MAIN(mgmsrv){
glob.cluster_config = 0;
glob.localNodeId= glob.mgmObject->getOwnNodeId();
if (glob.localNodeId == 0)
if (glob.localNodeId == 0) {
goto error_end;
}
glob.port= glob.mgmObject->getPort();
......@@ -244,8 +245,8 @@ NDB_MAIN(mgmsrv){
ndbout_c(msg);
g_EventLogger.info(msg);
snprintf(msg, 256, "Command port: %d, Statistics port: %d",
glob.port, glob.port_stats);
snprintf(msg, 256, "Id: %d, Command port: %d, Statistics port: %d",
glob.localNodeId, glob.port, glob.port_stats);
ndbout_c(msg);
g_EventLogger.info(msg);
......
......@@ -301,8 +301,6 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0];
const NodeId nodeId = refToNode(apiRegConf->qmgrRef);
m_connected_nodes.assign(apiRegConf->connected_nodes);
#if 0
ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId);
#endif
......@@ -426,8 +424,6 @@ ClusterMgr::reportDisconnected(NodeId nodeId){
void
ClusterMgr::reportNodeFailed(NodeId nodeId){
m_connected_nodes.clear(nodeId);
Node & theNode = theNodes[nodeId];
theNode.m_alive = false;
......
......@@ -78,7 +78,6 @@ public:
const Node & getNodeInfo(NodeId) const;
Uint32 getNoOfConnectedNodes() const;
NodeBitmask m_connected_nodes;
private:
Uint32 noOfConnectedNodes;
......
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