#At file:///home/msvensson/mysql/6.4/
3114 Magnus Svensson 2008-11-19 [merge]
Merge
added:
storage/ndb/test/include/SocketInputStream2.hpp
storage/ndb/test/src/SocketInputStream2.cpp
modified:
storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
storage/ndb/src/mgmapi/mgmapi.cpp
storage/ndb/src/mgmapi/mgmapi_internal.h
storage/ndb/src/mgmsrv/MgmtSrvr.cpp
storage/ndb/src/mgmsrv/MgmtSrvr.hpp
storage/ndb/src/mgmsrv/Services.cpp
storage/ndb/src/mgmsrv/main.cpp
storage/ndb/test/include/NdbMgmd.hpp
storage/ndb/test/ndbapi/Makefile.am
storage/ndb/test/ndbapi/testMgm.cpp
storage/ndb/test/src/Makefile.am
=== modified file 'storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp'
--- a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp 2008-10-24 10:06:10 +0000
+++ b/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp 2008-11-19 08:53:00 +0000
@@ -275,8 +275,10 @@ ConfigRetriever::verifyConfig(const stru
if (hostname && hostname[0] != 0 &&
!SocketServer::tryBind(0,hostname)) {
BaseString::snprintf(buf, 255,
- "Config hostname: %s don't match a local "
- "interface, tried to bind, error: %d '%s'",
+ "The hostname this node should have according "
+ "to the configuration does not match a local "
+ "interface. Attempt to bind '%s' "
+ "failed with error: %d '%s'",
hostname, errno, strerror(errno));
setError(CR_ERROR, buf);
return false;
=== modified file 'storage/ndb/src/mgmapi/mgmapi.cpp'
--- a/storage/ndb/src/mgmapi/mgmapi.cpp 2008-11-19 10:34:01 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp 2008-11-19 14:47:19 +0000
@@ -3342,4 +3342,9 @@ int ndb_mgm_ndbinfo_getrow(NdbMgmHandle
return 0;
}
+NDB_SOCKET_TYPE _ndb_mgm_get_socket(NdbMgmHandle h)
+{
+ return h->socket;
+}
+
template class Vector<const ParserRow<ParserDummy>*>;
=== modified file 'storage/ndb/src/mgmapi/mgmapi_internal.h'
--- a/storage/ndb/src/mgmapi/mgmapi_internal.h 2008-09-12 09:09:01 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi_internal.h 2008-11-19 13:42:48 +0000
@@ -80,6 +80,8 @@ extern "C" {
struct ndb_mgm_configuration* config);
+ NDB_SOCKET_TYPE _ndb_mgm_get_socket(NdbMgmHandle handle);
+
#ifdef __cplusplus
}
#endif
=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2008-11-13 13:36:29 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2008-11-19 14:47:19 +0000
@@ -421,7 +421,6 @@ MgmtSrvr::init()
BaseString error_string;
if (!alloc_node_id(&nodeId, NDB_MGM_NODE_TYPE_MGM,
0, /* client_addr */
- 0, /* client_addr_len */
error_code, error_string,
0 /* log_event */ ))
{
@@ -2741,7 +2740,6 @@ bool
MgmtSrvr::alloc_node_id(NodeId * nodeId,
enum ndb_mgm_node_type type,
struct sockaddr *client_addr,
- SOCKET_SIZE_TYPE *client_addr_len,
int &error_code, BaseString &error_string,
int log_event)
{
@@ -2757,6 +2755,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
}
DBUG_RETURN(true);
}
+
Guard g(m_node_id_mutex);
int no_mgm= 0;
NodeBitmask connected_nodes(m_reserved_nodes);
@@ -2775,91 +2774,98 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
int r_config_addr= -1;
unsigned type_c= 0;
- NdbMutex_Lock(m_local_config_mutex);
- ConfigIter iter(m_local_config, CFG_SECTION_NODE);
- for(iter.first(); iter.valid(); iter.next()) {
- unsigned tmp= 0;
- if(iter.get(CFG_NODE_ID, &tmp)) require(false);
- if (*nodeId && *nodeId != tmp)
- continue;
- found_matching_id= true;
- if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) require(false);
- if(type_c != (unsigned)type)
- continue;
- found_matching_type= true;
- if (connected_nodes.get(tmp))
- continue;
- found_free_node= true;
- if(iter.get(CFG_NODE_HOST, &config_hostname)) require(false);
- if (config_hostname && config_hostname[0] == 0)
- config_hostname= 0;
- else if (client_addr) {
- // check hostname compatability
- const void *tmp_in= &(((sockaddr_in*)client_addr)->sin_addr);
- if((r_config_addr= Ndb_getInAddr(&config_addr, config_hostname)) != 0
- || memcmp(&config_addr, tmp_in, sizeof(config_addr)) != 0) {
- struct in_addr tmp_addr;
- if(Ndb_getInAddr(&tmp_addr, "localhost") != 0
- || memcmp(&tmp_addr, tmp_in, sizeof(config_addr)) != 0) {
- // not localhost
-#if 0
- ndbout << "MgmtSrvr::getFreeNodeId compare failed for \""
- << config_hostname
- << "\" id=" << tmp << endl;
-#endif
- continue;
- }
- // connecting through localhost
- // check if config_hostname is local
- if (!SocketServer::tryBind(0,config_hostname)) {
- continue;
- }
+ {
+ Guard guard_config(m_local_config_mutex);
+ ConfigIter iter(m_local_config, CFG_SECTION_NODE);
+ for(iter.first(); iter.valid(); iter.next())
+ {
+ unsigned curr_nodeid = 0;
+ require(!iter.get(CFG_NODE_ID, &curr_nodeid));
+ if (*nodeId && *nodeId != curr_nodeid)
+ continue;
+ found_matching_id = true;
+
+ require(!iter.get(CFG_TYPE_OF_SECTION, &type_c));
+ if(type_c != (unsigned)type)
+ continue;
+ found_matching_type = true;
+
+ if (connected_nodes.get(curr_nodeid))
+ continue;
+ found_free_node = true;
+
+ require(!iter.get(CFG_NODE_HOST, &config_hostname));
+ if (config_hostname && config_hostname[0] == 0)
+ config_hostname = 0;
+ else if (client_addr)
+ {
+ // check hostname compatibility
+ const void *tmp_in = &(((sockaddr_in*)client_addr)->sin_addr);
+ if((r_config_addr= Ndb_getInAddr(&config_addr, config_hostname)) != 0 ||
+ memcmp(&config_addr, tmp_in, sizeof(config_addr)) != 0)
+ {
+ struct in_addr tmp_addr;
+ if(Ndb_getInAddr(&tmp_addr, "localhost") != 0 ||
+ memcmp(&tmp_addr, tmp_in, sizeof(config_addr)) != 0)
+ {
+ // not localhost
+ continue;
+ }
+
+ // connecting through localhost
+ // check if config_hostname is local
+ if (!SocketServer::tryBind(0,config_hostname))
+ continue;
+ }
}
- } else { // client_addr == 0
- if (!SocketServer::tryBind(0,config_hostname)) {
- continue;
+ else
+ {
+ // client_addr == 0
+ if (!SocketServer::tryBind(0,config_hostname))
+ continue;
}
+
+ if (*nodeId != 0 ||
+ type != NDB_MGM_NODE_TYPE_MGM ||
+ no_mgm == 1) // any match is ok
+ {
+ if (config_hostname == 0 &&
+ *nodeId == 0 &&
+ type != NDB_MGM_NODE_TYPE_MGM)
+ {
+ if (!id_found) // only set if not set earlier
+ id_found = curr_nodeid;
+ continue; /* continue looking for a nodeid with specified hostname */
+ }
+ assert(id_found == 0);
+ id_found = curr_nodeid;
+ break;
+ }
+
+ if (id_found) // mgmt server may only have one match
+ {
+ error_string.appfmt("Ambiguous node id's %d and %d. "
+ "Suggest specifying node id in connectstring, "
+ "or specifying unique host names in config file.",
+ id_found, curr_nodeid);
+ error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
+ DBUG_RETURN(false);
+ }
+
+ if (config_hostname == 0)
+ {
+ error_string.appfmt("Ambiguity for node id %d. "
+ "Suggest specifying node id in connectstring, "
+ "or specifying unique host names in config file, "
+ "or specifying just one mgmt server in "
+ "config file.",
+ curr_nodeid);
+ error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
+ DBUG_RETURN(false);
+ }
+ id_found = curr_nodeid; // mgmt server matched, check for more matches
}
- if (*nodeId != 0 ||
- type != NDB_MGM_NODE_TYPE_MGM ||
- no_mgm == 1) { // any match is ok
-
- if (config_hostname == 0 &&
- *nodeId == 0 &&
- type != NDB_MGM_NODE_TYPE_MGM)
- {
- if (!id_found) // only set if not set earlier
- id_found= tmp;
- continue; /* continue looking for a nodeid with specified
- * hostname
- */
- }
- assert(id_found == 0);
- id_found= tmp;
- break;
- }
- if (id_found) { // mgmt server may only have one match
- error_string.appfmt("Ambiguous node id's %d and %d.\n"
- "Suggest specifying node id in connectstring,\n"
- "or specifying unique host names in config file.",
- id_found, tmp);
- NdbMutex_Unlock(m_local_config_mutex);
- error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
- DBUG_RETURN(false);
- }
- if (config_hostname == 0) {
- error_string.appfmt("Ambiguity for node id %d.\n"
- "Suggest specifying node id in connectstring,\n"
- "or specifying unique host names in config file,\n"
- "or specifying just one mgmt server in config file.",
- tmp);
- NdbMutex_Unlock(m_local_config_mutex);
- error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
- DBUG_RETURN(false);
- }
- id_found= tmp; // mgmt server matched, check for more matches
}
- NdbMutex_Unlock(m_local_config_mutex);
if (id_found && client_addr != 0)
{
=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.hpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp 2008-11-12 08:17:14 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp 2008-11-19 09:09:11 +0000
@@ -93,7 +93,6 @@ public:
NodeBitmask m_reserved_nodes;
NDB_TICKS m_alloc_timeout;
};
- NdbMutex *m_node_id_mutex;
/**
* Enable/disable eventlog log levels/severities.
@@ -358,7 +357,6 @@ public:
bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ;
bool alloc_node_id(NodeId * _nodeId, enum ndb_mgm_node_type type,
struct sockaddr *client_addr,
- SOCKET_SIZE_TYPE *client_addr_len,
int &error_code, BaseString &error_string,
int log_event = 1);
@@ -480,6 +478,8 @@ private:
NdbMutex* m_local_config_mutex;
const Config* m_local_config;
+ NdbMutex *m_node_id_mutex;
+
BlockReference _ownReference;
class ConfigManager* m_config_manager;
=== modified file 'storage/ndb/src/mgmsrv/Services.cpp'
--- a/storage/ndb/src/mgmsrv/Services.cpp 2008-11-07 11:00:38 +0000
+++ b/storage/ndb/src/mgmsrv/Services.cpp 2008-11-17 09:22:20 +0000
@@ -556,7 +556,7 @@ MgmApiSession::get_nodeid(Parser_t::Cont
NDB_TICKS tick= 0;
/* only report error on second attempt as not to clog the cluster log */
while (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype,
- (struct sockaddr*)&addr, &addrlen,
+ (struct sockaddr*)&addr,
error_code, error_string,
tick == 0 ? 0 : log_event))
{
=== modified file 'storage/ndb/src/mgmsrv/main.cpp'
--- a/storage/ndb/src/mgmsrv/main.cpp 2008-11-13 08:00:21 +0000
+++ b/storage/ndb/src/mgmsrv/main.cpp 2008-11-13 12:10:52 +0000
@@ -136,12 +136,16 @@ static void usage()
ndb_usage(short_usage_sub, load_default_groups, my_long_options);
}
+static char **defaults_argv;
static void
mgmd_exit(int result)
{
g_eventLogger->close();
+ /* Free memory allocated by 'load_defaults' */
+ free_defaults(defaults_argv);
+
ndb_end(opt_ndb_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(result);
@@ -157,6 +161,7 @@ int main(int argc, char** argv)
ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
load_defaults("my",load_default_groups,&argc,&argv);
+ defaults_argv= argv; /* Must be freed by 'free_defaults' */
int ho_error;
#ifndef DBUG_OFF
=== modified file 'storage/ndb/test/include/NdbMgmd.hpp'
--- a/storage/ndb/test/include/NdbMgmd.hpp 2008-11-05 08:03:07 +0000
+++ b/storage/ndb/test/include/NdbMgmd.hpp 2008-11-19 13:42:48 +0000
@@ -16,18 +16,28 @@
#ifndef NDB_MGMD_HPP
#define NDB_MGMD_HPP
+#include <mgmapi.h>
+#include <mgmapi_internal.h>
+
#include <BaseString.hpp>
+#include <Properties.hpp>
-#include <mgmapi.h>
-#include <mgmapi_debug.h>
+#include <OutputStream.hpp>
+#include <SocketInputStream2.hpp>
+
+#include "../../src/mgmsrv/Config.hpp"
class NdbMgmd {
BaseString m_connect_str;
NdbMgmHandle m_handle;
-
- void error(const char* msg)
+ void error(const char* msg, ...) ATTRIBUTE_FORMAT(printf, 2, 3)
{
- ndbout_c("NdbMgmd:%s", msg);
+ va_list args;
+ printf("NdbMgmd::");
+ va_start(args, msg);
+ vprintf(msg, args);
+ va_end(args);
+ printf("\n");
if (m_handle){
ndbout_c(" error: %d, line: %d, desc: %s",
@@ -78,6 +88,160 @@ public:
return true;
}
+ bool is_connected(void) {
+ if (!m_handle){
+ error("is_connected: no handle");
+ return false;
+ }
+ if (!ndb_mgm_is_connected(m_handle)){
+ error("is_connected: not connected");
+ return false;
+ }
+ return true;
+ }
+
+ bool call(const char* cmd, const Properties& args,
+ const char* cmd_reply, Properties& reply){
+
+ if (!is_connected()){
+ error("call: not connected");
+ return false;
+ }
+
+ SocketOutputStream out(_ndb_mgm_get_socket(m_handle));
+
+ if (out.println(cmd)){
+ error("call: println failed at line %d", __LINE__);
+ return false;
+ }
+
+ Properties::Iterator iter(&args);
+ const char *name;
+ while((name = iter.next()) != NULL) {
+ PropertiesType t;
+ Uint32 val_i;
+ Uint64 val_64;
+ BaseString val_s;
+
+ args.getTypeOf(name, &t);
+ switch(t) {
+ case PropertiesType_Uint32:
+ args.get(name, &val_i);
+ if (out.println("%s: %d", name, val_i)){
+ error("call: println failed at line %d", __LINE__);
+ return false;
+ }
+ break;
+ case PropertiesType_Uint64:
+ args.get(name, &val_64);
+ if (out.println("%s: %Ld", name, val_64)){
+ error("call: println failed at line %d", __LINE__);
+ return false;
+ }
+ break;
+ case PropertiesType_char:
+ args.get(name, val_s);
+ if (out.println("%s: %s", name, val_s.c_str())){
+ error("call: println failed at line %d", __LINE__);
+ return false;
+ }
+ break;
+ default:
+ case PropertiesType_Properties:
+ /* Illegal */
+ abort();
+ break;
+ }
+ }
+ if (out.print("\n")){
+ error("call: print('\n') failed at line %d", __LINE__);
+ return false;
+ }
+
+
+ // Read the reply
+ BaseString buf;
+ SocketInputStream2 in(_ndb_mgm_get_socket(m_handle));
+ if (!in.gets(buf)){
+ error("call: could not read reply command");
+ return false;
+ }
+
+ // 1. Check correct reply header
+ if (buf != cmd_reply){
+ error("call: unexpected reply command, expected: '%s', got '%s'",
+ cmd_reply, buf.c_str());
+ return false;
+ }
+
+ // 2. Read colon separated name value pairs until empty line
+ while(in.gets(buf)){
+
+ // empty line -> end of reply
+ if (buf == "")
+ return true;
+
+ // Split the name value pair on first ':'
+ Vector<BaseString> name_value_pair;
+ if (buf.split(name_value_pair, ":", 2) != 2){
+ error("call: illegal name value pair '%s' received", buf.c_str());
+ return false;
+ }
+
+ reply.put(name_value_pair[0].trim(" ").c_str(),
+ name_value_pair[1].trim(" ").c_str());
+ }
+
+ error("call: should never come here");
+ abort();
+ return false;
+ }
+
+
+ bool get_config(Config& config){
+
+ if (!is_connected()){
+ error("get_config: not connected");
+ return false;
+ }
+
+ struct ndb_mgm_configuration* conf =
+ ndb_mgm_get_configuration(m_handle,0);
+ if (!conf) {
+ error("get_config: ndb_mgm_get_configuration failed");
+ return false;
+ }
+
+ config.m_configValues= conf;
+ return true;
+ }
+
+ bool end_session(void){
+ if (!is_connected()){
+ error("end_session: not connected");
+ return false;
+ }
+
+ if (ndb_mgm_end_session(m_handle) != 0){
+ error("end_session: ndb_mgm_end_session failed");
+ return false;
+ }
+ return true;
+ }
+
+ // Pretty printer for 'ndb_mgm_node_type'
+ class NodeType {
+ BaseString m_str;
+ public:
+ NodeType(Uint32 node_type) {
+ const char* str= NULL;
+ const char* alias=
+ ndb_mgm_get_node_type_alias_string((ndb_mgm_node_type)node_type, &str);
+ m_str.assfmt("%s(%s)", alias, str);
+ }
+
+ const char* c_str() { return m_str.c_str(); }
+ };
};
#endif
=== added file 'storage/ndb/test/include/SocketInputStream2.hpp'
--- a/storage/ndb/test/include/SocketInputStream2.hpp 1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/include/SocketInputStream2.hpp 2008-11-19 13:42:48 +0000
@@ -0,0 +1,55 @@
+/* Copyright (C) 2008 Sun Microsystems Inc.
+
+ 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; version 2 of the License.
+
+ 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 SOCKETINPUTSTREAM2_HPP
+#define SOCKETINPUTSTREAM2_HPP
+
+#include <NdbTCP.h>
+#include <BaseString.hpp>
+#include <UtilBuffer.hpp>
+
+class SocketInputStream2 {
+ NDB_SOCKET_TYPE m_socket;
+ unsigned m_read_timeout;
+ UtilBuffer m_buffer;
+ size_t m_buffer_read_pos;
+
+ bool has_data_to_read();
+ ssize_t read_socket(char* buf, size_t len);
+ bool get_buffered_line(BaseString& str);
+ bool add_buffer(char* buf, ssize_t len);
+
+public:
+ SocketInputStream2(NDB_SOCKET_TYPE socket,
+ unsigned read_timeout = 60) :
+ m_socket(socket),
+ m_read_timeout(read_timeout),
+ m_buffer_read_pos(0)
+ {};
+
+ /*
+ Read a line from socket into the string "str" until
+ either terminating newline, EOF or read timeout encountered.
+
+ Returns:
+ true - a line ended with newline was read from socket
+ false - EOF or read timeout occured
+
+ */
+ bool gets(BaseString& str);
+
+};
+
+#endif
=== modified file 'storage/ndb/test/ndbapi/Makefile.am'
--- a/storage/ndb/test/ndbapi/Makefile.am 2008-11-19 10:34:01 +0000
+++ b/storage/ndb/test/ndbapi/Makefile.am 2008-11-19 14:47:19 +0000
@@ -90,7 +90,10 @@ testDataBuffers_SOURCES = testDataBuffer
testDict_SOURCES = testDict.cpp
testIndex_SOURCES = testIndex.cpp
testLimits_SOURCES = testLimits.cpp
-testMgm_SOURCES = testMgm.cpp
+testMgm_SOURCES = testMgm.cpp \
+ $(top_srcdir)/storage/ndb/src/mgmsrv/Config.cpp \
+ $(top_srcdir)/storage/ndb/src/mgmsrv/ConfigInfo.cpp \
+ $(top_srcdir)/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
testMgm_CXXFLAGS = -I$(top_srcdir)/storage/ndb/src/mgmapi
testSingleUserMode_SOURCES = testSingleUserMode.cpp
testNdbApi_SOURCES = testNdbApi.cpp
=== modified file 'storage/ndb/test/ndbapi/testMgm.cpp'
--- a/storage/ndb/test/ndbapi/testMgm.cpp 2008-11-06 16:28:49 +0000
+++ b/storage/ndb/test/ndbapi/testMgm.cpp 2008-11-19 13:42:48 +0000
@@ -675,6 +675,17 @@ int runSetConfig(NDBT_Context* ctx, NDBT
}
+int runSetConfigUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result= NDBT_OK;
+ while(!ctx->isTestStopped() &&
+ (result= runSetConfig(ctx, step)) == NDBT_OK)
+ ;
+ ctx->stopTest();
+ return result;
+}
+
+
int runGetConfig(NDBT_Context* ctx, NDBT_Step* step)
{
NdbMgmd mgmd;
@@ -695,11 +706,20 @@ int runGetConfig(NDBT_Context* ctx, NDBT
}
-int getMgmLogInfo(NdbMgmHandle h, off_t *current_size, off_t *max_size)
+int runGetConfigUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
{
- NdbMgmd mgmd;
+ int result= NDBT_OK;
+ while(!ctx->isTestStopped() &&
+ (result= runGetConfig(ctx, step)) == NDBT_OK)
+ ;
+ ctx->stopTest();
+ return result;
+}
- const char *mgm= mgmd.getConnectString();
+
+
+int getMgmLogInfo(NdbMgmHandle h, off_t *current_size, off_t *max_size)
+{
int r, ncol;
char rowbuf[1024];
char **cols;
@@ -749,8 +769,8 @@ int getMgmLogInfo(NdbMgmHandle h, off_t
}
- ndbout_c("CURRENT SIZE = %llu",*current_size);
- ndbout_c("MAX SIZE = %llu",*max_size);
+ ndbout_c("CURRENT SIZE = %lu",*current_size);
+ ndbout_c("MAX SIZE = %lu",*max_size);
free(cols);
@@ -762,7 +782,6 @@ int runTestMgmLogRotation(NDBT_Context*
NdbMgmd mgmd;
const char *mgm= mgmd.getConnectString();
int result= NDBT_FAILED;
- const char *logdest= NULL;
int mgmid= 0;
off_t current_size= 0, max_size= 0;
int i,j;
@@ -848,8 +867,6 @@ done:
int runTestStatus(NDBT_Context* ctx, NDBT_Step* step)
{
- NdbMgmHandle h;
-
ndb_mgm_node_type types[2] = {
NDB_MGM_NODE_TYPE_NDB,
NDB_MGM_NODE_TYPE_UNKNOWN
@@ -857,35 +874,16 @@ int runTestStatus(NDBT_Context* ctx, NDB
NdbMgmd mgmd;
struct ndb_mgm_cluster_state *state;
- const char *connectstring= mgmd.getConnectString();
int iterations = ctx->getNumLoops();
int delay = 2;
- h= ndb_mgm_create_handle();
- if ( h == 0)
- {
- ndbout_c("Unable to create handle");
- return NDBT_FAILED;
- }
- if (ndb_mgm_set_connectstring(h, connectstring) == -1)
- {
- ndbout_c("Unable to set connectstring");
- ndb_mgm_destroy_handle(&h);
- return NDBT_FAILED;
- }
- if (ndb_mgm_connect(h,0,0,0))
- {
- ndbout_c("connect failed, %d: %s",
- ndb_mgm_get_latest_error(h),
- ndb_mgm_get_latest_error_msg(h));
- ndb_mgm_destroy_handle(&h);
+ if (!mgmd.connect())
return NDBT_FAILED;
- }
int result= NDBT_OK;
while (iterations-- != 0 && result == NDBT_OK)
{
- state = ndb_mgm_get_status(h);
+ state = ndb_mgm_get_status(mgmd.handle());
if(state == NULL) {
ndbout_c("Could not get status!");
result= NDBT_FAILED;
@@ -893,7 +891,7 @@ int runTestStatus(NDBT_Context* ctx, NDB
}
free(state);
- state = ndb_mgm_get_status2(h, types);
+ state = ndb_mgm_get_status2(mgmd.handle(), types);
if(state == NULL){
ndbout_c("Could not get status2!");
result= NDBT_FAILED;
@@ -901,23 +899,364 @@ int runTestStatus(NDBT_Context* ctx, NDB
}
free(state);
- state = ndb_mgm_get_status2(h, 0);
+ state = ndb_mgm_get_status2(mgmd.handle(), 0);
if(state == NULL){
ndbout_c("Could not get status2 second time!");
result= NDBT_FAILED;
continue;
}
free(state);
+ }
+ return result;
+}
+
+
+int runTestStatusUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result= NDBT_OK;
+ while(!ctx->isTestStopped() &&
+ (result= runTestStatus(ctx, step)) == NDBT_OK)
+ ;
+ ctx->stopTest();
+ return result;
+}
+
+
+static bool
+get_nodeid(NdbMgmd& mgmd,
+ const Properties& args,
+ Properties& reply)
+{
+ // Fill in default values of other args
+ Properties call_args(args);
+ if (!call_args.contains("version"))
+ call_args.put("version", 1);
+ if (!call_args.contains("nodetype"))
+ call_args.put("nodetype", 1);
+ if (!call_args.contains("nodeid"))
+ call_args.put("nodeid", 1);
+ if (!call_args.contains("user"))
+ call_args.put("user", "mysqld");
+ if (!call_args.contains("password"))
+ call_args.put("password", "mysqld");
+ if (!call_args.contains("public key"))
+ call_args.put("public key", "a public key");
+ if (!call_args.contains("name"))
+ call_args.put("name", "testMgm");
+ if (!call_args.contains("log_event"))
+ call_args.put("log_event", 1);
+ if (!call_args.contains("timeout"))
+ call_args.put("timeout", 100);
+
+ if (!call_args.contains("endian"))
+ {
+ union { long l; char c[sizeof(long)]; } endian_check;
+ endian_check.l = 1;
+ call_args.put("endian", (endian_check.c[sizeof(long)-1])?"big":"little");
+ }
+
+ if (!mgmd.call("get nodeid", call_args,
+ "get nodeid reply", reply))
+ {
+ g_err << "get_nodeid: mgmd.call failed" << endl;
+ return false;
+ }
+
+ // reply.print();
+ return true;
+}
+
+
+static const char*
+get_result(const Properties& reply)
+{
+ const char* result;
+ if (!reply.get("result", &result)){
+ ndbout_c("result: no 'result' found in reply");
+ return NULL;
+ }
+ return result;
+}
+
+
+static bool result_contains(const Properties& reply,
+ const char* expected_result)
+{
+ BaseString result(get_result(reply));
+ if (strstr(result.c_str(), expected_result) == NULL){
+ ndbout_c("result_contains: result string '%s' "
+ "didn't contain expected result '%s'",
+ result.c_str(), expected_result);
+ return false;
+ }
+ g_info << " result: " << result << endl;
+ return true;
+}
+
+
+static bool ok(const Properties& reply)
+{
+ BaseString result(get_result(reply));
+ if (result == "Ok")
+ return true;
+ return false;
+}
+
+
+static bool get_nodeid_result_contains(NdbMgmd& mgmd,
+ const Properties& args,
+ const char* expected_result)
+{
+ Properties reply;
+ if (!get_nodeid(mgmd, args, reply))
+ return false;
+ return result_contains(reply, expected_result);
+}
+
+
+
+static bool
+check_get_nodeid_invalid_endian1(NdbMgmd& mgmd)
+{
+ union { long l; char c[sizeof(long)]; } endian_check;
+ endian_check.l = 1;
+ Properties args;
+ /* Set endian to opposite value */
+ args.put("endian", (endian_check.c[sizeof(long)-1])?"little":"big");
+ return get_nodeid_result_contains(mgmd, args,
+ "Node does not have the same endian");
+}
+
+
+static bool
+check_get_nodeid_invalid_endian2(NdbMgmd& mgmd)
+{
+ Properties args;
+ /* Set endian to weird value */
+ args.put("endian", "hepp");
+ return get_nodeid_result_contains(mgmd, args,
+ "Node does not have the same endian");
+}
+
+
+static bool
+check_get_nodeid_invalid_nodetype1(NdbMgmd& mgmd)
+{
+ Properties args;
+ args.put("nodetype", 37);
+ return get_nodeid_result_contains(mgmd, args,
+ "unknown nodetype 37");
+}
+
+
+static bool
+check_get_nodeid_invalid_nodeid(NdbMgmd& mgmd)
+{
+ for (int nodeId = MAX_NODES; nodeId < MAX_NODES+2; nodeId++){
+ g_info << "Testing invalid node " << nodeId << endl;;
+
+ Properties args;
+ args.put("nodeid", nodeId);
+ BaseString expected;
+ expected.assfmt("No node defined with id=%d", nodeId);
+ if (!get_nodeid_result_contains(mgmd, args, expected.c_str()))
+ return false;
+ }
+ return true;
+}
+
+
+static bool
+check_get_nodeid_dynamic_nodeid(NdbMgmd& mgmd)
+{
+ bool result = true;
+ Uint32 nodeId= 0; // Get dynamic node id
+ for (int nodeType = NDB_MGM_NODE_TYPE_MIN;
+ nodeType < NDB_MGM_NODE_TYPE_MAX; nodeType++){
+ while(true)
+ {
+ g_info << "Testing dynamic nodeid " << nodeId
+ << ", nodeType: " << nodeType << endl;
+
+ Properties args;
+ args.put("nodeid", nodeId);
+ args.put("nodetype", nodeType);
+ Properties reply;
+ if (!get_nodeid(mgmd, args, reply))
+ return false;
+
+ /*
+ Continue to get dynamic id's until
+ an error "there is no more nodeid" occur
+ */
+ if (!ok(reply)){
+ BaseString expected;
+ expected.assfmt("No free node id found for %s",
+ NdbMgmd::NodeType(nodeType).c_str());
+ if (!result_contains(reply, expected.c_str()))
+ result= false; // Got wrong error message
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+
+static bool
+check_get_nodeid_nonode(NdbMgmd& mgmd)
+{
+ // Find a node that does not exist
+ Config conf;
+ if (!mgmd.get_config(conf))
+ return false;
+
+ Uint32 nodeId = 0;
+ for(Uint32 i= 1; i < MAX_NODES; i++){
+ ConfigIter iter(&conf, CFG_SECTION_NODE);
+ if (iter.find(CFG_NODE_ID, i) != 0){
+ nodeId = i;
+ break;
+ }
+ }
+ if (nodeId == 0)
+ return true; // All nodes probably defined
+
+ g_info << "Testing nonexisting node " << nodeId << endl;;
+
+ Properties args;
+ args.put("nodeid", nodeId);
+ BaseString expected;
+ expected.assfmt("No node defined with id=%d", nodeId);
+ return get_nodeid_result_contains(mgmd, args, expected.c_str());
+}
+
+
+static bool
+check_get_nodeid_nodeid1(NdbMgmd& mgmd)
+{
+
+ // Find a node that does exist
+ Config conf;
+ if (!mgmd.get_config(conf))
+ return false;
+
+ Uint32 nodeId = 0;
+ Uint32 nodeType = NDB_MGM_NODE_TYPE_UNKNOWN;
+ for(Uint32 i= 1; i < MAX_NODES; i++){
+ ConfigIter iter(&conf, CFG_SECTION_NODE);
+ if (iter.find(CFG_NODE_ID, i) == 0){
+ nodeId = i;
+ iter.get(CFG_TYPE_OF_SECTION, &nodeType);
+ break;
+ }
+ }
+ assert(nodeId);
+ assert(nodeType != (Uint32)NDB_MGM_NODE_TYPE_UNKNOWN);
+
+ Properties args, reply;
+ args.put("nodeid",nodeId);
+ args.put("nodetype",nodeType);
+ if (!get_nodeid(mgmd, args, reply))
+ {
+ g_err << "check_get_nodeid_nodeid1: failed for "
+ << "nodeid: " << nodeId << ", nodetype: " << nodeType << endl;
+ return false;
+ }
+ reply.print();
+ return ok(reply);
+}
+
+
+static bool
+check_get_nodeid_wrong_nodetype(NdbMgmd& mgmd)
+{
+ // Find a node that does exist
+ Config conf;
+ if (!mgmd.get_config(conf))
+ return false;
+
+ Uint32 nodeId = 0;
+ Uint32 nodeType = NDB_MGM_NODE_TYPE_UNKNOWN;
+ for(Uint32 i= 1; i < MAX_NODES; i++){
+ ConfigIter iter(&conf, CFG_SECTION_NODE);
+ if (iter.find(CFG_NODE_ID, i) == 0){
+ nodeId = i;
+ iter.get(CFG_TYPE_OF_SECTION, &nodeType);
+ break;
+ }
+ }
+ assert(nodeId && nodeType != (Uint32)NDB_MGM_NODE_TYPE_UNKNOWN);
+
+ nodeType = (nodeType + 1) / NDB_MGM_NODE_TYPE_MAX;
+ assert(nodeType > NDB_MGM_NODE_TYPE_MIN && nodeType < NDB_MGM_NODE_TYPE_MAX);
- NdbSleep_MilliSleep(delay);
+ Properties args, reply;
+ args.put("nodeid",nodeId);
+ args.put("nodeid",nodeType);
+ if (!get_nodeid(mgmd, args, reply))
+ {
+ g_err << "check_get_nodeid_nodeid1: failed for "
+ << "nodeid: " << nodeId << ", nodetype: " << nodeType << endl;
+ return false;
}
- // No disconnect, destroy should take care of that
- // ndb_mgm_disconnect(h);
- ndb_mgm_destroy_handle(&h);
+ BaseString expected;
+ expected.assfmt("Id %d configured as", nodeId);
+ return result_contains(reply, expected.c_str());
+}
+
+
+
+int runTestGetNodeId(NDBT_Context* ctx, NDBT_Step* step)
+{
+ NdbMgmd mgmd;
+
+ if (!mgmd.connect())
+ return NDBT_FAILED;
+
+ int result= NDBT_FAILED;
+ if (
+ check_get_nodeid_invalid_endian1(mgmd) &&
+ check_get_nodeid_invalid_endian2(mgmd) &&
+ check_get_nodeid_invalid_nodetype1(mgmd) &&
+// check_get_nodeid_invalid_nodeid(mgmd) &&
+ check_get_nodeid_dynamic_nodeid(mgmd) &&
+ check_get_nodeid_nonode(mgmd) &&
+// check_get_nodeid_nodeid1(mgmd) &&
+ check_get_nodeid_wrong_nodetype(mgmd) &&
+ true)
+ result= NDBT_OK;
+
+ if (!mgmd.end_session())
+ result= NDBT_FAILED;
+
+ return result;
+}
+
+
+int runTestGetNodeIdUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result= NDBT_OK;
+ while(!ctx->isTestStopped() &&
+ (result= runTestGetNodeId(ctx, step)) == NDBT_OK)
+ ;
+ ctx->stopTest();
return result;
}
+int runSleepAndStop(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int counter= 10*ctx->getNumLoops();
+
+ while(!ctx->isTestStopped() && counter--)
+ NdbSleep_SecSleep(1);;
+ ctx->stopTest();
+ return NDBT_OK;
+}
+
+
+
NDBT_TESTSUITE(testMgm);
DRIVER(DummyDriver); /* turn off use of NdbApi */
TESTCASE("ApiSessionFailure",
@@ -963,11 +1302,13 @@ TESTCASE("SetConfig",
TESTCASE("GetConfig", "Run ndb_mgm_get_configuration in parallel"){
STEPS(runGetConfig, 100);
}
+#if 0
TESTCASE("MgmLogRotation",
"Test log rotation"){
INITIALIZER(runTestMgmLogRotation);
}
+#endif
TESTCASE("TestStatus",
"Test status and status2"){
INITIALIZER(runTestStatus);
@@ -978,6 +1319,19 @@ TESTCASE("TestStatus200",
STEPS(runTestStatus, 200);
}
+TESTCASE("TestGetNodeId",
+ "Test 'get nodeid'"){
+ INITIALIZER(runTestGetNodeId);
+
+}
+TESTCASE("Stress",
+ "Run everything while changing config"){
+ STEP(runTestGetNodeIdUntilStopped);
+ STEP(runSetConfigUntilStopped);
+ STEPS(runGetConfigUntilStopped, 10);
+ STEPS(runTestStatusUntilStopped, 10);
+ STEP(runSleepAndStop);
+}
NDBT_TESTSUITE_END(testMgm);
int main(int argc, const char** argv){
=== modified file 'storage/ndb/test/src/Makefile.am'
--- a/storage/ndb/test/src/Makefile.am 2008-08-26 14:20:06 +0000
+++ b/storage/ndb/test/src/Makefile.am 2008-11-19 13:42:48 +0000
@@ -26,7 +26,8 @@ libNDBT_a_SOURCES = \
NdbRestarter.cpp NdbRestarts.cpp NDBT_Output.cpp \
NdbBackup.cpp NdbConfig.cpp NDBT_Table.cpp \
NdbSchemaCon.cpp NdbSchemaOp.cpp getarg.c AtrtClient.cpp \
- CpcClient.cpp NdbMixRestarter.cpp NDBT_Thread.cpp DbUtil.cpp
+ CpcClient.cpp NdbMixRestarter.cpp NDBT_Thread.cpp DbUtil.cpp \
+ SocketInputStream2.cpp
INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/common/mgmcommon -I$(top_srcdir)/storage/ndb/include/mgmcommon -I$(top_srcdir)/storage/ndb/include/kernel -I$(top_srcdir)/storage/ndb/src/mgmapi -I$(top_srcdir)/include
=== added file 'storage/ndb/test/src/SocketInputStream2.cpp'
--- a/storage/ndb/test/src/SocketInputStream2.cpp 1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/src/SocketInputStream2.cpp 2008-11-19 13:42:48 +0000
@@ -0,0 +1,120 @@
+/* Copyright (C) 2008 Sun Microsystems Inc.
+
+ 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; version 2 of the License.
+
+ 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 <SocketInputStream2.hpp>
+
+#include <NdbOut.hpp>
+
+bool
+SocketInputStream2::gets(BaseString& str)
+{
+ if (get_buffered_line(str))
+ return true;
+
+ char buf[16];
+ do {
+ ssize_t read_res = read_socket(buf, sizeof(buf));
+ if (read_res == -1)
+ return false;
+
+ if (!add_buffer(buf, read_res))
+ return false;
+
+ if (get_buffered_line(str))
+ return true;
+
+ } while(true);
+
+ abort(); // Should never come here
+ return false;
+};
+
+
+bool
+SocketInputStream2::has_data_to_read()
+{
+ fd_set readset;
+ FD_ZERO(&readset);
+ my_FD_SET(m_socket, &readset);
+
+ struct timeval timeout;
+ timeout.tv_sec = m_read_timeout;
+ timeout.tv_usec = 0;
+
+ const int res = select(my_socket_nfds(m_socket, 0) + 1,
+ &readset, 0, 0, &timeout);
+
+ if (res == 1)
+ return true; // Yes, there was data
+
+ if (res == 0)
+ return false; // Timeout occured
+
+ assert(res == -1);
+ return false;
+}
+
+
+ssize_t
+SocketInputStream2::read_socket(char* buf, size_t len)
+{
+ if (!has_data_to_read())
+ return -1;
+
+ size_t read_res = my_recv(m_socket, buf, len, 0);
+ if (read_res == 0)
+ return -1; // Has data to read but only EOF received
+
+ return read_res;
+}
+
+
+bool
+SocketInputStream2::get_buffered_line(BaseString& str)
+{
+ char *start, *ptr;
+ char *end = (char*)m_buffer.get_data() + m_buffer.length();
+ start = ptr =(char*)m_buffer.get_data() + m_buffer_read_pos;
+
+ while(ptr && ptr < end && *ptr)
+ {
+ if (*ptr == '\n')
+ {
+ size_t len = ptr-start;
+ /* Found end of line, return this part of the buffer */
+ str.assign(start, len);
+
+ /*
+ Set new read position in buffer, increase with
+ one to step past '\n'
+ */
+ m_buffer_read_pos += (len + 1);
+
+ return true;
+ }
+ ptr++;
+ }
+ return false;
+}
+
+
+bool
+SocketInputStream2::add_buffer(char* buf, ssize_t len)
+{
+ // ndbout_c("add_buffer: '%.*s'", len, buf);
+ if (m_buffer.append(buf, len) != 0)
+ return false;
+ return true;
+}
| Thread |
|---|
| • bzr commit into mysql-5.1 branch (msvensson:3114) | Magnus Svensson | 19 Nov |