summaryrefslogtreecommitdiff
path: root/ndb
diff options
context:
space:
mode:
authorunknown <hartmut@mysql.com>2005-09-30 18:16:57 +0200
committerunknown <hartmut@mysql.com>2005-09-30 18:16:57 +0200
commit3cb5e1fb5d228c3ce9ca0d3988c1912dd3dbd12c (patch)
treee8f6638a94b8cca6df059c2a836b5b37761c6195 /ndb
parent4cd0250267ff80403bb322cbcd3730cf2ee56ffa (diff)
parentc5d2c2e880c3832fced281bbbed9cebcee43d078 (diff)
downloadmariadb-git-3cb5e1fb5d228c3ce9ca0d3988c1912dd3dbd12c.tar.gz
Merge hholzgraefe@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/hartmut/projects/mysql/dev/5.0 ndb/tools/ndb_config.cpp: Auto merged
Diffstat (limited to 'ndb')
-rw-r--r--ndb/include/kernel/GlobalSignalNumbers.h10
-rw-r--r--ndb/include/kernel/signaldata/ApiVersion.hpp5
-rw-r--r--ndb/include/kernel/signaldata/StopReq.hpp10
-rw-r--r--ndb/include/mgmapi/ndb_logevent.h11
-rw-r--r--ndb/src/common/debugger/EventLogger.cpp24
-rw-r--r--ndb/src/common/util/SimpleProperties.cpp7
-rw-r--r--ndb/src/kernel/blocks/dbdict/Makefile.am12
-rw-r--r--ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp169
-rw-r--r--ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp65
-rw-r--r--ndb/src/kernel/blocks/qmgr/QmgrMain.cpp2
-rw-r--r--ndb/src/mgmapi/ndb_logevent.cpp2
-rw-r--r--ndb/src/mgmclient/CommandInterpreter.cpp7
-rw-r--r--ndb/src/mgmsrv/Config.cpp87
-rw-r--r--ndb/src/mgmsrv/Config.hpp10
-rw-r--r--ndb/src/mgmsrv/ConfigInfo.cpp52
-rw-r--r--ndb/src/mgmsrv/InitConfigFileParser.cpp381
-rw-r--r--ndb/src/mgmsrv/InitConfigFileParser.hpp22
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.cpp1537
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.hpp190
-rw-r--r--ndb/src/mgmsrv/MgmtSrvrConfig.cpp241
-rw-r--r--ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp120
-rw-r--r--ndb/src/mgmsrv/Services.cpp59
-rw-r--r--ndb/src/mgmsrv/Services.hpp3
-rw-r--r--ndb/src/mgmsrv/main.cpp24
-rw-r--r--ndb/tools/ndb_config.cpp175
-rw-r--r--ndb/tools/ndb_size.pl263
-rw-r--r--ndb/tools/ndb_size.tmpl175
-rw-r--r--ndb/tools/restore/consumer_restore.cpp2
28 files changed, 1833 insertions, 1832 deletions
diff --git a/ndb/include/kernel/GlobalSignalNumbers.h b/ndb/include/kernel/GlobalSignalNumbers.h
index ff3690d60a5..98b6ce7d949 100644
--- a/ndb/include/kernel/GlobalSignalNumbers.h
+++ b/ndb/include/kernel/GlobalSignalNumbers.h
@@ -553,7 +553,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_STATISTICS_CONF 454
#define GSN_START_ORD 455
-/* 456 unused */
/* 457 unused */
#define GSN_EVENT_SUBSCRIBE_REQ 458
@@ -835,14 +834,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
/* Start Global Replication */
#define GSN_GREP_REQ 656
-/**
- * Management server
- */
-#define GSN_MGM_LOCK_CONFIG_REQ 657
-#define GSN_MGM_LOCK_CONFIG_REP 658
-#define GSN_MGM_UNLOCK_CONFIG_REQ 659
-#define GSN_MGM_UNLOCK_CONFIG_REP 660
-
#define GSN_UTIL_CREATE_LOCK_REQ 132
#define GSN_UTIL_CREATE_LOCK_REF 133
#define GSN_UTIL_CREATE_LOCK_CONF 188
@@ -900,6 +891,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_RESUME_REQ 682
#define GSN_STOP_REQ 443
#define GSN_STOP_REF 444
+#define GSN_STOP_CONF 456
#define GSN_API_VERSION_REQ 697
#define GSN_API_VERSION_CONF 698
diff --git a/ndb/include/kernel/signaldata/ApiVersion.hpp b/ndb/include/kernel/signaldata/ApiVersion.hpp
index 28281e7d186..a3774c9fba6 100644
--- a/ndb/include/kernel/signaldata/ApiVersion.hpp
+++ b/ndb/include/kernel/signaldata/ApiVersion.hpp
@@ -49,12 +49,11 @@ class ApiVersionConf {
*/
friend class MgmtSrv;
public:
- STATIC_CONST( SignalLength = 3 );
+ STATIC_CONST( SignalLength = 4 );
Uint32 senderRef;
Uint32 nodeId; //api node id
Uint32 version; // Version of API node
-
-
+ Uint32 inet_addr;
};
#endif
diff --git a/ndb/include/kernel/signaldata/StopReq.hpp b/ndb/include/kernel/signaldata/StopReq.hpp
index ea453ae115d..8e6a0b90a91 100644
--- a/ndb/include/kernel/signaldata/StopReq.hpp
+++ b/ndb/include/kernel/signaldata/StopReq.hpp
@@ -67,6 +67,13 @@ public:
static bool getStopAbort(const Uint32 & requestInfo);
};
+struct StopConf
+{
+ STATIC_CONST( SignalLength = 2 );
+ Uint32 senderData;
+ Uint32 nodeState;
+};
+
class StopRef
{
/**
@@ -86,7 +93,8 @@ public:
OK = 0,
NodeShutdownInProgress = 1,
SystemShutdownInProgress = 2,
- NodeShutdownWouldCauseSystemCrash = 3
+ NodeShutdownWouldCauseSystemCrash = 3,
+ TransactionAbortFailed = 4
};
public:
diff --git a/ndb/include/mgmapi/ndb_logevent.h b/ndb/include/mgmapi/ndb_logevent.h
index d5744b0fffe..b69379545fc 100644
--- a/ndb/include/mgmapi/ndb_logevent.h
+++ b/ndb/include/mgmapi/ndb_logevent.h
@@ -148,9 +148,9 @@ extern "C" {
/** NDB_MGM_EVENT_CATEGORY_INFO */
NDB_LE_InfoEvent = 49,
- /* GREP */
- NDB_LE_GrepSubscriptionInfo = 52,
- NDB_LE_GrepSubscriptionAlert = 53,
+ /* SINGLE USER */
+ NDB_LE_SingleUser = 52,
+ /* NDB_LE_ UNUSED = 53, */
/** NDB_MGM_EVENT_CATEGORY_BACKUP */
NDB_LE_BackupStarted = 54,
@@ -593,6 +593,11 @@ extern "C" {
unsigned backup_id;
unsigned error;
} BackupAborted;
+ /** Log event data @ref NDB_LE_SingleUser */
+ struct {
+ unsigned type;
+ unsigned node_id;
+ } SingleUser;
#ifndef DOXYGEN_FIX
};
#else
diff --git a/ndb/src/common/debugger/EventLogger.cpp b/ndb/src/common/debugger/EventLogger.cpp
index d18b0feb1ad..9a1dcb8a3e1 100644
--- a/ndb/src/common/debugger/EventLogger.cpp
+++ b/ndb/src/common/debugger/EventLogger.cpp
@@ -633,6 +633,27 @@ void getTextBackupAborted(QQQQ) {
theData[3]);
}
+void getTextSingleUser(QQQQ) {
+ switch (theData[1])
+ {
+ case 0:
+ BaseString::snprintf(m_text, m_text_len, "Entering single user mode");
+ break;
+ case 1:
+ BaseString::snprintf(m_text, m_text_len,
+ "Entered single user mode "
+ "Node %d has exclusive access", theData[2]);
+ break;
+ case 2:
+ BaseString::snprintf(m_text, m_text_len,"Exiting single user mode");
+ break;
+ default:
+ BaseString::snprintf(m_text, m_text_len,
+ "Unknown single user report %d", theData[1]);
+ break;
+ }
+}
+
#if 0
BaseString::snprintf(m_text,
m_text_len,
@@ -716,6 +737,9 @@ const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = {
ROW(CreateLogBytes, LogLevel::llInfo, 11, Logger::LL_INFO ),
ROW(InfoEvent, LogLevel::llInfo, 2, Logger::LL_INFO ),
+ //Single User
+ ROW(SingleUser, LogLevel::llInfo, 7, Logger::LL_INFO ),
+
// Backup
ROW(BackupStarted, LogLevel::llBackup, 7, Logger::LL_INFO ),
ROW(BackupCompleted, LogLevel::llBackup, 7, Logger::LL_INFO ),
diff --git a/ndb/src/common/util/SimpleProperties.cpp b/ndb/src/common/util/SimpleProperties.cpp
index c25aaea491a..c9251c6a854 100644
--- a/ndb/src/common/util/SimpleProperties.cpp
+++ b/ndb/src/common/util/SimpleProperties.cpp
@@ -51,11 +51,12 @@ SimpleProperties::Writer::add(const char * value, int len){
union {
Uint32 lastWord;
char lastBytes[4];
- };
- memcpy(lastBytes,
+ } tmp;
+ tmp.lastWord =0 ;
+ memcpy(tmp.lastBytes,
value + putLen*4,
len - putLen*4);
- return putWord(lastWord);
+ return putWord(tmp.lastWord);
}
bool
diff --git a/ndb/src/kernel/blocks/dbdict/Makefile.am b/ndb/src/kernel/blocks/dbdict/Makefile.am
index 9a0d68f8148..3c1cf6735d9 100644
--- a/ndb/src/kernel/blocks/dbdict/Makefile.am
+++ b/ndb/src/kernel/blocks/dbdict/Makefile.am
@@ -1,12 +1,20 @@
-#SUBDIRS = printSchemafile
-
noinst_LIBRARIES = libdbdict.a
+EXTRA_PROGRAMS = printSchemaFile
libdbdict_a_SOURCES = Dbdict.cpp
+printSchemaFile_SOURCES = printSchemaFile.cpp
+
include $(top_srcdir)/ndb/config/common.mk.am
include $(top_srcdir)/ndb/config/type_kernel.mk.am
+LDADD += \
+ $(top_builddir)/ndb/src/common/util/libgeneral.la \
+ $(top_builddir)/ndb/src/common/portlib/libportlib.la \
+ $(top_builddir)/dbug/libdbug.a \
+ $(top_builddir)/mysys/libmysys.a \
+ $(top_builddir)/strings/libmystrings.a
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp b/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
index 9858744a61d..f73654fd9d5 100644
--- a/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
+++ b/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
@@ -1,14 +1,3 @@
-#if 0
-make -f Makefile -f - printSchemaFile <<'_eof_'
-printSchemaFile: printSchemaFile.cpp SchemaFile.hpp
- $(CXXCOMPILE) -o $@ $@.cpp -L../../../common/util/.libs -lgeneral
-ifneq ($(MYSQL_HOME),)
- ln -sf `pwd`/$@ $(MYSQL_HOME)/bin/$@
-endif
-_eof_
-exit $?
-#endif
-
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -36,14 +25,19 @@ exit $?
static const char* progname = 0;
static bool allflag = false;
static bool checkonly = false;
-static int xitcode = 0;
+static bool equalcontents = false;
+static bool okquiet = false;
static void
usage()
{
- ndbout << "Usage " << progname
- << " [-ac]"
- << " P0.SchemaLog" << endl;
+ ndbout
+ << "Usage: " << progname << " [-aceq]" << " file ..." << endl
+ << "-a print also unused slots" << endl
+ << "-c check only (return status 1 on error)" << endl
+ << "-e check also that the files have identical contents" << endl
+ << "-q no output if file is ok" << endl
+ << "Example: " << progname << " -ceq ndb_*_fs/D[12]/DBDICT/P0.SchemaLog" << endl;
}
static void
@@ -57,53 +51,78 @@ fill(const char * buf, int mod)
}
}
-static void
+static const char*
+version(Uint32 v)
+{
+ static char buf[40];
+ sprintf(buf, "%d.%d.%d", v >> 16, (v >> 8) & 0xFF, v & 0xFF);
+ return buf;
+}
+
+static int
print_head(const char * filename, const SchemaFile * sf)
{
+ int retcode = 0;
+
if (! checkonly) {
ndbout << "----- Schemafile: " << filename << " -----" << endl;
- ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %d.%d.%d FileSize: %d",
+ ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %s FileSize: %d",
sizeof(sf->Magic),
sf->Magic,
sf->ByteOrder,
- sf->NdbVersion >> 16,
- (sf->NdbVersion >> 8) & 0xFF,
- sf->NdbVersion & 0xFF,
+ version(sf->NdbVersion),
sf->FileSize);
}
+
+ if (memcmp(sf->Magic, "NDBSCHMA", sizeof(sf->Magic) != 0)) {
+ ndbout << filename << ": invalid header magic" << endl;
+ retcode = 1;
+ }
+
+ if ((sf->NdbVersion >> 16) < 4 || (sf->NdbVersion >> 16) > 9) {
+ ndbout << filename << ": impossible version " << hex << sf->NdbVersion << endl;
+ retcode = 1;
+ }
+
+ return retcode;
}
-static void
-print_old(const char * filename, const SchemaFile * sf)
+static int
+print_old(const char * filename, const SchemaFile * sf, Uint32 sz)
{
- print_head(filename, sf);
+ int retcode = 0;
+
+ if (print_head(filename, sf) != 0)
+ retcode = 1;
for (Uint32 i = 0; i < sf->NoOfTableEntries; i++) {
SchemaFile::TableEntry_old te = sf->TableEntries_old[i];
if (allflag ||
(te.m_tableState != SchemaFile::INIT &&
te.m_tableState != SchemaFile::DROP_TABLE_COMMITTED)) {
- ndbout << "Table " << i << ":"
- << " State = " << te.m_tableState
- << " version = " << table_version_major(te.m_tableVersion) <<
- << "(" << table_version_minor(te.m_tableVersion) << ")"
- << " type = " << te.m_tableType
- << " noOfPages = " << te.m_noOfPages
- << " gcp: " << te.m_gcp << endl;
+ if (! checkonly)
+ ndbout << "Table " << i << ":"
+ << " State = " << te.m_tableState
+ << " version = " << te.m_tableVersion
+ << " type = " << te.m_tableType
+ << " noOfPages = " << te.m_noOfPages
+ << " gcp: " << te.m_gcp << endl;
}
}
+ return retcode;
}
-static void
+static int
print(const char * filename, const SchemaFile * xsf, Uint32 sz)
{
int retcode = 0;
- print_head(filename, xsf);
+ if (print_head(filename, xsf) != 0)
+ retcode = 1;
assert(sizeof(SchemaFile) == NDB_SF_PAGE_SIZE);
if (xsf->FileSize != sz || xsf->FileSize % NDB_SF_PAGE_SIZE != 0) {
- ndbout << "***** invalid FileSize " << xsf->FileSize << endl;
+ ndbout << filename << ": invalid FileSize " << xsf->FileSize << endl;
retcode = 1;
}
Uint32 noOfPages = xsf->FileSize / NDB_SF_PAGE_SIZE;
@@ -112,19 +131,23 @@ print(const char * filename, const SchemaFile * xsf, Uint32 sz)
ndbout << "----- Page: " << n << " (" << noOfPages << ") -----" << endl;
}
const SchemaFile * sf = &xsf[n];
+ if (memcmp(sf->Magic, xsf->Magic, sizeof(sf->Magic)) != 0) {
+ ndbout << filename << ": page " << n << " invalid magic" << endl;
+ retcode = 1;
+ }
if (sf->FileSize != xsf->FileSize) {
- ndbout << "***** page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl;
+ ndbout << filename << ": page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl;
retcode = 1;
}
Uint32 cs = 0;
for (Uint32 j = 0; j < NDB_SF_PAGE_SIZE_IN_WORDS; j++)
cs ^= ((const Uint32*)sf)[j];
if (cs != 0) {
- ndbout << "***** page " << n << " invalid CheckSum" << endl;
+ ndbout << filename << ": page " << n << " invalid CheckSum" << endl;
retcode = 1;
}
if (sf->NoOfTableEntries != NDB_SF_PAGE_ENTRIES) {
- ndbout << "***** page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl;
+ ndbout << filename << ": page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl;
retcode = 1;
}
for (Uint32 i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
@@ -142,31 +165,41 @@ print(const char * filename, const SchemaFile * xsf, Uint32 sz)
<< " gcp: " << te.m_gcp << endl;
}
if (te.m_unused[0] != 0 || te.m_unused[1] != 0 || te.m_unused[2] != 0) {
- ndbout << "***** entry " << j << " garbage in m_unused[3]" << endl;
+ ndbout << filename << ": entry " << j << " garbage in m_unused[3]" << endl;
retcode = 1;
}
}
}
- if (retcode != 0)
- xitcode = 1;
- else if (checkonly)
- ndbout << "ok: " << filename << endl;
+ return retcode;
}
NDB_COMMAND(printSchemafile,
"printSchemafile", "printSchemafile", "Prints a schemafile", 16384)
{
progname = argv[0];
+ int exitcode = 0;
- while (argv[1][0] == '-') {
+ while (argc > 1 && argv[1][0] == '-') {
if (strchr(argv[1], 'a') != 0)
allflag = true;
if (strchr(argv[1], 'c') != 0)
checkonly = true;
+ if (strchr(argv[1], 'e') != 0)
+ equalcontents = true;
+ if (strchr(argv[1], 'q') != 0)
+ okquiet = true;
+ if (strchr(argv[1], 'h') != 0 || strchr(argv[1], '?') != 0) {
+ usage();
+ return 0;
+ }
argc--, argv++;
}
+ const char * prevfilename = 0;
+ Uint32 * prevbuf = 0;
+ Uint32 prevbytes = 0;
+
while (argc > 1) {
const char * filename = argv[1];
argc--, argv++;
@@ -174,8 +207,9 @@ NDB_COMMAND(printSchemafile,
struct stat sbuf;
const int res = stat(filename, &sbuf);
if (res != 0) {
- ndbout << "Could not find file: \"" << filename << "\"" << endl;
- return 1;
+ ndbout << filename << ": not found errno=" << errno << endl;
+ exitcode = 1;
+ continue;
}
const Uint32 bytes = sbuf.st_size;
@@ -183,25 +217,56 @@ NDB_COMMAND(printSchemafile,
FILE * f = fopen(filename, "rb");
if (f == 0) {
- ndbout << "Failed to open file" << endl;
+ ndbout << filename << ": open failed errno=" << errno << endl;
delete [] buf;
- return 1;
+ exitcode = 1;
+ continue;
}
Uint32 sz = fread(buf, 1, bytes, f);
fclose(f);
if (sz != bytes) {
- ndbout << "Failure while reading file" << endl;
+ ndbout << filename << ": read failed errno=" << errno << endl;
+ delete [] buf;
+ exitcode = 1;
+ continue;
+ }
+
+ if (sz < 32) {
+ ndbout << filename << ": too short (no header)" << endl;
delete [] buf;
- return 1;
+ exitcode = 1;
+ continue;
}
SchemaFile* sf = (SchemaFile *)&buf[0];
+ int ret;
if (sf->NdbVersion < NDB_SF_VERSION_5_0_6)
- print_old(filename, sf);
+ ret = print_old(filename, sf, sz);
else
- print(filename, sf, sz);
- delete [] buf;
+ ret = print(filename, sf, sz);
+
+ if (ret != 0) {
+ ndbout << filename << ": check failed"
+ << " version=" << version(sf->NdbVersion) << endl;
+ exitcode = 1;
+ } else if (! okquiet) {
+ ndbout << filename << ": ok"
+ << " version=" << version(sf->NdbVersion) << endl;
+ }
+
+ if (equalcontents && prevfilename != 0) {
+ if (prevbytes != bytes || memcmp(prevbuf, buf, bytes) != 0) {
+ ndbout << filename << ": differs from " << prevfilename << endl;
+ exitcode = 1;
+ }
+ }
+
+ prevfilename = filename;
+ delete [] prevbuf;
+ prevbuf = buf;
+ prevbytes = bytes;
}
- return xitcode;
+ delete [] prevbuf;
+ return exitcode;
}
diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
index 97b16f1dbc4..e50e6bd242b 100644
--- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
+++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
@@ -1962,6 +1962,11 @@ Ndbcntr::execRESUME_REQ(Signal* signal){
//ResumeRef * const ref = (ResumeRef *)&signal->theData[0];
jamEntry();
+
+ signal->theData[0] = NDB_LE_SingleUser;
+ signal->theData[1] = 2;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
+
//Uint32 senderData = req->senderData;
//BlockReference senderRef = req->senderRef;
NodeState newState(NodeState::SL_STARTED);
@@ -2000,12 +2005,11 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
return;
}
- if(c_stopRec.stopReq.senderRef != 0 && !singleuser){
- jam();
+ if(c_stopRec.stopReq.senderRef != 0){
/**
* Requested a system shutdown
*/
- if(StopReq::getSystemStop(req->requestInfo)){
+ if(!singleuser && StopReq::getSystemStop(req->requestInfo)){
jam();
sendSignalWithDelay(reference(), GSN_STOP_REQ, signal, 100,
StopReq::SignalLength);
@@ -2027,23 +2031,28 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
c_stopRec.stopReq = * req;
c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
- if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) && !singleuser) {
- jam();
- if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){
- ((Configuration&)theConfiguration).stopOnError(false);
- }
- }
if(!singleuser) {
+ if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo)) {
+ jam();
+ if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){
+ ((Configuration&)theConfiguration).stopOnError(false);
+ }
+ }
if(!c_stopRec.checkNodeFail(signal)){
jam();
return;
}
+ signal->theData[0] = NDB_LE_NDBStopStarted;
+ signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
}
-
- signal->theData[0] = NDB_LE_NDBStopStarted;
- signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
+ else
+ {
+ signal->theData[0] = NDB_LE_SingleUser;
+ signal->theData[1] = 0;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
+ }
+
NodeState newState(NodeState::SL_STOPPING_1,
StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
@@ -2125,9 +2134,11 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){
stopReq.senderRef = 0;
- NodeState newState(NodeState::SL_STARTED);
-
- cntr.updateNodeState(signal, newState);
+ if (cntr.getNodeState().startLevel != NodeState::SL_SINGLEUSER)
+ {
+ NodeState newState(NodeState::SL_STARTED);
+ cntr.updateNodeState(signal, newState);
+ }
signal->theData[0] = NDB_LE_NDBStopAborted;
cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
@@ -2223,12 +2234,24 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){
jamEntry();
if(c_stopRec.stopReq.singleuser) {
jam();
+
NodeState newState(NodeState::SL_SINGLEUSER);
newState.setSingleUser(true);
newState.setSingleUserApi(c_stopRec.stopReq.singleUserApi);
updateNodeState(signal, newState);
c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
+ StopConf * const stopConf = (StopConf *)&signal->theData[0];
+ stopConf->senderData = c_stopRec.stopReq.senderData;
+ stopConf->nodeState = (Uint32) NodeState::SL_SINGLEUSER;
+ sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_CONF, signal, StopConf::SignalLength, JBB);
+
+ c_stopRec.stopReq.senderRef = 0; // the command is done
+
+ signal->theData[0] = NDB_LE_SingleUser;
+ signal->theData[1] = 1;
+ signal->theData[2] = c_stopRec.stopReq.singleUserApi;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
}
else
{
@@ -2246,7 +2269,13 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){
void Ndbcntr::execABORT_ALL_REF(Signal* signal){
jamEntry();
- ndbrequire(false);
+ AbortAllRef *abortAllRef = (AbortAllRef *)&signal->theData[0];
+ AbortAllRef::ErrorCode errorCode = (AbortAllRef::ErrorCode) abortAllRef->errorCode;
+
+ StopRef * const stopRef = (StopRef *)&signal->theData[0];
+ stopRef->senderData = c_stopRec.stopReq.senderData;
+ stopRef->errorCode = StopRef::TransactionAbortFailed;
+ sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
}
void
diff --git a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
index 7052e0da98a..0f736c54555 100644
--- a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+++ b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
@@ -2013,6 +2013,8 @@ Qmgr::execAPI_VERSION_REQ(Signal * signal) {
else
conf->version = 0;
conf->nodeId = nodeId;
+ struct in_addr in= globalTransporterRegistry.get_connect_address(nodeId);
+ conf->inet_addr= in.s_addr;
sendSignal(senderRef,
GSN_API_VERSION_CONF,
diff --git a/ndb/src/mgmapi/ndb_logevent.cpp b/ndb/src/mgmapi/ndb_logevent.cpp
index 27e7c1f36f5..918ec5d6705 100644
--- a/ndb/src/mgmapi/ndb_logevent.cpp
+++ b/ndb/src/mgmapi/ndb_logevent.cpp
@@ -289,6 +289,8 @@ struct Ndb_logevent_body_row ndb_logevent_body[]= {
ROW( BackupAborted, "backup_id", 2, backup_id),
ROW( BackupAborted, "error", 3, error),
+ ROW( SingleUser, "type", 1, type),
+ ROW( SingleUser, "node_id", 2, node_id),
{ NDB_LE_ILLEGAL_TYPE, 0, 0, 0, 0, 0}
};
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index b4bbb3531ad..b5d1f38ba53 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -1443,9 +1443,8 @@ CommandInterpreter::executeEnterSingleUser(char* parameters)
ndbout_c("Entering single user mode for node %d failed", nodeId);
printError();
} else {
- ndbout_c("Entering single user mode");
- ndbout_c("Access will be granted for API node %d only.", nodeId);
- ndbout_c("Use ALL STATUS to see when single user mode has been entered.");
+ ndbout_c("Single user mode entered");
+ ndbout_c("Access is granted for API node %d only.", nodeId);
}
}
@@ -1458,7 +1457,7 @@ CommandInterpreter::executeExitSingleUser(char* parameters)
printError();
} else {
ndbout_c("Exiting single user mode in progress.");
- ndbout_c("Use ALL STATUS to see when single user mode has been exited.");
+ ndbout_c("Use ALL STATUS or SHOW to see when single user mode has been exited.");
}
}
diff --git a/ndb/src/mgmsrv/Config.cpp b/ndb/src/mgmsrv/Config.cpp
index 5ff9cbe04ad..6ff5fb789f0 100644
--- a/ndb/src/mgmsrv/Config.cpp
+++ b/ndb/src/mgmsrv/Config.cpp
@@ -179,90 +179,3 @@ void Config::printConfigFile(NdbOut &out) const {
}
#endif
}
-
-Uint32
-Config::getGenerationNumber() const {
-#if 0
- Uint32 ret;
- const Properties *prop = NULL;
-
- get("SYSTEM", &prop);
-
- if(prop != NULL)
- if(prop->get("ConfigGenerationNumber", &ret))
- return ret;
-
- return 0;
-#else
- return 0;
-#endif
-}
-
-int
-Config::setGenerationNumber(Uint32 gen) {
-#if 0
- Properties *prop = NULL;
-
- getCopy("SYSTEM", &prop);
-
- if(prop != NULL) {
- MGM_REQUIRE(prop->put("ConfigGenerationNumber", gen, true));
- MGM_REQUIRE(put("SYSTEM", prop, true));
- return 0;
- }
- return -1;
-#else
- return -1;
-#endif
-}
-
-bool
-Config::change(const BaseString &section,
- const BaseString &param,
- const BaseString &value) {
-#if 0
- const char *name;
- Properties::Iterator it(this);
-
- for(name = it.first(); name != NULL; name = it.next()) {
- Properties *prop = NULL;
- if(strcasecmp(section.c_str(), name) == 0) {
- getCopy(name, &prop);
- if(prop == NULL) /* doesn't exist */
- return false;
- if(value == "") {
- prop->remove(param.c_str());
- put(section.c_str(), prop, true);
- } else {
- PropertiesType t;
- if(!prop->getTypeOf(param.c_str(), &t)) /* doesn't exist */
- return false;
- switch(t) {
- case PropertiesType_Uint32:
- long val;
- char *ep;
- errno = 0;
- val = strtol(value.c_str(), &ep, 0);
- if(value.length() == 0 || *ep != '\0') /* not a number */
- return false;
- if(errno == ERANGE)
- return false;
- prop->put(param.c_str(), (unsigned int)val, true);
- put(section.c_str(), prop, true);
- break;
- case PropertiesType_char:
- prop->put(param.c_str(), value.c_str(), true);
- put(section.c_str(), prop, true);
- break;
- default:
- return false;
- }
- }
- break;
- }
- }
- return true;
-#else
- return false;
-#endif
-}
diff --git a/ndb/src/mgmsrv/Config.hpp b/ndb/src/mgmsrv/Config.hpp
index b5e1e17b027..8e16ddf1810 100644
--- a/ndb/src/mgmsrv/Config.hpp
+++ b/ndb/src/mgmsrv/Config.hpp
@@ -60,16 +60,6 @@ public:
printConfigFile(ndb);
}
- Uint32 getGenerationNumber() const;
- int setGenerationNumber(Uint32);
-
- /** Change configuration
- */
- bool change(const BaseString &section,
- const BaseString &param,
- const BaseString &value);
-
-
/**
* Info
*/
diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp
index 4e96047e54d..a870c395bd2 100644
--- a/ndb/src/mgmsrv/ConfigInfo.cpp
+++ b/ndb/src/mgmsrv/ConfigInfo.cpp
@@ -241,6 +241,9 @@ struct DepricationTransform {
static
const DepricationTransform f_deprication[] = {
{ DB_TOKEN, "Discless", "Diskless", 0, 1 },
+ { DB_TOKEN, "Id", "nodeid", 0, 1 },
+ { API_TOKEN, "Id", "nodeid", 0, 1 },
+ { MGM_TOKEN, "Id", "nodeid", 0, 1 },
{ 0, 0, 0, 0, 0}
};
@@ -405,9 +408,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0, 0 },
{
- CFG_NODE_ID,
+ KEY_INTERNAL,
"Id",
DB_TOKEN,
+ "",
+ ConfigInfo::CI_DEPRICATED,
+ false,
+ ConfigInfo::CI_INT,
+ MANDATORY,
+ "1",
+ STR_VALUE(MAX_NODES) },
+
+ {
+ CFG_NODE_ID,
+ "nodeid",
+ DB_TOKEN,
"Number identifying the database node ("DB_TOKEN_PRINT")",
ConfigInfo::CI_USED,
false,
@@ -1244,9 +1259,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0, 0 },
{
- CFG_NODE_ID,
+ KEY_INTERNAL,
"Id",
API_TOKEN,
+ "",
+ ConfigInfo::CI_DEPRICATED,
+ false,
+ ConfigInfo::CI_INT,
+ MANDATORY,
+ "1",
+ STR_VALUE(MAX_NODES) },
+
+ {
+ CFG_NODE_ID,
+ "nodeid",
+ API_TOKEN,
"Number identifying application node ("API_TOKEN_PRINT")",
ConfigInfo::CI_USED,
false,
@@ -1375,9 +1402,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0, 0 },
{
- CFG_NODE_ID,
+ KEY_INTERNAL,
"Id",
MGM_TOKEN,
+ "",
+ ConfigInfo::CI_DEPRICATED,
+ false,
+ ConfigInfo::CI_INT,
+ MANDATORY,
+ "1",
+ STR_VALUE(MAX_NODES) },
+
+ {
+ CFG_NODE_ID,
+ "nodeid",
+ MGM_TOKEN,
"Number identifying the management server node ("MGM_TOKEN_PRINT")",
ConfigInfo::CI_USED,
false,
@@ -2516,14 +2555,14 @@ bool
transformNode(InitConfigFileParser::Context & ctx, const char * data){
Uint32 id;
- if(!ctx.m_currentSection->get("Id", &id)){
+ if(!ctx.m_currentSection->get("nodeid", &id) && !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);
+ ctx.m_currentSection->put("nodeid", id);
#if 0
ctx.reportError("Mandatory parameter Id missing from section "
"[%s] starting at line: %d",
@@ -2531,7 +2570,7 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){
return false;
#endif
} else if(ctx.m_userProperties.get("AllocatedNodeId_", id, &id)) {
- ctx.reportError("Duplicate Id in section "
+ ctx.reportError("Duplicate nodeid in section "
"[%s] starting at line: %d",
ctx.fname, ctx.m_sectionLineno);
return false;
@@ -3356,6 +3395,7 @@ transform(InitConfigFileParser::Context & ctx,
PropertiesType oldType;
require(ctx.m_currentSection->getTypeOf(oldName, &oldType));
ConfigInfo::Type newType = ctx.m_info->getType(ctx.m_currentInfo, newName);
+
if(!((oldType == PropertiesType_Uint32 || oldType == PropertiesType_Uint64)
&& (newType == ConfigInfo::CI_INT || newType == ConfigInfo::CI_INT64 || newType == ConfigInfo::CI_BOOL))){
ndbout << "oldType: " << (int)oldType << ", newType: " << (int)newType << endl;
diff --git a/ndb/src/mgmsrv/InitConfigFileParser.cpp b/ndb/src/mgmsrv/InitConfigFileParser.cpp
index 822e10c89aa..233458ddf83 100644
--- a/ndb/src/mgmsrv/InitConfigFileParser.cpp
+++ b/ndb/src/mgmsrv/InitConfigFileParser.cpp
@@ -31,8 +31,10 @@ static void require(bool v) { if(!v) abort();}
//****************************************************************************
// Ctor / Dtor
//****************************************************************************
-InitConfigFileParser::InitConfigFileParser(){
+InitConfigFileParser::InitConfigFileParser(FILE * out)
+{
m_info = new ConfigInfo();
+ m_errstream = out ? out : stdout;
}
InitConfigFileParser::~InitConfigFileParser() {
@@ -42,11 +44,12 @@ InitConfigFileParser::~InitConfigFileParser() {
//****************************************************************************
// Read Config File
//****************************************************************************
-InitConfigFileParser::Context::Context(const ConfigInfo * info)
+InitConfigFileParser::Context::Context(const ConfigInfo * info, FILE * out)
: m_userProperties(true), m_configValues(1000, 20) {
m_config = new Properties(true);
m_defaults = new Properties(true);
+ m_errstream = out;
}
InitConfigFileParser::Context::~Context(){
@@ -61,10 +64,10 @@ Config *
InitConfigFileParser::parseConfig(const char * filename) {
FILE * file = fopen(filename, "r");
if(file == 0){
- ndbout << "Error opening file: " << filename << endl;
+ fprintf(m_errstream, "Error opening file: %s\n", filename);
return 0;
}
-
+
Config * ret = parseConfig(file);
fclose(file);
return ret;
@@ -75,7 +78,7 @@ InitConfigFileParser::parseConfig(FILE * file) {
char line[MAX_LINE_LENGTH];
- Context ctx(m_info);
+ Context ctx(m_info, m_errstream);
ctx.m_lineno = 0;
ctx.m_currentSection = 0;
@@ -160,6 +163,13 @@ InitConfigFileParser::parseConfig(FILE * file) {
ctx.reportError("Could not store section of configuration file.");
return 0;
}
+
+ return run_config_rules(ctx);
+}
+
+Config*
+InitConfigFileParser::run_config_rules(Context& ctx)
+{
for(size_t i = 0; ConfigInfo::m_ConfigRules[i].m_configRule != 0; i++){
ctx.type = InitConfigFileParser::Undefined;
ctx.m_currentSection = 0;
@@ -267,10 +277,10 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line)
}
if (status == ConfigInfo::CI_DEPRICATED) {
const char * desc = m_info->getDescription(ctx.m_currentInfo, fname);
- if(desc){
+ if(desc && desc[0]){
ctx.reportWarning("[%s] %s is depricated, use %s instead",
ctx.fname, fname, desc);
- } else {
+ } else if (desc == 0){
ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname);
}
}
@@ -571,8 +581,9 @@ InitConfigFileParser::Context::reportError(const char * fmt, ...){
va_start(ap, fmt);
if (fmt != 0)
BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- ndbout << "Error line " << m_lineno << ": " << buf << endl;
va_end(ap);
+ fprintf(m_errstream, "Error line %d: %s\n",
+ m_lineno, buf);
//m_currentSection->print();
}
@@ -585,6 +596,358 @@ InitConfigFileParser::Context::reportWarning(const char * fmt, ...){
va_start(ap, fmt);
if (fmt != 0)
BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- ndbout << "Warning line " << m_lineno << ": " << buf << endl;
va_end(ap);
+ fprintf(m_errstream, "Warning line %d: %s\n",
+ m_lineno, buf);
+}
+
+#include <my_sys.h>
+#include <my_getopt.h>
+
+static int order = 1;
+static
+my_bool
+parse_mycnf_opt(int, const struct my_option * opt, char * value)
+{
+ if(opt->comment)
+ ((struct my_option *)opt)->app_type++;
+ else
+ ((struct my_option *)opt)->app_type = order++;
+ return 0;
+}
+
+bool
+InitConfigFileParser::store_in_properties(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name)
+{
+ for(unsigned i = 0; i<options.size(); i++)
+ {
+ if(options[i].comment &&
+ options[i].app_type &&
+ strcmp(options[i].comment, name) == 0)
+ {
+ Uint64 value_int;
+ switch(options[i].var_type){
+ case GET_INT:
+ value_int = *(Uint32*)options[i].value;
+ break;
+ case GET_LL:
+ value_int = *(Uint64*)options[i].value;
+ break;
+ case GET_STR:
+ ctx.m_currentSection->put(options[i].name, (char*)options[i].value);
+ continue;
+ default:
+ abort();
+ }
+
+ const char * fname = options[i].name;
+ if (!m_info->verify(ctx.m_currentInfo, fname, value_int)) {
+ ctx.reportError("Illegal value %lld for parameter %s.\n"
+ "Legal values are between %Lu and %Lu",
+ value_int, fname,
+ m_info->getMin(ctx.m_currentInfo, fname),
+ m_info->getMax(ctx.m_currentInfo, fname));
+ return false;
+ }
+ if (options[i].var_type == GET_INT)
+ ctx.m_currentSection->put(options[i].name, (Uint32)value_int);
+ else
+ ctx.m_currentSection->put(options[i].name, value_int);
+ }
+ }
+ return true;
}
+
+bool
+InitConfigFileParser::handle_mycnf_defaults(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name)
+{
+ strcpy(ctx.fname, name);
+ ctx.type = InitConfigFileParser::DefaultSection;
+ ctx.m_currentSection = new Properties(true);
+ ctx.m_userDefaults = NULL;
+ require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
+ require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0);
+ if(store_in_properties(options, ctx, name))
+ return storeSection(ctx);
+ return false;
+}
+
+static
+int
+load_defaults(Vector<struct my_option>& options, const char* groups[])
+{
+ int argc = 1;
+ const char * argv[] = { "ndb_mgmd", 0, 0, 0, 0 };
+ BaseString file;
+ BaseString extra_file;
+ BaseString group_suffix;
+
+ const char *save_file = defaults_file;
+ char *save_extra_file = defaults_extra_file;
+ const char *save_group_suffix = defaults_group_suffix;
+
+ if (defaults_file)
+ {
+ file.assfmt("--defaults-file=%s", defaults_file);
+ argv[argc++] = file.c_str();
+ }
+
+ if (defaults_extra_file)
+ {
+ extra_file.assfmt("--defaults-extra-file=%s", defaults_extra_file);
+ argv[argc++] = extra_file.c_str();
+ }
+
+ if (defaults_group_suffix)
+ {
+ group_suffix.assfmt("--defaults-group-suffix=%s", defaults_group_suffix);
+ argv[argc++] = group_suffix.c_str();
+ }
+
+ char ** tmp = (char**)argv;
+ int ret = load_defaults("my", groups, &argc, &tmp);
+
+ defaults_file = save_file;
+ defaults_extra_file = save_extra_file;
+ defaults_group_suffix = save_group_suffix;
+
+ if (ret == 0)
+ {
+ return handle_options(&argc, &tmp, options.getBase(), parse_mycnf_opt);
+ }
+
+ return ret;
+}
+
+bool
+InitConfigFileParser::load_mycnf_groups(Vector<struct my_option> & options,
+ InitConfigFileParser::Context& ctx,
+ const char * name,
+ const char *groups[])
+{
+ unsigned i;
+ Vector<struct my_option> copy;
+ for(i = 0; i<options.size(); i++)
+ {
+ if(options[i].comment && strcmp(options[i].comment, name) == 0)
+ {
+ options[i].app_type = 0;
+ copy.push_back(options[i]);
+ }
+ }
+
+ struct my_option end;
+ bzero(&end, sizeof(end));
+ copy.push_back(end);
+
+ if (load_defaults(copy, groups))
+ return false;
+
+ return store_in_properties(copy, ctx, name);
+}
+
+Config *
+InitConfigFileParser::parse_mycnf()
+{
+ int i;
+ Config * res = 0;
+ Vector<struct my_option> options;
+ for(i = 0; i<ConfigInfo::m_NoOfParams; i++)
+ {
+ if (strcmp(ConfigInfo::m_ParamInfo[i]._section, "DB") == 0 ||
+ strcmp(ConfigInfo::m_ParamInfo[i]._section, "API") == 0 ||
+ strcmp(ConfigInfo::m_ParamInfo[i]._section, "MGM") == 0)
+ {
+ struct my_option opt;
+ bzero(&opt, sizeof(opt));
+ const ConfigInfo::ParamInfo& param = ConfigInfo::m_ParamInfo[i];
+ switch(param._type){
+ case ConfigInfo::CI_BOOL:
+ opt.value = (gptr*)malloc(sizeof(int));
+ opt.var_type = GET_INT;
+ break;
+ case ConfigInfo::CI_INT:
+ opt.value = (gptr*)malloc(sizeof(int));
+ opt.var_type = GET_INT;
+ require(convertStringToUint64(param._min, (Uint64&)opt.min_value));
+ require(convertStringToUint64(param._max, (Uint64&)opt.max_value));
+ break;
+ case ConfigInfo::CI_INT64:
+ opt.value = (gptr*)malloc(sizeof(Int64));
+ opt.var_type = GET_LL;
+ require(convertStringToUint64(param._min, (Uint64&)opt.min_value));
+ require(convertStringToUint64(param._max, (Uint64&)opt.max_value));
+ break;
+ case ConfigInfo::CI_STRING:
+ opt.value = (gptr*)malloc(sizeof(char *));
+ opt.var_type = GET_STR;
+ break;
+ default:
+ continue;
+ }
+ opt.name = param._fname;
+ opt.id = 256;
+ opt.app_type = 0;
+ opt.arg_type = REQUIRED_ARG;
+ opt.comment = param._section;
+ options.push_back(opt);
+ }
+ }
+
+ struct my_option *ndbd, *ndb_mgmd, *mysqld, *api;
+
+ /**
+ * Add ndbd, ndb_mgmd, api/mysqld
+ */
+ {
+ struct my_option opt;
+ bzero(&opt, sizeof(opt));
+ opt.name = "ndbd";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ ndbd = &options.back();
+
+ opt.name = "ndb_mgmd";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ ndb_mgmd = &options.back();
+
+ opt.name = "mysqld";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ mysqld = &options.back();
+
+ opt.name = "api";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ api = &options.back();
+
+ bzero(&opt, sizeof(opt));
+ options.push_back(opt);
+ }
+
+
+ Context ctx(m_info, m_errstream);
+ const char *groups[]= { "cluster_config", 0 };
+ if (load_defaults(options, groups))
+ goto end;
+
+ ctx.m_lineno = 0;
+ if(!handle_mycnf_defaults(options, ctx, "DB"))
+ goto end;
+ if(!handle_mycnf_defaults(options, ctx, "API"))
+ goto end;
+ if(!handle_mycnf_defaults(options, ctx, "MGM"))
+ goto end;
+
+ {
+ struct sect { struct my_option* src; const char * name; } sections[] =
+ {
+ { ndb_mgmd, "MGM" }
+ ,{ ndbd, "DB" }
+ ,{ mysqld, "API" }
+ ,{ api, "API" }
+ ,{ 0, 0 }, { 0, 0 }
+ };
+
+ for(i = 0; sections[i].src; i++)
+ {
+ for(int j = i + 1; sections[j].src; j++)
+ {
+ if (sections[j].src->app_type < sections[i].src->app_type)
+ {
+ sect swap = sections[i];
+ sections[i] = sections[j];
+ sections[j] = swap;
+ }
+ }
+ }
+
+ ctx.type = InitConfigFileParser::Section;
+ ctx.m_sectionLineno = ctx.m_lineno;
+ for(i = 0; sections[i].src; i++)
+ {
+ if (sections[i].src->app_type)
+ {
+ strcpy(ctx.fname, sections[i].name);
+ BaseString str(*(char**)sections[i].src->value);
+ Vector<BaseString> list;
+ str.split(list, ",");
+
+ const char * defaults_groups[] = { 0, 0, 0 };
+ for(unsigned j = 0; j<list.size(); j++)
+ {
+ BaseString group_idx;
+ BaseString group_host;
+ group_idx.assfmt("%s.%s.%d", groups[0],
+ sections[i].src->name, j + 1);
+ group_host.assfmt("%s.%s.%s", groups[0],
+ sections[i].src->name, list[j].c_str());
+ defaults_groups[0] = group_idx.c_str();
+ if(list[j].length())
+ defaults_groups[1] = group_host.c_str();
+ else
+ defaults_groups[1] = 0;
+
+ ctx.m_currentSection = new Properties(true);
+ ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults);
+ require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
+ require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname))!= 0);
+ ctx.m_currentSection->put("HostName", list[j].c_str());
+ if(!load_mycnf_groups(options, ctx, sections[i].name,
+ defaults_groups))
+ goto end;
+
+ if(!storeSection(ctx))
+ goto end;
+ }
+ }
+ }
+ }
+
+ res = run_config_rules(ctx);
+
+end:
+ for(i = 0; options[i].name; i++)
+ free(options[i].value);
+
+ return res;
+}
+
+template class Vector<struct my_option>;
+
+#if 0
+struct my_option
+{
+ const char *name; /* Name of the option */
+ int id; /* unique id or short option */
+ const char *comment; /* option comment, for autom. --help */
+ gptr *value; /* The variable value */
+ gptr *u_max_value; /* The user def. max variable value */
+ const char **str_values; /* Pointer to possible values */
+ ulong var_type;
+ enum get_opt_arg_type arg_type;
+ longlong def_value; /* Default value */
+ longlong min_value; /* Min allowed value */
+ longlong max_value; /* Max allowed value */
+ longlong sub_size; /* Subtract this from given value */
+ long block_size; /* Value should be a mult. of this */
+ int app_type; /* To be used by an application */
+};
+#endif
diff --git a/ndb/src/mgmsrv/InitConfigFileParser.hpp b/ndb/src/mgmsrv/InitConfigFileParser.hpp
index 1ea0a094ccd..616fd5a62fb 100644
--- a/ndb/src/mgmsrv/InitConfigFileParser.hpp
+++ b/ndb/src/mgmsrv/InitConfigFileParser.hpp
@@ -34,11 +34,12 @@ class ConfigInfo;
* object if the config file has correct syntax and semantic.
*/
class InitConfigFileParser {
+ FILE * m_errstream;
public:
/**
* Constructor
*/
- InitConfigFileParser();
+ InitConfigFileParser(FILE * errstream = stdout);
~InitConfigFileParser();
/**
@@ -50,6 +51,7 @@ public:
*/
Config * parseConfig(FILE * file);
Config * parseConfig(const char * filename);
+ Config * parse_mycnf();
/**
* Parser context struct
@@ -60,7 +62,7 @@ public:
* Context = Which section in init config file we are currently parsing
*/
struct Context {
- Context(const ConfigInfo *);
+ Context(const ConfigInfo *, FILE * out);
~Context();
ContextSectionType type; ///< Section type (e.g. default section,section)
@@ -82,6 +84,7 @@ public:
ConfigValuesFactory m_configValues; //
public:
+ FILE * m_errstream;
void reportError(const char * msg, ...);
void reportWarning(const char * msg, ...);
};
@@ -122,6 +125,21 @@ private:
* Information about parameters (min, max values etc)
*/
ConfigInfo* m_info;
+
+ bool handle_mycnf_defaults(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name);
+
+ bool load_mycnf_groups(Vector<struct my_option> & options,
+ InitConfigFileParser::Context& ctx,
+ const char * name,
+ const char *groups[]);
+
+ bool store_in_properties(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name);
+
+ Config* run_config_rules(Context& ctx);
};
#endif // InitConfigFileParser_H
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index d946b4af4a7..5a07c5fa1ec 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -67,6 +67,16 @@
#define DEBUG(x)
#endif
+#define INIT_SIGNAL_SENDER(ss,nodeId) \
+ SignalSender ss(theFacade); \
+ ss.lock(); /* lock will be released on exit */ \
+ {\
+ int result = okToSendTo(nodeId, true);\
+ if (result != 0) {\
+ return result;\
+ }\
+ }
+
extern int global_flag_send_heartbeat_now;
extern int g_no_nodeid_checks;
extern my_bool opt_core;
@@ -90,55 +100,6 @@ MgmtSrvr::logLevelThread_C(void* m)
return 0;
}
-void *
-MgmtSrvr::signalRecvThread_C(void *m)
-{
- MgmtSrvr *mgm = (MgmtSrvr*)m;
- mgm->signalRecvThreadRun();
- return 0;
-}
-
-class SigMatch
-{
-public:
- int gsn;
- void (MgmtSrvr::* function)(NdbApiSignal *signal);
-
- SigMatch() { gsn = 0; function = NULL; };
-
- SigMatch(int _gsn,
- void (MgmtSrvr::* _function)(NdbApiSignal *signal)) {
- gsn = _gsn;
- function = _function;
- };
-
- bool check(NdbApiSignal *signal) {
- if(signal->readSignalNumber() == gsn)
- return true;
- return false;
- };
-
-};
-
-void
-MgmtSrvr::signalRecvThreadRun()
-{
- Vector<SigMatch> siglist;
- siglist.push_back(SigMatch(GSN_MGM_LOCK_CONFIG_REQ,
- &MgmtSrvr::handle_MGM_LOCK_CONFIG_REQ));
- siglist.push_back(SigMatch(GSN_MGM_UNLOCK_CONFIG_REQ,
- &MgmtSrvr::handle_MGM_UNLOCK_CONFIG_REQ));
-
- while(!_isStopThread) {
- SigMatch *handler = NULL;
- NdbApiSignal *signal = NULL;
- if(m_signalRecvQueue.waitFor(siglist, &handler, &signal, DEFAULT_TIMEOUT)) {
- if(handler->function != 0)
- (this->*handler->function)(signal);
- }
- }
-}
-
extern EventLogger g_eventLogger;
static NdbOut&
@@ -426,15 +387,12 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
_isStopThread = false;
_logLevelThread = NULL;
_logLevelThreadSleep = 500;
- m_signalRecvThread = NULL;
theFacade = 0;
m_newConfig = NULL;
if (config_filename)
m_configFilename.assign(config_filename);
- else
- m_configFilename.assign("config.ini");
m_nextConfigGenerationNumber = 0;
@@ -469,7 +427,7 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
_config= readConfig();
if (_config == 0) {
ndbout << "Unable to read config file" << endl;
- require(false);
+ exit(-1);
}
}
@@ -654,12 +612,6 @@ MgmtSrvr::start(BaseString &error_string)
"MgmtSrvr_Loglevel",
NDB_THREAD_PRIO_LOW);
- m_signalRecvThread = NdbThread_Create(signalRecvThread_C,
- (void **)this,
- 32768,
- "MgmtSrvr_Service",
- NDB_THREAD_PRIO_LOW);
-
DBUG_RETURN(true);
}
@@ -668,10 +620,6 @@ MgmtSrvr::start(BaseString &error_string)
//****************************************************************************
MgmtSrvr::~MgmtSrvr()
{
- while (theSignalIdleList != NULL) {
- freeSignal();
- }
-
if(theFacade != 0){
theFacade->stop_instance();
delete theFacade;
@@ -699,10 +647,6 @@ MgmtSrvr::~MgmtSrvr()
NdbThread_Destroy(&_logLevelThread);
}
- if (m_signalRecvThread != NULL) {
- NdbThread_WaitFor(m_signalRecvThread, &res);
- NdbThread_Destroy(&m_signalRecvThread);
- }
if (m_config_retriever)
delete m_config_retriever;
}
@@ -710,21 +654,21 @@ MgmtSrvr::~MgmtSrvr()
//****************************************************************************
//****************************************************************************
-int MgmtSrvr::okToSendTo(NodeId processId, bool unCond)
+int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond)
{
- if(processId == 0)
+ if(nodeId == 0)
return 0;
- if (getNodeType(processId) != NDB_MGM_NODE_TYPE_NDB)
+ if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)
return WRONG_PROCESS_TYPE;
// Check if we have contact with it
if(unCond){
- if(theFacade->theClusterMgr->getNodeInfo(processId).connected)
+ if(theFacade->theClusterMgr->getNodeInfo(nodeId).connected)
return 0;
return NO_CONTACT_WITH_PROCESS;
}
- if (theFacade->get_node_alive(processId) == 0) {
+ if (theFacade->get_node_alive(nodeId) == 0) {
return NO_CONTACT_WITH_PROCESS;
} else {
return 0;
@@ -745,241 +689,454 @@ void report_unknown_signal(SimpleSignal *signal)
****************************************************************************/
int
-MgmtSrvr::start(int processId)
+MgmtSrvr::start(int nodeId)
{
- int result;
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StartOrd* const startOrd = CAST_PTR(StartOrd, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
+ INIT_SIGNAL_SENDER(ss,nodeId);
+ SimpleSignal ssig;
+ StartOrd* const startOrd = CAST_PTR(StartOrd, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
startOrd->restartInfo = 0;
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
+}
+
+/*****************************************************************************
+ * Version handling
+ *****************************************************************************/
+
+int
+MgmtSrvr::versionNode(int nodeId, Uint32 &version, const char **address)
+{
+ version= 0;
+ if (getOwnNodeId() == nodeId)
+ {
+ /**
+ * If we're inquiring about our own node id,
+ * We know what version we are (version implies connected for mgm)
+ * but would like to find out from elsewhere what address they're using
+ * to connect to us. This means that secondary mgm servers
+ * can list ip addresses for mgm servers.
+ *
+ * If we don't get an address (i.e. no db nodes),
+ * we get the address from the configuration.
+ */
+ sendVersionReq(nodeId, version, address);
+ version= NDB_VERSION;
+ if(!*address)
+ {
+ ndb_mgm_configuration_iterator
+ iter(*_config->m_configValues, CFG_SECTION_NODE);
+ unsigned tmp= 0;
+ for(iter.first();iter.valid();iter.next())
+ {
+ if(iter.get(CFG_NODE_ID, &tmp)) require(false);
+ if((unsigned)nodeId!=tmp)
+ continue;
+ if(iter.get(CFG_NODE_HOST, address)) require(false);
+ break;
+ }
+ }
}
-
+ else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
+ {
+ ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(nodeId);
+ if(node.connected)
+ version= node.m_info.m_version;
+ *address= get_connect_address(nodeId);
+ }
+ else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
+ getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
+ {
+ return sendVersionReq(nodeId, version, address);
+ }
+
+ return 0;
+}
+
+int
+MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address)
+{
+ SignalSender ss(theFacade);
+ ss.lock();
+
+ SimpleSignal ssig;
+ ApiVersionReq* req = CAST_PTR(ApiVersionReq, ssig.getDataPtrSend());
+ req->senderRef = ss.getOwnRef();
+ req->nodeId = v_nodeId;
+ ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ,
+ ApiVersionReq::SignalLength);
+
+ int do_send = 1;
+ NodeId nodeId;
+
+ while (1)
+ {
+ if (do_send)
+ {
+ bool next;
+ nodeId = 0;
+
+ while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
+ okToSendTo(nodeId, true) != 0);
+
+ const ClusterMgr::Node &node=
+ theFacade->theClusterMgr->getNodeInfo(nodeId);
+ if(next && node.m_state.startLevel != NodeState::SL_STARTED)
+ {
+ NodeId tmp=nodeId;
+ while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
+ okToSendTo(nodeId, true) != 0);
+ if(!next)
+ nodeId= tmp;
+ }
+
+ if(!next) return NO_CONTACT_WITH_DB_NODES;
+
+ if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ do_send = 0;
+ }
+
+ SimpleSignal *signal = ss.waitFor();
+
+ int gsn = signal->readSignalNumber();
+ switch (gsn) {
+ case GSN_API_VERSION_CONF: {
+ const ApiVersionConf * const conf =
+ CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
+ assert(conf->nodeId == v_nodeId);
+ version = conf->version;
+ struct in_addr in;
+ in.s_addr= conf->inet_addr;
+ *address= inet_ntoa(in);
+ return 0;
+ }
+ case GSN_NF_COMPLETEREP:{
+ const NFCompleteRep * const rep =
+ CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
+ if (rep->failedNodeId == nodeId)
+ do_send = 1; // retry with other node
+ continue;
+ }
+ case GSN_NODE_FAILREP:{
+ const NodeFailRep * const rep =
+ CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
+ if (NodeBitmask::get(rep->theNodes,nodeId))
+ do_send = 1; // retry with other node
+ continue;
+ }
+ default:
+ report_unknown_signal(signal);
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ break;
+ } // while(1)
+
return 0;
}
-/**
- * Restart one database node
+/*
+ * Common method for handeling all STOP_REQ signalling that
+ * is used by Stopping, Restarting and Single user commands
*/
-int
-MgmtSrvr::restartNode(int processId, bool nostart,
- bool initalStart, bool abort,
- StopCallback callback, void * anyData)
+
+int MgmtSrvr::sendSTOP_REQ(NodeId nodeId,
+ NodeBitmask &stoppedNodes,
+ Uint32 singleUserNodeId,
+ bool abort,
+ bool stop,
+ bool restart,
+ bool nostart,
+ bool initialStart)
{
- int result;
+ stoppedNodes.clear();
- if(m_stopRec.singleUserMode)
- return 5060;
+ SignalSender ss(theFacade);
+ ss.lock(); // lock will be released on exit
- if(m_stopRec.inUse){
- return 5029;
- }
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ SimpleSignal ssig;
+ StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend());
+ ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
-
stopReq->requestInfo = 0;
- StopReq::setSystemStop(stopReq->requestInfo, false);
- StopReq::setPerformRestart(stopReq->requestInfo, true);
- StopReq::setNoStart(stopReq->requestInfo, nostart);
- StopReq::setInitialStart(stopReq->requestInfo, initalStart);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
- stopReq->singleuser = 0;
stopReq->apiTimeout = 5000;
stopReq->transactionTimeout = 1000;
stopReq->readOperationTimeout = 1000;
stopReq->operationTimeout = 1000;
stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- m_stopRec.singleUserMode = false;
- m_stopRec.sentCount = 1;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = processId;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- if(callback == NULL){
- Uint32 timeOut = 0;
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
- result = sendRecSignal(processId, WAIT_STOP, signal, true, timeOut);
- } else {
- result = sendSignal(processId, NO_WAIT, signal, true);
+ stopReq->senderRef = ss.getOwnRef();
+ if (singleUserNodeId)
+ {
+ stopReq->singleuser = 1;
+ stopReq->singleUserApi = singleUserNodeId;
+ StopReq::setSystemStop(stopReq->requestInfo, false);
+ StopReq::setPerformRestart(stopReq->requestInfo, false);
+ StopReq::setStopAbort(stopReq->requestInfo, false);
}
-
- if (result == -1 && theWaitState != WAIT_NODEFAILURE) {
- m_stopRec.inUse = false;
- return SEND_OR_RECEIVE_FAILED;
+ else
+ {
+ stopReq->singleuser = 0;
+ StopReq::setSystemStop(stopReq->requestInfo, stop);
+ StopReq::setPerformRestart(stopReq->requestInfo, restart);
+ StopReq::setStopAbort(stopReq->requestInfo, abort);
+ StopReq::setNoStart(stopReq->requestInfo, nostart);
+ StopReq::setInitialStart(stopReq->requestInfo, initialStart);
}
- if(callback == 0){
- m_stopRec.inUse = false;
- return m_stopRec.reply;
- } else {
- return 0;
+ // send the signals
+ NodeBitmask nodes;
+ if (nodeId)
+ {
+ {
+ int r;
+ if((r = okToSendTo(nodeId, true)) != 0)
+ return r;
+ }
+ {
+ if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ nodes.set(nodeId);
}
+ else
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
+ {
+ if(okToSendTo(nodeId, true) == 0)
+ {
+ SendStatus result = ss.sendSignal(nodeId, &ssig);
+ if (result == SEND_OK)
+ nodes.set(nodeId);
+ }
+ }
+
+ // now wait for the replies
+ int error = 0;
+ while (!nodes.isclear())
+ {
+ SimpleSignal *signal = ss.waitFor();
+ int gsn = signal->readSignalNumber();
+ switch (gsn) {
+ case GSN_STOP_REF:{
+ const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
+ const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
+#ifdef VM_TRACE
+ ndbout_c("Node %d refused stop", nodeId);
+#endif
+ assert(nodes.get(nodeId));
+ nodes.clear(nodeId);
+ error = translateStopRef(ref->errorCode);
+ break;
+ }
+ case GSN_STOP_CONF:{
+ const StopConf * const ref = CAST_CONSTPTR(StopConf, signal->getDataPtr());
+ const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
+#ifdef VM_TRACE
+ ndbout_c("Node %d single user mode", nodeId);
+#endif
+ assert(nodes.get(nodeId));
+ assert(singleUserNodeId != 0);
+ nodes.clear(nodeId);
+ stoppedNodes.set(nodeId);
+ break;
+ }
+ case GSN_NF_COMPLETEREP:{
+ const NFCompleteRep * const rep =
+ CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
+#ifdef VM_TRACE
+ ndbout_c("Node %d fail completed", rep->failedNodeId);
+#endif
+ break;
+ }
+ case GSN_NODE_FAILREP:{
+ const NodeFailRep * const rep =
+ CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
+ NodeBitmask failedNodes;
+ failedNodes.assign(NodeBitmask::Size, rep->theNodes);
+#ifdef VM_TRACE
+ {
+ ndbout << "Failed nodes:";
+ for (unsigned i = 0; i < 32*NodeBitmask::Size; i++)
+ if(failedNodes.get(i))
+ ndbout << " " << i;
+ ndbout << endl;
+ }
+#endif
+ failedNodes.bitAND(nodes);
+ if (!failedNodes.isclear())
+ {
+ nodes.bitANDC(failedNodes); // clear the failed nodes
+ if (singleUserNodeId == 0)
+ stoppedNodes.bitOR(failedNodes);
+ }
+ break;
+ }
+ default:
+ report_unknown_signal(signal);
+#ifdef VM_TRACE
+ ndbout_c("Unknown signal %d", gsn);
+#endif
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ }
+ return error;
}
-/**
- * Restart all database nodes
+/*
+ * Stop one node
*/
-int
-MgmtSrvr::restart(bool nostart, bool initalStart, bool abort,
- int * stopCount, StopCallback callback, void * anyData)
+
+int MgmtSrvr::stopNode(int nodeId, bool abort)
{
- if(m_stopRec.singleUserMode)
- return 5060;
+ NodeBitmask nodes;
+ return sendSTOP_REQ(nodeId,
+ nodes,
+ 0,
+ abort,
+ false,
+ false,
+ false,
+ false);
+}
+
+/*
+ * Perform system shutdown
+ */
- if(m_stopRec.inUse){
- return 5029;
- }
-
- m_stopRec.singleUserMode = false;
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- /**
- * Restart all database nodes into idle ("no-started") state
- */
- Uint32 timeOut = 0;
- NodeId nodeId = 0;
+int MgmtSrvr::stop(int * stopCount, bool abort)
+{
NodeBitmask nodes;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- if(okToSendTo(nodeId, true) == 0){
+ int ret = sendSTOP_REQ(0,
+ nodes,
+ 0,
+ abort,
+ true,
+ false,
+ false,
+ false);
+ if (stopCount)
+ *stopCount = nodes.count();
+ return ret;
+}
+
+/*
+ * Enter single user mode on all live nodes
+ */
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
- StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 0;
- StopReq::setSystemStop(stopReq->requestInfo, true);
- StopReq::setPerformRestart(stopReq->requestInfo, true);
- if (callback == 0) {
- // Start node in idle ("no-started") state
- StopReq::setNoStart(stopReq->requestInfo, 1);
- } else {
- StopReq::setNoStart(stopReq->requestInfo, nostart);
- }
- StopReq::setInitialStart(stopReq->requestInfo, initalStart);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
-
- m_stopRec.sentCount++;
- int res;
- if(callback == 0){
- res = sendSignal(nodeId, WAIT_STOP, signal, true);
- } else {
- res = sendSignal(nodeId, NO_WAIT, signal, true);
- }
-
- if(res != -1){
- nodes.set(nodeId);
- }
- }
- }
-
- if(stopCount != 0){
- * stopCount = m_stopRec.sentCount;
+int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId)
+{
+ if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API)
+ return 5062;
+ NodeId nodeId = 0;
+ ClusterMgr::Node node;
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
+ {
+ node = theFacade->theClusterMgr->getNodeInfo(nodeId);
+ if((node.m_state.startLevel != NodeState::SL_STARTED) &&
+ (node.m_state.startLevel != NodeState::SL_NOTHING))
+ return 5063;
}
+ NodeBitmask nodes;
+ int ret = sendSTOP_REQ(0,
+ nodes,
+ singleUserNodeId,
+ false,
+ false,
+ false,
+ false,
+ false);
+ if (stopCount)
+ *stopCount = nodes.count();
+ return ret;
+}
+
+/*
+ * Perform node restart
+ */
- if(m_stopRec.sentCount == 0){
- m_stopRec.inUse = false;
- return 0;
- }
-
- if(callback != 0){
- return 0;
- }
-
- theFacade->lock_mutex();
- int waitTime = timeOut/m_stopRec.sentCount;
- if (receiveOptimisedResponse(waitTime) != 0) {
- m_stopRec.inUse = false;
- return -1;
- }
-
+int MgmtSrvr::restartNode(int nodeId, bool nostart, bool initialStart,
+ bool abort)
+{
+ NodeBitmask nodes;
+ return sendSTOP_REQ(nodeId,
+ nodes,
+ 0,
+ abort,
+ false,
+ true,
+ nostart,
+ initialStart);
+}
+
+/*
+ * Perform system restart
+ */
+
+int MgmtSrvr::restart(bool nostart, bool initialStart,
+ bool abort, int * stopCount )
+{
+ NodeBitmask nodes;
+ int ret = sendSTOP_REQ(0,
+ nodes,
+ 0,
+ abort,
+ true,
+ true,
+ true,
+ initialStart);
+
+ if (ret)
+ return ret;
+
+ if (stopCount)
+ *stopCount = nodes.count();
+
+#ifdef VM_TRACE
+ ndbout_c("Stopped %d nodes", nodes.count());
+#endif
/**
* Here all nodes were correctly stopped,
* so we wait for all nodes to be contactable
*/
- nodeId = 0;
+ int waitTime = 12000;
+ NodeId nodeId = 0;
NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB) && nodes.get(nodeId)) {
+
+ ndbout_c(" %d", nodes.get(1));
+ ndbout_c(" %d", nodes.get(2));
+
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
+ if (!nodes.get(nodeId))
+ continue;
enum ndb_mgm_node_status s;
s = NDB_MGM_NODE_STATUS_NO_CONTACT;
+#ifdef VM_TRACE
+ ndbout_c("Waiting for %d not started", nodeId);
+#endif
while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) {
Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
Uint32 connectCount = 0;
bool system;
+ const char *address;
status(nodeId, &s, &version, &startPhase,
- &system, &dynamicId, &nodeGroup, &connectCount);
+ &system, &dynamicId, &nodeGroup, &connectCount, &address);
NdbSleep_MilliSleep(100);
waitTime = (maxTime - NdbTick_CurrentMillisecond());
}
}
- if(nostart){
- m_stopRec.inUse = false;
+ if(nostart)
return 0;
- }
/**
* Now we start all database nodes (i.e. we make them non-idle)
* We ignore the result we get from the start command.
*/
nodeId = 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB) && nodes.get(nodeId)) {
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
+ if (!nodes.get(nodeId))
+ continue;
int result;
result = start(nodeId);
DEBUG("Starting node " << nodeId << " with result " << result);
@@ -988,455 +1145,43 @@ MgmtSrvr::restart(bool nostart, bool initalStart, bool abort,
* Maybe the user only wanted to restart a subset of the nodes.
* It is also easy for the user to check which nodes have
* started and which nodes have not.
- *
- * if (result != 0) {
- * m_stopRec.inUse = false;
- * return result;
- * }
*/
}
- m_stopRec.inUse = false;
- return 0;
-}
-
-/*****************************************************************************
- * Version handling
- *****************************************************************************/
-
-int
-MgmtSrvr::versionNode(int processId, bool abort,
- VersionCallback callback, void * anyData)
-{
- int version;
-
- if(m_versionRec.inUse)
- return OPERATION_IN_PROGRESS;
-
- m_versionRec.callback = callback;
- m_versionRec.inUse = true ;
-
- if (getOwnNodeId() == processId)
- {
- version= NDB_VERSION;
- }
- else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB)
- {
- ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(processId);
- if(node.connected)
- version= node.m_info.m_version;
- else
- version= 0;
- }
- else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API ||
- getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM)
- {
- return sendVersionReq(processId);
- }
- else
- version= 0;
-
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, version, this,0);
- m_versionRec.inUse = false ;
-
- m_versionRec.version[processId]= version;
-
- return 0;
-}
-
-int
-MgmtSrvr::sendVersionReq(int processId)
-{
- Uint32 ndbnode=0;
- int result;
- for(Uint32 i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- if(okToSendTo(i, true) == 0)
- {
- ndbnode = i;
- break;
- }
- }
- }
-
- if (ndbnode == 0) {
- m_versionRec.inUse = false;
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, 0, this,0);
- return NO_CONTACT_WITH_CLUSTER;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- m_versionRec.inUse = false;
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, 0, this,0);
- return COULD_NOT_ALLOCATE_MEMORY;
- }
- ApiVersionReq* req = CAST_PTR(ApiVersionReq, signal->getDataPtrSend());
- req->senderRef = _ownReference;
- req->nodeId = processId;
-
- signal->set(TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ,
- ApiVersionReq::SignalLength);
-
-
- // if(m_versionRec.callback == 0){
- Uint32 timeOut = 0;
- timeOut = 10000;
- result = sendRecSignal(ndbnode, WAIT_VERSION, signal, true, timeOut);
- //} else {
- //result = sendSignal(processId, NO_WAIT, signal, true);
- // }
-
- if (result == -1) {
- m_versionRec.inUse = false;
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, 0, this,0);
- m_versionRec.version[processId] = 0;
- return SEND_OR_RECEIVE_FAILED;
- }
-
- m_versionRec.inUse = false;
- return 0;
-}
-
-int
-MgmtSrvr::version(int * stopCount, bool abort,
- VersionCallback callback, void * anyData)
-{
- ClusterMgr::Node node;
- int version;
-
- if(m_versionRec.inUse)
- return 1;
-
- m_versionRec.callback = callback;
- m_versionRec.inUse = true ;
- Uint32 i;
- for(i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM) {
- m_versionRec.callback(i, NDB_VERSION, this,0);
- }
- }
- for(i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- node = theFacade->theClusterMgr->getNodeInfo(i);
- version = node.m_info.m_version;
- if(theFacade->theClusterMgr->getNodeInfo(i).connected)
- m_versionRec.callback(i, version, this,0);
- else
- m_versionRec.callback(i, 0, this,0);
-
- }
- }
- for(i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_API) {
- return sendVersionReq(i);
- }
- }
-
return 0;
}
-int
-MgmtSrvr::stopNode(int processId, bool abort, StopCallback callback,
- void * anyData)
-
-{
- if(m_stopRec.singleUserMode)
- return 5060;
-
- if(m_stopRec.inUse)
- return 5029;
-
- int result;
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 0;
- StopReq::setPerformRestart(stopReq->requestInfo, false);
- StopReq::setSystemStop(stopReq->requestInfo, false);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- m_stopRec.sentCount = 1;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = processId;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- if(callback == NULL){
- Uint32 timeOut = 0;
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
- result = sendRecSignal(processId, WAIT_STOP, signal, true, timeOut);
- } else {
- result = sendSignal(processId, NO_WAIT, signal, true);
- }
-
- if (result == -1) {
- m_stopRec.inUse = false;
- return SEND_OR_RECEIVE_FAILED;
- }
-
- if(callback == 0){
- m_stopRec.inUse = false;
- return m_stopRec.reply;
- } else {
- return 0;
- }
-}
-
-int
-MgmtSrvr::stop(int * stopCount, bool abort, StopCallback callback,
- void * anyData)
-{
- if(m_stopRec.singleUserMode)
- return 5060;
-
- if(m_stopRec.inUse){
- return 5029;
- }
-
- m_stopRec.singleUserMode = false;
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- NodeId nodeId = 0;
- Uint32 timeOut = 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- if(okToSendTo(nodeId, true) == 0){
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
- StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 0;
- StopReq::setSystemStop(stopReq->requestInfo, true);
- StopReq::setPerformRestart(stopReq->requestInfo, false);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
-
- m_stopRec.sentCount++;
- if(callback == 0)
- sendSignal(nodeId, WAIT_STOP, signal, true);
- else
- sendSignal(nodeId, NO_WAIT, signal, true);
- }
- }
-
- if(stopCount != 0)
- * stopCount = m_stopRec.sentCount;
-
- if(m_stopRec.sentCount > 0){
- if(callback == 0){
- theFacade->lock_mutex();
- receiveOptimisedResponse(timeOut / m_stopRec.sentCount);
- } else {
- return 0;
- }
- }
-
- m_stopRec.inUse = false;
- return m_stopRec.reply;
-}
-
-/*****************************************************************************
- * Single user mode
- ****************************************************************************/
-
int
-MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId,
- EnterSingleCallback callback, void * anyData)
+MgmtSrvr::exitSingleUser(int * stopCount, bool abort)
{
- if(m_stopRec.singleUserMode) {
- return 5060;
- }
-
- if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API) {
- return 5062;
- }
- ClusterMgr::Node node;
-
- for(Uint32 i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- node = theFacade->theClusterMgr->getNodeInfo(i);
- if((node.m_state.startLevel != NodeState::SL_STARTED) &&
- (node.m_state.startLevel != NodeState::SL_NOTHING)) {
- return 5063;
- }
- }
- }
-
- if(m_stopRec.inUse){
- return 5029;
- }
-
- if(singleUserNodeId == 0)
- return 1;
- m_stopRec.singleUserMode = true;
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
NodeId nodeId = 0;
- Uint32 timeOut = 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- if(okToSendTo(nodeId, true) == 0){
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
- StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 1;
- stopReq->singleUserApi = singleUserNodeId;
- StopReq::setSystemStop(stopReq->requestInfo, false);
- StopReq::setPerformRestart(stopReq->requestInfo, false);
- StopReq::setStopAbort(stopReq->requestInfo, false);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
-
- m_stopRec.sentCount++;
- if(callback == 0)
- sendSignal(nodeId, WAIT_STOP, signal, true);
- else
- sendSignal(nodeId, NO_WAIT, signal, true);
- }
- }
-
- if(stopCount != 0)
- * stopCount = m_stopRec.sentCount;
+ int count = 0;
- if(callback == 0){
- m_stopRec.inUse = false;
- return 0;
- // return m_stopRec.reply;
- } else {
- return 0;
- }
+ SignalSender ss(theFacade);
+ ss.lock(); // lock will be released on exit
- m_stopRec.inUse = false;
- return m_stopRec.reply;
-}
+ SimpleSignal ssig;
+ ResumeReq* const resumeReq =
+ CAST_PTR(ResumeReq, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ,
+ ResumeReq::SignalLength);
+ resumeReq->senderData = 12;
+ resumeReq->senderRef = ss.getOwnRef();
-int
-MgmtSrvr::exitSingleUser(int * stopCount, bool abort,
- ExitSingleCallback callback, void * anyData)
-{
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- NodeId nodeId = 0;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
if(okToSendTo(nodeId, true) == 0){
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- ResumeReq* const resumeReq =
- CAST_PTR(ResumeReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ,
- StopReq::SignalLength);
- resumeReq->senderData = 12;
- resumeReq->senderRef = _ownReference;
-
- m_stopRec.sentCount++;
- if(callback == 0)
- sendSignal(nodeId, WAIT_STOP, signal, true);
- else
- sendSignal(nodeId, NO_WAIT, signal, true);
+ SendStatus result = ss.sendSignal(nodeId, &ssig);
+ if (result == SEND_OK)
+ count++;
}
}
- m_stopRec.singleUserMode = false;
-
if(stopCount != 0)
- * stopCount = m_stopRec.sentCount;
-
-
- if(callback == 0){
- m_stopRec.inUse = false;
- return m_stopRec.reply;
- } else {
- return 0;
- }
+ * stopCount = count;
- m_stopRec.inUse = false;
- return m_stopRec.reply;
+ return 0;
}
-
/*****************************************************************************
* Status
****************************************************************************/
@@ -1444,32 +1189,32 @@ MgmtSrvr::exitSingleUser(int * stopCount, bool abort,
#include <ClusterMgr.hpp>
int
-MgmtSrvr::status(int processId,
+MgmtSrvr::status(int nodeId,
ndb_mgm_node_status * _status,
Uint32 * version,
Uint32 * _phase,
bool * _system,
Uint32 * dynamic,
Uint32 * nodegroup,
- Uint32 * connectCount)
+ Uint32 * connectCount,
+ const char **address)
{
- if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API ||
- getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM) {
- if(versionNode(processId, false,0,0) ==0)
- * version = m_versionRec.version[processId];
- else
- * version = 0;
+ if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
+ getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) {
+ versionNode(nodeId, *version, address);
+ } else {
+ *address= get_connect_address(nodeId);
}
const ClusterMgr::Node node =
- theFacade->theClusterMgr->getNodeInfo(processId);
+ theFacade->theClusterMgr->getNodeInfo(nodeId);
if(!node.connected){
* _status = NDB_MGM_NODE_STATUS_NO_CONTACT;
return 0;
}
- if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB) {
+ if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) {
* version = node.m_info.m_version;
}
@@ -1532,67 +1277,81 @@ MgmtSrvr::status(int processId,
}
int
-MgmtSrvr::setEventReportingLevelImpl(int processId,
+MgmtSrvr::setEventReportingLevelImpl(int nodeId,
const EventSubscribeReq& ll)
{
-
- int result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal signal(_ownReference);
+ INIT_SIGNAL_SENDER(ss,nodeId);
+ SimpleSignal ssig;
EventSubscribeReq * dst =
- CAST_PTR(EventSubscribeReq, signal.getDataPtrSend());
-
- * dst = ll;
-
- signal.set(TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
- EventSubscribeReq::SignalLength);
-
- theFacade->lock_mutex();
- send(&signal, processId, NODE_TYPE_DB);
- theFacade->unlock_mutex();
-
+ CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
+ EventSubscribeReq::SignalLength);
+ *dst = ll;
+
+ send(ss,ssig,nodeId,NODE_TYPE_DB);
+
+#if 0
+ while (1)
+ {
+ SimpleSignal *signal = ss.waitFor();
+ int gsn = signal->readSignalNumber();
+ switch (gsn) {
+ case GSN_EVENT_SUBSCRIBE_CONF:{
+ break;
+ }
+ case GSN_EVENT_SUBSCRIBE_REF:{
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ case GSN_NF_COMPLETEREP:{
+ const NFCompleteRep * const rep =
+ CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
+ if (rep->failedNodeId == nodeId)
+ return SEND_OR_RECEIVE_FAILED;
+ break;
+ }
+ case GSN_NODE_FAILREP:{
+ const NodeFailRep * const rep =
+ CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
+ if (NodeBitmask::get(rep->theNodes,nodeId))
+ return SEND_OR_RECEIVE_FAILED;
+ break;
+ }
+ default:
+ report_unknown_signal(signal);
+ return SEND_OR_RECEIVE_FAILED;
+ }
+
+ }
+#endif
return 0;
}
//****************************************************************************
//****************************************************************************
int
-MgmtSrvr::setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll)
+MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll)
{
- int result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal signal(_ownReference);
-
- SetLogLevelOrd * dst = CAST_PTR(SetLogLevelOrd, signal.getDataPtrSend());
-
- * dst = ll;
-
- signal.set(TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
- SetLogLevelOrd::SignalLength);
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
+ SetLogLevelOrd::SignalLength);
+ SetLogLevelOrd* const dst = CAST_PTR(SetLogLevelOrd, ssig.getDataPtrSend());
+ *dst = ll;
- theFacade->lock_mutex();
- theFacade->sendSignalUnCond(&signal, processId);
- theFacade->unlock_mutex();
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
int
-MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){
+MgmtSrvr::send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type){
Uint32 max = (node == 0) ? MAX_NODES : node + 1;
for(; node < max; node++){
while(nodeTypes[node] != (int)node_type && node < max) node++;
if(nodeTypes[node] != (int)node_type)
break;
- theFacade->sendSignalUnCond(signal, node);
+ ss.sendSignal(node, &ssig);
}
return 0;
}
@@ -1601,34 +1360,21 @@ MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){
//****************************************************************************
int
-MgmtSrvr::insertError(int processId, int errorNo)
+MgmtSrvr::insertError(int nodeId, int errorNo)
{
if (errorNo < 0) {
return INVALID_ERROR_NUMBER;
}
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD,
+ TamperOrd::SignalLength);
+ TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, ssig.getDataPtrSend());
tamperOrd->errorNo = errorNo;
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD,
- TamperOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -1637,37 +1383,23 @@ MgmtSrvr::insertError(int processId, int errorNo)
//****************************************************************************
int
-MgmtSrvr::setTraceNo(int processId, int traceNo)
+MgmtSrvr::setTraceNo(int nodeId, int traceNo)
{
if (traceNo < 0) {
return INVALID_TRACE_NUMBER;
}
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
-
// Assume TRACE command causes toggling. Not really defined... ? TODO
testOrd->setTraceCommand(TestOrd::Toggle,
(TestOrd::TraceSpecification)traceNo);
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
-
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
//****************************************************************************
@@ -1686,14 +1418,10 @@ MgmtSrvr::getBlockNumber(const BaseString &blockName)
//****************************************************************************
int
-MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
+MgmtSrvr::setSignalLoggingMode(int nodeId, LogMode mode,
const Vector<BaseString>& blocks)
{
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
// Convert from MgmtSrvr format...
@@ -1728,12 +1456,10 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
return -1;
}
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
if (blocks.size() == 0 || blocks[0] == "ALL") {
@@ -1743,78 +1469,44 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
for(unsigned i = 0; i < blocks.size(); i++){
int blockNumber = getBlockNumber(blocks[i]);
if (blockNumber == -1) {
- releaseSignal(signal);
return INVALID_BLOCK_NAME;
}
testOrd->addSignalLoggerCommand(blockNumber, command, logSpec);
} // for
} // else
-
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
-
/*****************************************************************************
* Signal tracing
*****************************************************************************/
-int MgmtSrvr::startSignalTracing(int processId)
+int MgmtSrvr::startSignalTracing(int nodeId)
{
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
+ INIT_SIGNAL_SENDER(ss,nodeId);
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
+
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
testOrd->setTestCommand(TestOrd::On);
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
int
-MgmtSrvr::stopSignalTracing(int processId)
+MgmtSrvr::stopSignalTracing(int nodeId)
{
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
testOrd->setTestCommand(TestOrd::Off);
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -1823,7 +1515,7 @@ MgmtSrvr::stopSignalTracing(int processId)
*****************************************************************************/
int
-MgmtSrvr::dumpState(int processId, const char* args)
+MgmtSrvr::dumpState(int nodeId, const char* args)
{
// Convert the space separeted args
// string to an int array
@@ -1845,29 +1537,20 @@ MgmtSrvr::dumpState(int processId, const char* args)
}
}
- return dumpState(processId, args_array, numArgs);
+ return dumpState(nodeId, args_array, numArgs);
}
int
-MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no)
+MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no)
{
- int result;
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
const Uint32 len = no > 25 ? 25 : no;
+ SimpleSignal ssig;
DumpStateOrd * const dumpOrd =
- CAST_PTR(DumpStateOrd, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len);
+ CAST_PTR(DumpStateOrd, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len);
for(Uint32 i = 0; i<25; i++){
if (i < len)
dumpOrd->args[i] = args[i];
@@ -1875,12 +1558,7 @@ MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no)
dumpOrd->args[i] = 0;
}
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -1911,42 +1589,18 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
int gsn = signal->readSignalNumber();
switch (gsn) {
- case GSN_API_VERSION_CONF: {
- if (theWaitState == WAIT_VERSION) {
- const ApiVersionConf * const conf =
- CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
- if(m_versionRec.callback != 0)
- m_versionRec.callback(conf->nodeId, conf->version, this, 0);
- else {
- m_versionRec.version[conf->nodeId]=conf->version;
- }
- } else return;
- theWaitState = NO_WAIT;
- }
- break;
-
case GSN_EVENT_SUBSCRIBE_CONF:
break;
-
+ case GSN_EVENT_SUBSCRIBE_REF:
+ break;
case GSN_EVENT_REP:
eventReport(refToNode(signal->theSendersBlockRef), signal->getDataPtr());
break;
- case GSN_STOP_REF:{
- const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
- const NodeId nodeId = refToNode(signal->theSendersBlockRef);
- handleStopReply(nodeId, ref->errorCode);
- return;
- }
+ case GSN_NF_COMPLETEREP:
break;
-
- case GSN_MGM_LOCK_CONFIG_REP:
- case GSN_MGM_LOCK_CONFIG_REQ:
- case GSN_MGM_UNLOCK_CONFIG_REP:
- case GSN_MGM_UNLOCK_CONFIG_REQ: {
- m_signalRecvQueue.receive(new NdbApiSignal(*signal));
+ case GSN_NODE_FAILREP:
break;
- }
default:
g_eventLogger.error("Unknown signal received. SignalNumber: "
@@ -1961,75 +1615,6 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
}
}
-/**
- * A database node was either stopped or there was some error
- */
-void
-MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode)
-{
- /**
- * If we are in single user mode and get a stop reply from a
- * DB node, then we have had a node crash.
- * If all DB nodes are gone, and we are still in single user mode,
- * the set m_stopRec.singleUserMode = false;
- */
- if(m_stopRec.singleUserMode) {
- ClusterMgr::Node node;
- bool failure = true;
- for(Uint32 i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- node = theFacade->theClusterMgr->getNodeInfo(i);
- if((node.m_state.startLevel == NodeState::SL_NOTHING))
- failure = true;
- else
- failure = false;
- }
- }
- if(failure) {
- m_stopRec.singleUserMode = false;
- }
- }
- if(m_stopRec.inUse == false)
- return;
-
- if(!(m_stopRec.nodeId == 0 || m_stopRec.nodeId == nodeId))
- goto error;
-
- if(m_stopRec.sentCount <= 0)
- goto error;
-
- if(!(theWaitState == WAIT_STOP || m_stopRec.callback != 0))
- goto error;
-
- if(errCode != 0)
- m_stopRec.reply = translateStopRef(errCode);
-
- m_stopRec.sentCount --;
- if(m_stopRec.sentCount == 0){
- if(theWaitState == WAIT_STOP){
- theWaitState = NO_WAIT;
- NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
- return;
- }
- if(m_stopRec.callback != 0){
- m_stopRec.inUse = false;
- StopCallback callback = m_stopRec.callback;
- m_stopRec.callback = NULL;
- (* callback)(m_stopRec.nodeId,
- m_stopRec.anyData,
- m_stopRec.reply);
- return;
- }
- }
- return;
-
- error:
- if(errCode != 0){
- g_eventLogger.error("Unexpected signal received. SignalNumber: %i from %d",
- GSN_STOP_REF, nodeId);
- }
-}
-
void
MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
{
@@ -2043,16 +1628,8 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
theData[0] = NDB_LE_Disconnected;
if(nfComplete)
{
- handleStopReply(nodeId, 0);
DBUG_VOID_RETURN;
}
-
- if(theWaitNode == nodeId &&
- theWaitState != NO_WAIT && theWaitState != WAIT_STOP)
- {
- theWaitState = WAIT_NODEFAILURE;
- NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
- }
}
eventReport(_ownNodeId, theData);
@@ -2401,6 +1978,7 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData)
/***************************************************************************
* Backup
***************************************************************************/
+
int
MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
{
@@ -2415,7 +1993,6 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
if(!next) return NO_CONTACT_WITH_DB_NODES;
SimpleSignal ssig;
-
BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend());
ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ,
BackupReq::SignalLength);
@@ -2430,8 +2007,7 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
while (1) {
if (do_send)
{
- SendStatus result = ss.sendSignal(nodeId, &ssig);
- if (result != SEND_OK) {
+ if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
return SEND_OR_RECEIVE_FAILED;
}
if (waitCompleted == 0)
@@ -2533,13 +2109,13 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
return SEND_OR_RECEIVE_FAILED;
}
}
-
- return 0;
}
int
MgmtSrvr::abortBackup(Uint32 backupId)
{
+ SignalSender ss(theFacade);
+
bool next;
NodeId nodeId = 0;
while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
@@ -2549,25 +2125,17 @@ MgmtSrvr::abortBackup(Uint32 backupId)
return NO_CONTACT_WITH_DB_NODES;
}
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ SimpleSignal ssig;
- AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD,
- AbortBackupOrd::SignalLength);
+ AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, ssig.getDataPtrSend());
+ ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD,
+ AbortBackupOrd::SignalLength);
ord->requestType = AbortBackupOrd::ClientAbort;
ord->senderData = 19;
ord->backupId = backupId;
- int result = sendSignal(nodeId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -2582,26 +2150,6 @@ MgmtSrvr::repCommand(Uint32* repReqId, Uint32 request, bool waitCompleted)
return 0;
}
-
-NodeId
-MgmtSrvr::getPrimaryNode() const {
-#if 0
- Uint32 tmp;
- const Properties *prop = NULL;
-
- getConfig()->get("SYSTEM", &prop);
- if(prop == NULL)
- return 0;
-
- prop->get("PrimaryMGMNode", &tmp);
-
- return tmp;
-#else
- return 0;
-#endif
-}
-
-
MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m)
: m_mgmsrv(m)
{
@@ -2751,7 +2299,6 @@ MgmtSrvr::setDbParameter(int node, int param, const char * value,
NdbMutex_Unlock(m_configMutex);
return 0;
}
-
int
MgmtSrvr::setConnectionDbParameter(int node1,
int node2,
@@ -2886,10 +2433,6 @@ int MgmtSrvr::set_connect_string(const char *str)
}
-template class Vector<SigMatch>;
-#if __SUNPRO_CC != 0x560
-template bool SignalQueue::waitFor<SigMatch>(Vector<SigMatch>&, SigMatch**, NdbApiSignal**, unsigned);
-#endif
template class MutexVector<unsigned short>;
template class MutexVector<Ndb_mgmd_event_service::Event_listener>;
diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp
index de1af1286ff..3b14fa60e6b 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -22,15 +22,17 @@
#include <NdbCondition.h>
#include <mgmapi.h>
-
+#include <NdbTCP.h>
+#include <ConfigRetriever.hpp>
#include <Vector.hpp>
#include <NodeBitmask.hpp>
#include <signaldata/ManagementServer.hpp>
-#include "SignalQueue.hpp"
#include <ndb_version.h>
#include <EventLogger.hpp>
#include <signaldata/EventSubscribeReq.hpp>
+#include <SignalSender.hpp>
+
/**
* @desc Block number for Management server.
* @todo This should probably be somewhere else. I don't know where atm.
@@ -200,51 +202,26 @@ public:
~MgmtSrvr();
- int status(int processId,
- ndb_mgm_node_status * status,
+ /**
+ * Get status on a node.
+ * address may point to a common area (e.g. from inet_addr)
+ * There is no gaurentee that it is preserved across calls.
+ * Copy the string if you are not going to use it immediately.
+ */
+ int status(int nodeId,
+ ndb_mgm_node_status * status,
Uint32 * version,
Uint32 * phase,
bool * systemShutdown,
Uint32 * dynamicId,
Uint32 * nodeGroup,
- Uint32 * connectCount);
+ Uint32 * connectCount,
+ const char **address);
// All the functions below may return any of this error codes:
// NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE,
// COULD_NOT_ALLOCATE_MEMORY, SEND_OR_RECEIVE_FAILED
-
- typedef void (* StopCallback)(int nodeId, void * anyData, int errorCode);
-
- typedef void (* VersionCallback)(int nodeId, int version,
- void * anyData, int errorCode);
-
-
- typedef void (* EnterSingleCallback)(int nodeId, void * anyData,
- int errorCode);
- typedef void (* ExitSingleCallback)(int nodeId, void * anyData,
- int errorCode);
-
- /**
- * Lock configuration
- */
- int lockConf();
-
- /**
- * Unlock configuration, and commit it if commit is true
- */
- int unlockConf(bool commit);
-
- /**
- * Commit new configuration
- */
- int commitConfig();
-
- /**
- * Rollback configuration
- */
- int rollbackConfig();
-
/**
* Save a configuration to permanent storage
*/
@@ -273,12 +250,12 @@ public:
* @param processId: Id of the DB process to stop
* @return 0 if succeeded, otherwise: as stated above, plus:
*/
- int stopNode(int nodeId, bool abort = false, StopCallback = 0, void *any= 0);
+ int stopNode(int nodeId, bool abort = false);
/**
* Stop the system
*/
- int stop(int * cnt = 0, bool abort = false, StopCallback = 0, void *any = 0);
+ int stop(int * cnt = 0, bool abort = false);
/**
* print version info about a node
@@ -286,27 +263,18 @@ public:
* @param processId: Id of the DB process to stop
* @return 0 if succeeded, otherwise: as stated above, plus:
*/
- int versionNode(int nodeId, bool abort = false,
- VersionCallback = 0, void *any= 0);
+ int versionNode(int nodeId, Uint32 &version, const char **address);
/**
- * print version info about all node in the system
- */
- int version(int * cnt = 0, bool abort = false,
- VersionCallback = 0, void *any = 0);
-
- /**
* Maintenance on the system
*/
- int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0,
- EnterSingleCallback = 0, void *any = 0);
+ int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0);
/**
* Resume from maintenance on the system
*/
- int exitSingleUser(int * cnt = 0, bool abort = false,
- ExitSingleCallback = 0, void *any = 0);
+ int exitSingleUser(int * cnt = 0, bool abort = false);
/**
* Start DB process.
@@ -320,15 +288,14 @@ public:
* @param processId: Id of the DB process to start
*/
int restartNode(int processId, bool nostart, bool initialStart,
- bool abort = false,
- StopCallback = 0, void * anyData = 0);
+ bool abort = false);
/**
* Restart the system
*/
int restart(bool nostart, bool initialStart,
bool abort = false,
- int * stopCount = 0, StopCallback = 0, void * anyData = 0);
+ int * stopCount = 0);
struct BackupEvent {
enum Event {
@@ -483,13 +450,6 @@ public:
const Config * getConfig() const;
/**
- * Change configuration paramter
- */
- bool changeConfig(const BaseString &section,
- const BaseString &param,
- const BaseString &value);
-
- /**
* Returns the node count for the specified node type.
*
* @param type The node type.
@@ -498,11 +458,6 @@ public:
int getNodeCount(enum ndb_mgm_node_type type) const;
/**
- * Returns the nodeId of the management master
- */
- NodeId getPrimaryNode() const;
-
- /**
* Returns the port number.
* @return port number.
*/
@@ -528,8 +483,17 @@ public:
private:
//**************************************************************************
- int setEventReportingLevel(int processId, LogLevel::EventCategory, Uint32);
-
+ int send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type);
+
+ int sendSTOP_REQ(NodeId nodeId,
+ NodeBitmask &stoppedNodes,
+ Uint32 singleUserNodeId,
+ bool abort,
+ bool stop,
+ bool restart,
+ bool nostart,
+ bool initialStart);
+
/**
* Check if it is possible to send a signal to a (DB) process
*
@@ -593,9 +557,6 @@ private:
// Returns: -
//**************************************************************************
- void handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal);
- void handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal);
-
//**************************************************************************
// Specific signal handling data
//**************************************************************************
@@ -619,59 +580,8 @@ private:
enum WaitSignalType {
NO_WAIT, // We don't expect to receive any signal
WAIT_SET_VAR, // Accept SET_VAR_CONF and SET_VAR_REF
- WAIT_SUBSCRIBE_CONF, // Accept event subscription confirmation
- WAIT_STOP,
- WAIT_BACKUP_STARTED,
- WAIT_BACKUP_COMPLETED,
- WAIT_VERSION,
- WAIT_NODEFAILURE
+ WAIT_SUBSCRIBE_CONF // Accept event subscription confirmation
};
-
- /**
- * Get an unused signal
- * @return A signal if succeeded, NULL otherwise
- */
- NdbApiSignal* getSignal();
-
- /**
- * Add a signal to the list of unused signals
- * @param signal: The signal to add
- */
- void releaseSignal(NdbApiSignal* signal);
-
- /**
- * Remove a signal from the list of unused signals and delete
- * the memory for it.
- */
- void freeSignal();
-
- /**
- * Send a signal
- * @param processId: Id of the receiver process
- * @param waitState: State denoting a set of signals we accept to receive
- * @param signal: The signal to send
- * @return 0 if succeeded, -1 otherwise
- */
- int sendSignal(Uint16 processId, WaitSignalType waitState,
- NdbApiSignal* signal, bool force = false);
-
- /**
- * Send a signal and wait for an answer signal
- * @param processId: Id of the receiver process
- * @param waitState: State denoting a set of signals we accept to receive.
- * @param signal: The signal to send
- * @return 0 if succeeded, -1 otherwise (for example failed to send or
- * failed to receive expected signal).
- */
- int sendRecSignal(Uint16 processId, WaitSignalType waitState,
- NdbApiSignal* signal, bool force = false,
- int waitTime = WAIT_FOR_RESPONSE_TIMEOUT);
-
- /**
- * Wait for a signal to arrive.
- * @return 0 if signal arrived, -1 otherwise
- */
- int receiveOptimisedResponse(int waitTime);
/**
* This function is called from "outside" of MgmtSrvr
@@ -682,7 +592,7 @@ private:
static void signalReceivedNotification(void* mgmtSrvr,
NdbApiSignal* signal,
struct LinearSectionPtr ptr[3]);
-
+
/**
* Called from "outside" of MgmtSrvr when a DB process has died.
* @param mgmtSrvr: The MgmtSrvr object wreceiveOptimisedResponsehich
@@ -719,31 +629,7 @@ private:
class TransporterFacade * theFacade;
- class SignalQueue m_signalRecvQueue;
-
- struct StopRecord {
- StopRecord(){ inUse = false; callback = 0; singleUserMode = false;}
- bool inUse;
- bool singleUserMode;
- int sentCount;
- int reply;
- int nodeId;
- void * anyData;
- StopCallback callback;
- };
- StopRecord m_stopRec;
-
- struct VersionRecord {
- VersionRecord(){ inUse = false; callback = 0;}
- bool inUse;
- Uint32 version[MAX_NODES];
- VersionCallback callback;
- };
- VersionRecord m_versionRec;
- int sendVersionReq( int processId);
-
-
- void handleStopReply(NodeId nodeId, Uint32 errCode);
+ int sendVersionReq( int processId, Uint32 &version, const char **address);
int translateStopRef(Uint32 errCode);
bool _isStopThread;
@@ -764,14 +650,8 @@ private:
static void *logLevelThread_C(void *);
void logLevelThreadRun();
- struct NdbThread *m_signalRecvThread;
- static void *signalRecvThread_C(void *);
- void signalRecvThreadRun();
-
Config *_props;
- int send(class NdbApiSignal* signal, Uint32 node, Uint32 node_type);
-
ConfigRetriever *m_config_retriever;
};
diff --git a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
index 6c4b4e9ae3c..e56643a3d7e 100644
--- a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
@@ -23,228 +23,6 @@
#include <ConfigRetriever.hpp>
#include <ndb_version.h>
-void
-MgmtSrvr::handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal) {
- NodeId sender = refToNode(signal->theSendersBlockRef);
- const MgmLockConfigReq * const req = CAST_CONSTPTR(MgmLockConfigReq, signal->getDataPtr());
-
- NdbApiSignal *reply = getSignal();
- if(signal == NULL)
- return; /** @todo handle allocation failure */
-
- reply->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_LOCK_CONFIG_REP,
- MgmLockConfigRep::SignalLength);
-
- MgmLockConfigRep *lockRep = CAST_PTR(MgmLockConfigRep, reply->getDataPtrSend());
-
- lockRep->errorCode = MgmLockConfigRep::UNKNOWN_ERROR;
-
- if(req->newConfigGeneration < m_nextConfigGenerationNumber) {
- lockRep->errorCode = MgmLockConfigRep::GENERATION_MISMATCH;
- goto done;
- }
- NdbMutex_Lock(m_configMutex);
-
- m_nextConfigGenerationNumber = req->newConfigGeneration+1;
-
- lockRep->errorCode = MgmLockConfigRep::OK;
-
- done:
- sendSignal(sender, NO_WAIT, reply, true);
- NdbMutex_Unlock(m_configMutex);
- return;
-}
-
-void
-MgmtSrvr::handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal) {
- NodeId sender = refToNode(signal->theSendersBlockRef);
- const MgmUnlockConfigReq * const req = CAST_CONSTPTR(MgmUnlockConfigReq, signal->getDataPtr());
- MgmUnlockConfigRep *unlockRep;
-
- NdbApiSignal *reply = getSignal();
- if(signal == NULL)
- goto error; /** @todo handle allocation failure */
-
- reply->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_UNLOCK_CONFIG_REP,
- MgmUnlockConfigRep::SignalLength);
-
- unlockRep = CAST_PTR(MgmUnlockConfigRep, reply->getDataPtrSend());
-
- unlockRep->errorCode = MgmUnlockConfigRep::UNKNOWN_ERROR;
-
-
- NdbMutex_Lock(m_configMutex);
-
- if(req->commitConfig == 1) {
- m_newConfig = fetchConfig();
- commitConfig();
- } else
- rollbackConfig();
-
- unlockRep->errorCode = MgmUnlockConfigRep::OK;
-
- sendSignal(sender, NO_WAIT, reply, true);
- error:
- NdbMutex_Unlock(m_configMutex);
- return;
-}
-
-
-/**
- * Prepare all MGM nodes for configuration changes
- *
- * @returns 0 on success, or -1 on failure
- */
-int
-MgmtSrvr::lockConf() {
- int result = -1;
- MgmLockConfigReq* lockReq;
- NodeId node = 0;
-
- /* Check if this is the master node */
- if(getPrimaryNode() != _ownNodeId)
- goto done;
-
- if(NdbMutex_Trylock(m_configMutex) != 0)
- return -1;
-
- m_newConfig = new Config(*_config); /* copy the existing config */
- _config = m_newConfig;
-
- m_newConfig = new Config(*_config);
-
- m_nextConfigGenerationNumber++;
-
- /* Make sure the new configuration _always_ is at least one step older */
- if(m_nextConfigGenerationNumber < m_newConfig->getGenerationNumber()+1)
- m_nextConfigGenerationNumber = _config->getGenerationNumber()+1;
-
- m_newConfig->setGenerationNumber(m_nextConfigGenerationNumber);
-
- node = 0;
- while(getNextNodeId(&node, NDB_MGM_NODE_TYPE_MGM)) {
- if(node != _ownNodeId) {
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- result = COULD_NOT_ALLOCATE_MEMORY;
- goto done;
- }
-
- lockReq = CAST_PTR(MgmLockConfigReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_LOCK_CONFIG_REQ,
- MgmLockConfigReq::SignalLength);
-
- lockReq->newConfigGeneration = m_nextConfigGenerationNumber;
-
- result = sendSignal(node, NO_WAIT, signal, true);
-
- NdbApiSignal *reply =
- m_signalRecvQueue.waitFor(GSN_MGM_LOCK_CONFIG_REP, 0);
-
- if(reply == NULL) {
- /** @todo handle timeout/error */
- ndbout << __FILE__ << ":" << __LINE__ << endl;
- result = -1;
- goto done;
- }
-
- }
- }
-
- done:
- NdbMutex_Unlock(m_configMutex);
- return result;
-}
-
-/**
- * Unlocks configuration
- *
- * @returns 0 on success, ! 0 on error
- */
-int
-MgmtSrvr::unlockConf(bool commit) {
- int result = -1;
- MgmUnlockConfigReq* unlockReq;
- NodeId node = 0;
-
- /* Check if this is the master node */
- if(getPrimaryNode() != _ownNodeId)
- goto done;
-
- errno = 0;
- if(NdbMutex_Lock(m_configMutex) != 0)
- return -1;
-
- if(commit)
- commitConfig();
- else
- rollbackConfig();
-
- node = 0;
- while(getNextNodeId(&node, NDB_MGM_NODE_TYPE_MGM)) {
- if(node != _ownNodeId) {
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- result = COULD_NOT_ALLOCATE_MEMORY;
- goto done;
- }
-
- unlockReq = CAST_PTR(MgmUnlockConfigReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_UNLOCK_CONFIG_REQ,
- MgmUnlockConfigReq::SignalLength);
- unlockReq->commitConfig = commit;
-
- result = sendSignal(node, NO_WAIT, signal, true);
-
- NdbApiSignal *reply =
- m_signalRecvQueue.waitFor(GSN_MGM_UNLOCK_CONFIG_REP, 0);
-
- if(reply == NULL) {
- /** @todo handle timeout/error */
- result = -1;
- goto done;
- }
-
- }
- }
-
- done:
- NdbMutex_Unlock(m_configMutex);
- return result;
-}
-
-/**
- * Commit the new configuration
- */
-int
-MgmtSrvr::commitConfig() {
- int ret = saveConfig(m_newConfig);
- delete _config;
- _config = m_newConfig;
- m_newConfig = NULL;
- ndbout << "commit " << ret << endl;
- return ret;
-}
-
-/**
- * Rollback to the old configuration
- */
-int
-MgmtSrvr::rollbackConfig() {
- delete m_newConfig;
- m_newConfig = NULL;
- ndbout << "rollback" << endl;
- return saveConfig(_config);
-}
-
/**
* Save a configuration to the running configuration file
*/
@@ -274,7 +52,15 @@ Config *
MgmtSrvr::readConfig() {
Config *conf;
InitConfigFileParser parser;
- conf = parser.parseConfig(m_configFilename.c_str());
+ if (m_configFilename.length())
+ {
+ conf = parser.parseConfig(m_configFilename.c_str());
+ }
+ else
+ {
+ ndbout_c("Reading cluster configuration using my.cnf");
+ conf = parser.parse_mycnf();
+ }
return conf;
}
@@ -288,12 +74,3 @@ MgmtSrvr::fetchConfig() {
}
return 0;
}
-
-bool
-MgmtSrvr::changeConfig(const BaseString &section,
- const BaseString &param,
- const BaseString &value) {
- if(m_newConfig == NULL)
- return false;
- return m_newConfig->change(section, param, value);
-}
diff --git a/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp b/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
index f93948abc75..c99936e1861 100644
--- a/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
@@ -20,123 +20,3 @@
// Some kind of reuse should be preferred.
//******************************************************************************
-#include "MgmtSrvr.hpp"
-#include <NdbApiSignal.hpp>
-#include <NdbTick.h>
-
-
-NdbApiSignal*
-MgmtSrvr::getSignal()
-{
- NdbApiSignal* tSignal;
- tSignal = theSignalIdleList;
- if (tSignal != NULL){
- NdbApiSignal* tSignalNext = tSignal->next();
- tSignal->next(NULL);
- theSignalIdleList = tSignalNext;
- return tSignal;
- } else
- {
- tSignal = new NdbApiSignal(_ownReference);
- if (tSignal != NULL)
- tSignal->next(NULL);
- }
- return tSignal;
-}
-
-
-void
-MgmtSrvr::releaseSignal(NdbApiSignal* aSignal)
-{
- aSignal->next(theSignalIdleList);
- theSignalIdleList = aSignal;
-}
-
-
-void
-MgmtSrvr::freeSignal()
-{
- NdbApiSignal* tSignal = theSignalIdleList;
- theSignalIdleList = tSignal->next();
- delete tSignal;
-}
-
-
-int
-MgmtSrvr::sendSignal(Uint16 aNodeId,
- WaitSignalType aWaitState,
- NdbApiSignal* aSignal,
- bool force)
-{
- int tReturnCode;
- theFacade->lock_mutex();
- if(force){
- tReturnCode = theFacade->sendSignalUnCond(aSignal,
- aNodeId);
- } else {
- tReturnCode = theFacade->sendSignal(aSignal,
- aNodeId);
- }
- releaseSignal(aSignal);
- if (tReturnCode == -1) {
- theFacade->unlock_mutex();
- return -1;
- }
- theWaitState = aWaitState;
- theFacade->unlock_mutex();
- return 0;
-}
-
-
-int
-MgmtSrvr::sendRecSignal(Uint16 aNodeId,
- WaitSignalType aWaitState,
- NdbApiSignal* aSignal,
- bool force,
- int waitTime)
-{
- int tReturnCode;
- theFacade->lock_mutex();
- if(force){
- tReturnCode = theFacade->sendSignalUnCond(aSignal, aNodeId);
- } else {
- tReturnCode = theFacade->sendSignalUnCond(aSignal, aNodeId);
- }
- releaseSignal(aSignal);
- if (tReturnCode == -1) {
- theFacade->unlock_mutex();
- return -1;
- }
- theWaitState = aWaitState;
- theWaitNode = aNodeId;
- return receiveOptimisedResponse(waitTime);
-}
-
-
-int
-MgmtSrvr::receiveOptimisedResponse(int waitTime)
-{
- int tResultCode;
- theFacade->checkForceSend(_blockNumber);
- NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
-
- while (theWaitState != NO_WAIT && theWaitState != WAIT_NODEFAILURE
- && waitTime > 0) {
- NdbCondition_WaitTimeout(theMgmtWaitForResponseCondPtr,
- theFacade->theMutexPtr,
- waitTime);
- if(theWaitState == NO_WAIT || theWaitState == WAIT_NODEFAILURE)
- break;
- waitTime = (maxTime - NdbTick_CurrentMillisecond());
- }//while
-
- if(theWaitState == NO_WAIT) {
- tResultCode = 0;
- } else {
- tResultCode = -1;
- }
- theFacade->unlock_mutex();
- return tResultCode;
-}
-
-
diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp
index ed32ab9c963..8c087c2a3ca 100644
--- a/ndb/src/mgmsrv/Services.cpp
+++ b/ndb/src/mgmsrv/Services.cpp
@@ -222,21 +222,6 @@ ParserRow<MgmApiSession> commands[] = {
MGM_ARG("level", Int, Mandatory, "Severety level"),
MGM_ARG("enable", Int, Mandatory, "1=disable, 0=enable, -1=toggle"),
- MGM_CMD("config lock", &MgmApiSession::configLock, ""),
-
- MGM_CMD("config unlock", &MgmApiSession::configUnlock, ""),
- MGM_ARG("commit", Int, Mandatory, "Commit changes"),
-
- MGM_CMD("config change", &MgmApiSession::configChange, ""),
- MGM_ARG("section", String, Mandatory, "Section"),
- MGM_ARG("parameter", String, Mandatory, "Parameter"),
- MGM_ARG("value", String, Mandatory, "Value"),
-
- MGM_CMD("config lock", &MgmApiSession::configLock, ""),
-
- MGM_CMD("config unlock", &MgmApiSession::configUnlock, ""),
- MGM_ARG("commit", Int, Mandatory, "Commit changes"),
-
MGM_CMD("set parameter", &MgmApiSession::setParameter, ""),
MGM_ARG("node", String, Mandatory, "Node"),
MGM_ARG("parameter", String, Mandatory, "Parameter"),
@@ -940,8 +925,10 @@ printNodeStatus(OutputStream *output,
nodeGroup = 0,
connectCount = 0;
bool system;
- mgmsrv.status(nodeId, &status, &version, &startPhase,
- &system, &dynamicId, &nodeGroup, &connectCount);
+ const char *address= NULL;
+ mgmsrv.status(nodeId, &status, &version, &startPhase,
+ &system, &dynamicId, &nodeGroup, &connectCount,
+ &address);
output->println("node.%d.type: %s",
nodeId,
ndb_mgm_get_node_type_string(type));
@@ -953,7 +940,7 @@ printNodeStatus(OutputStream *output,
output->println("node.%d.dynamic_id: %d", nodeId, dynamicId);
output->println("node.%d.node_group: %d", nodeId, nodeGroup);
output->println("node.%d.connect_count: %d", nodeId, connectCount);
- output->println("node.%d.address: %s", nodeId, mgmsrv.get_connect_address(nodeId));
+ output->println("node.%d.address: %s", nodeId, address);
}
}
@@ -1222,42 +1209,6 @@ MgmApiSession::setLogFilter(Parser_t::Context &ctx,
m_output->println("");
}
-void
-MgmApiSession::configLock(Parser_t::Context &,
- Properties const &) {
- int ret = m_mgmsrv.lockConf();
- m_output->println("config lock reply");
- m_output->println("result: %d", ret);
- m_output->println("");
-}
-
-void
-MgmApiSession::configUnlock(Parser_t::Context &,
- Properties const &args) {
- Uint32 commit;
- args.get("commit", &commit);
- int ret = m_mgmsrv.unlockConf(commit == 1);
- m_output->println("config unlock reply");
- m_output->println("result: %d", ret);
- m_output->println("");
-}
-
-void
-MgmApiSession::configChange(Parser_t::Context &,
- Properties const &args) {
- BaseString section, param, value;
- args.get("section", section);
- args.get("parameter", param);
- args.get("value", value);
-
- int ret = m_mgmsrv.changeConfig(section.c_str(),
- param.c_str(),
- value.c_str());
- m_output->println("config change reply");
- m_output->println("result: %d", ret);
- m_output->println("");
-}
-
static NdbOut&
operator<<(NdbOut& out, const LogLevel & ll)
{
diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp
index ff9008b05a8..431126a1f35 100644
--- a/ndb/src/mgmsrv/Services.hpp
+++ b/ndb/src/mgmsrv/Services.hpp
@@ -83,9 +83,6 @@ public:
void setClusterLogLevel(Parser_t::Context &ctx,
const class Properties &args);
void setLogFilter(Parser_t::Context &ctx, const class Properties &args);
- void configLock(Parser_t::Context &ctx, const class Properties &args);
- void configUnlock(Parser_t::Context &ctx, const class Properties &args);
- void configChange(Parser_t::Context &ctx, const class Properties &args);
void setParameter(Parser_t::Context &ctx, const class Properties &args);
void setConnectionParameter(Parser_t::Context &ctx,
diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp
index ec20101493e..f0c2ac298a5 100644
--- a/ndb/src/mgmsrv/main.cpp
+++ b/ndb/src/mgmsrv/main.cpp
@@ -102,6 +102,7 @@ static int opt_daemon; // NOT bool, bool need not be int
static int opt_non_interactive;
static int opt_interactive;
static const char * opt_config_filename= 0;
+static int opt_mycnf = 0;
struct MgmGlobals {
MgmGlobals();
@@ -166,6 +167,10 @@ static struct my_option my_long_options[] =
"Don't run as daemon, but don't read from stdin",
(gptr*) &opt_non_interactive, (gptr*) &opt_non_interactive, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "mycnf", 256,
+ "Read cluster config from my.cnf",
+ (gptr*) &opt_mycnf, (gptr*) &opt_mycnf, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -199,7 +204,7 @@ int main(int argc, char** argv)
#endif
global_mgmt_server_check = 1;
-
+
const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
load_defaults("my",load_default_groups,&argc,&argv);
@@ -217,13 +222,26 @@ int main(int argc, char** argv)
opt_daemon= 0;
}
+ if (opt_mycnf && opt_config_filename)
+ {
+ ndbout_c("Both --mycnf and -f is not supported");
+ return 0;
+ }
+
+ if (opt_mycnf == 0 && opt_config_filename == 0)
+ {
+ struct stat buf;
+ if (stat("config.ini", &buf) != -1)
+ opt_config_filename = "config.ini";
+ }
+
glob->socketServer = new SocketServer();
MgmApiService * mapi = new MgmApiService();
glob->mgmObject = new MgmtSrvr(glob->socketServer,
- opt_config_filename,
- opt_connect_str);
+ opt_config_filename,
+ opt_connect_str);
if (g_print_full_config)
goto the_end;
diff --git a/ndb/tools/ndb_config.cpp b/ndb/tools/ndb_config.cpp
index 290dd440479..1b9a771f243 100644
--- a/ndb/tools/ndb_config.cpp
+++ b/ndb/tools/ndb_config.cpp
@@ -42,6 +42,8 @@ static const char * g_type = 0;
static const char * g_host = 0;
static const char * g_field_delimiter=",";
static const char * g_row_delimiter=" ";
+static const char * g_config_file = 0;
+static int g_mycnf = 0;
int g_print_full_config, opt_ndb_shm;
my_bool opt_core;
@@ -92,6 +94,12 @@ static struct my_option my_long_options[] =
{ "rows", 'r', "Row separator",
(gptr*) &g_row_delimiter, (gptr*) &g_row_delimiter,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ { "config-file", 256, "Path to config.ini",
+ (gptr*) &g_config_file, (gptr*) &g_config_file,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ { "mycnf", 256, "Read config from my.cnf",
+ (gptr*) &g_mycnf, (gptr*) &g_mycnf,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -126,7 +134,7 @@ struct Match
{
int m_key;
BaseString m_value;
- virtual int eval(NdbMgmHandle, const Iter&);
+ virtual int eval(const Iter&);
};
struct HostMatch : public Match
@@ -139,18 +147,21 @@ struct Apply
Apply() {}
Apply(int val) { m_key = val;}
int m_key;
- virtual int apply(NdbMgmHandle, const Iter&);
+ virtual int apply(const Iter&);
};
struct NodeTypeApply : public Apply
{
- virtual int apply(NdbMgmHandle, const Iter&);
+ virtual int apply(const Iter&);
};
static int parse_query(Vector<Apply*>&, int &argc, char**& argv);
static int parse_where(Vector<Match*>&, int &argc, char**& argv);
-static int eval(NdbMgmHandle, const Iter&, const Vector<Match*>&);
-static int apply(NdbMgmHandle, const Iter&, const Vector<Apply*>&);
+static int eval(const Iter&, const Vector<Match*>&);
+static int apply(const Iter&, const Vector<Apply*>&);
+static ndb_mgm_configuration* fetch_configuration();
+static ndb_mgm_configuration* load_configuration();
+
int
main(int argc, char** argv){
NDB_INIT(argv[0]);
@@ -161,51 +172,16 @@ main(int argc, char** argv){
ndb_std_get_one_option)))
return -1;
- NdbMgmHandle mgm = ndb_mgm_create_handle();
- if(mgm == NULL) {
- fprintf(stderr, "Cannot create handle to management server.\n");
- exit(-1);
- }
+ ndb_mgm_configuration * conf = 0;
- ndb_mgm_set_error_stream(mgm, stderr);
-
- if (ndb_mgm_set_connectstring(mgm, g_connectstring))
- {
- fprintf(stderr, "* %5d: %s\n",
- ndb_mgm_get_latest_error(mgm),
- ndb_mgm_get_latest_error_msg(mgm));
- fprintf(stderr,
- "* %s", ndb_mgm_get_latest_error_desc(mgm));
- exit(-1);
- }
+ if (g_config_file || g_mycnf)
+ conf = load_configuration();
+ else
+ conf = fetch_configuration();
- if(ndb_mgm_connect(mgm, try_reconnect-1, 5, 1))
+ if (conf == 0)
{
- fprintf(stderr, "Connect failed");
- fprintf(stderr, " code: %d, msg: %s\n",
- ndb_mgm_get_latest_error(mgm),
- ndb_mgm_get_latest_error_msg(mgm));
- exit(-1);
- }
- else if(g_verbose)
- {
- fprintf(stderr, "Connected to %s:%d\n",
- ndb_mgm_get_connected_host(mgm),
- ndb_mgm_get_connected_port(mgm));
- }
-
- ndb_mgm_configuration * conf = ndb_mgm_get_configuration(mgm, 0);
- if(conf == 0)
- {
- fprintf(stderr, "Could not get configuration");
- fprintf(stderr, "code: %d, msg: %s\n",
- ndb_mgm_get_latest_error(mgm),
- ndb_mgm_get_latest_error_msg(mgm));
- exit(-1);
- }
- else if(g_verbose)
- {
- fprintf(stderr, "Fetched configuration\n");
+ return -1;
}
Vector<Apply*> select_list;
@@ -231,12 +207,12 @@ main(int argc, char** argv){
iter.first();
for(iter.first(); iter.valid(); iter.next())
{
- if(eval(mgm, iter, where_clause))
+ if(eval(iter, where_clause))
{
if(prev)
printf("%s", g_row_delimiter);
prev= true;
- apply(mgm, iter, select_list);
+ apply(iter, select_list);
}
}
printf("\n");
@@ -331,11 +307,11 @@ template class Vector<Match*>;
static
int
-eval(NdbMgmHandle mgm, const Iter& iter, const Vector<Match*>& where)
+eval(const Iter& iter, const Vector<Match*>& where)
{
for(unsigned i = 0; i<where.size(); i++)
{
- if(where[i]->eval(mgm, iter) == 0)
+ if(where[i]->eval(iter) == 0)
return 0;
}
@@ -344,11 +320,11 @@ eval(NdbMgmHandle mgm, const Iter& iter, const Vector<Match*>& where)
static
int
-apply(NdbMgmHandle mgm, const Iter& iter, const Vector<Apply*>& list)
+apply(const Iter& iter, const Vector<Apply*>& list)
{
for(unsigned i = 0; i<list.size(); i++)
{
- list[i]->apply(mgm, iter);
+ list[i]->apply(iter);
if(i + 1 != list.size())
printf("%s", g_field_delimiter);
}
@@ -356,19 +332,19 @@ apply(NdbMgmHandle mgm, const Iter& iter, const Vector<Apply*>& list)
}
int
-Match::eval(NdbMgmHandle h, const Iter& iter)
+Match::eval(const Iter& iter)
{
Uint32 val32;
Uint64 val64;
const char* valc;
if (iter.get(m_key, &val32) == 0)
{
- if(atoi(m_value.c_str()) != val32)
+ if(atoi(m_value.c_str()) != (int)val32)
return 0;
}
else if(iter.get(m_key, &val64) == 0)
{
- if(strtoll(m_value.c_str(), (char **)NULL, 10) != val64)
+ if(strtoll(m_value.c_str(), (char **)NULL, 10) != (long long)val64)
return 0;
}
else if(iter.get(m_key, &valc) == 0)
@@ -418,7 +394,7 @@ HostMatch::eval(NdbMgmHandle h, const Iter& iter)
}
int
-Apply::apply(NdbMgmHandle h, const Iter& iter)
+Apply::apply(const Iter& iter)
{
Uint32 val32;
Uint64 val64;
@@ -439,7 +415,7 @@ Apply::apply(NdbMgmHandle h, const Iter& iter)
}
int
-NodeTypeApply::apply(NdbMgmHandle h, const Iter& iter)
+NodeTypeApply::apply(const Iter& iter)
{
Uint32 val32;
if (iter.get(CFG_TYPE_OF_SECTION, &val32) == 0)
@@ -448,3 +424,86 @@ NodeTypeApply::apply(NdbMgmHandle h, const Iter& iter)
}
return 0;
}
+
+ndb_mgm_configuration*
+fetch_configuration()
+{
+ ndb_mgm_configuration* conf = 0;
+ NdbMgmHandle mgm = ndb_mgm_create_handle();
+ if(mgm == NULL) {
+ fprintf(stderr, "Cannot create handle to management server.\n");
+ return 0;
+ }
+
+ ndb_mgm_set_error_stream(mgm, stderr);
+
+ if (ndb_mgm_set_connectstring(mgm, g_connectstring))
+ {
+ fprintf(stderr, "* %5d: %s\n",
+ ndb_mgm_get_latest_error(mgm),
+ ndb_mgm_get_latest_error_msg(mgm));
+ fprintf(stderr,
+ "* %s", ndb_mgm_get_latest_error_desc(mgm));
+ goto noconnect;
+ }
+
+ if(ndb_mgm_connect(mgm, try_reconnect-1, 5, 1))
+ {
+ fprintf(stderr, "Connect failed");
+ fprintf(stderr, " code: %d, msg: %s\n",
+ ndb_mgm_get_latest_error(mgm),
+ ndb_mgm_get_latest_error_msg(mgm));
+ goto noconnect;
+ }
+ else if(g_verbose)
+ {
+ fprintf(stderr, "Connected to %s:%d\n",
+ ndb_mgm_get_connected_host(mgm),
+ ndb_mgm_get_connected_port(mgm));
+ }
+
+ conf = ndb_mgm_get_configuration(mgm, 0);
+ if(conf == 0)
+ {
+ fprintf(stderr, "Could not get configuration");
+ fprintf(stderr, "code: %d, msg: %s\n",
+ ndb_mgm_get_latest_error(mgm),
+ ndb_mgm_get_latest_error_msg(mgm));
+ }
+ else if(g_verbose)
+ {
+ fprintf(stderr, "Fetched configuration\n");
+ }
+
+ ndb_mgm_disconnect(mgm);
+noconnect:
+ ndb_mgm_destroy_handle(&mgm);
+
+ return conf;
+}
+
+#include <Config.hpp>
+
+ndb_mgm_configuration*
+load_configuration()
+{
+ InitConfigFileParser parser(stderr);
+ if (g_config_file)
+ {
+ if (g_verbose)
+ fprintf(stderr, "Using config.ini : %s", g_config_file);
+
+ Config* conf = parser.parseConfig(g_config_file);
+ if (conf)
+ return conf->m_configValues;
+ }
+
+ if (g_verbose)
+ fprintf(stderr, "Using my.cnf");
+
+ Config* conf = parser.parse_mycnf();
+ if (conf)
+ return conf->m_configValues;
+
+ return 0;
+}
diff --git a/ndb/tools/ndb_size.pl b/ndb/tools/ndb_size.pl
new file mode 100644
index 00000000000..64a20423636
--- /dev/null
+++ b/ndb/tools/ndb_size.pl
@@ -0,0 +1,263 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+use DBI;
+use POSIX;
+use HTML::Template;
+
+# MySQL Cluster size estimator
+# ----------------------------
+#
+# (C)2005 MySQL AB
+#
+#
+# The purpose of this tool is to work out storage requirements
+# from an existing MySQL database.
+#
+# This involves connecting to a mysql server and throwing a bunch
+# of queries at it.
+#
+# We currently estimate sizes for: 4.1, 5.0 and 5.1 to various amounts
+# of accurracy.
+#
+# There is no warranty.
+#
+# BUGS
+# ----
+# - enum/set is 0 byte storage! Woah - efficient!
+# - some float stores come out weird (when there's a comma e.g. 'float(4,1)')
+# - no disk data values
+# - computes the storage requirements of views (and probably MERGE)
+# - ignores character sets.
+
+my $template = HTML::Template->new(filename => 'ndb_size.tmpl',
+ die_on_bad_params => 0);
+
+my $dbh;
+
+{
+ my $database= $ARGV[0];
+ my $hostname= $ARGV[1];
+ my $port= $ARGV[2];
+ my $user= $ARGV[3];
+ my $password= $ARGV[4];
+ my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port";
+ $dbh= DBI->connect($dsn, $user, $password);
+ $template->param(db => $database);
+ $template->param(dsn => $dsn);
+}
+
+my @releases = ({rel=>'4.1'},{rel=>'5.0'},{rel=>'5.1'});
+$template->param(releases => \@releases);
+
+my $tables = $dbh->selectall_arrayref("show tables");
+
+my @table_size;
+
+sub align {
+ my($to,@unaligned) = @_;
+ my @aligned;
+ foreach my $x (@unaligned) {
+ push @aligned, $to * POSIX::floor(($x+$to-1)/$to);
+ }
+ return @aligned;
+}
+
+foreach(@{$tables})
+{
+ my $table= @{$_}[0];
+ my @columns;
+ my $info= $dbh->selectall_hashref("describe ".$dbh->quote($table),"Field");
+ my @count = $dbh->selectrow_array("select count(*) from "
+ .$dbh->quote($table));
+ my %columnsize; # used for index calculations
+
+ # We now work out the DataMemory usage
+
+ # sizes for 4.1, 5.0, 5.1
+ my @totalsize= (0,0,0);
+
+ foreach(keys %$info)
+ {
+ my @realsize = (0,0,0);
+ my $type;
+ my $size;
+ my $name= $_;
+
+ if($$info{$_}{Type} =~ /^(.*?)\((\d+)\)/)
+ {
+ $type= $1;
+ $size= $2;
+ }
+ else
+ {
+ $type= $$info{$_}{Type};
+ }
+
+ if($type =~ /tinyint/)
+ {@realsize=(1,1,1)}
+ elsif($type =~ /smallint/)
+ {@realsize=(2,2,2)}
+ elsif($type =~ /mediumint/)
+ {@realsize=(3,3,3)}
+ elsif($type =~ /bigint/)
+ {@realsize=(8,8,8)}
+ elsif($type =~ /int/)
+ {@realsize=(4,4,4)}
+ elsif($type =~ /float/)
+ {
+ if($size<=24)
+ {@realsize=(4,4,4)}
+ else
+ {@realsize=(8,8,8)}
+ }
+ elsif($type =~ /double/ || $type =~ /real/)
+ {@realsize=(8,8,8)}
+ elsif($type =~ /bit/)
+ {
+ my $a=($size+7)/8;
+ @realsize = ($a,$a,$a);
+ }
+ elsif($type =~ /datetime/)
+ {@realsize=(8,8,8)}
+ elsif($type =~ /timestamp/)
+ {@realsize=(4,4,4)}
+ elsif($type =~ /date/ || $type =~ /time/)
+ {@realsize=(3,3,3)}
+ elsif($type =~ /year/)
+ {@realsize=(1,1,1)}
+ elsif($type =~ /varchar/ || $type =~ /varbinary/)
+ {
+ my $fixed= 1+$size;
+ my @dynamic=$dbh->selectrow_array("select avg(length("
+ .$dbh->quote($name)
+ .")) from ".$dbh->quote($table));
+ $dynamic[0]=0 if !$dynamic[0];
+ @realsize= ($fixed,$fixed,ceil($dynamic[0]));
+ }
+ elsif($type =~ /binary/ || $type =~ /char/)
+ {@realsize=($size,$size,$size)}
+ elsif($type =~ /text/ || $type =~ /blob/)
+ {@realsize=(256,256,1)} # FIXME check if 5.1 is correct
+
+ @realsize= align(4,@realsize);
+
+ $totalsize[$_]+=$realsize[$_] foreach 0..$#totalsize;
+
+ my @realout;
+ push @realout,{val=>$_} foreach @realsize;
+
+ push @columns, {
+ name=>$name,
+ type=>$type,
+ size=>$size,
+ key=>$$info{$_}{Key},
+ datamemory=>\@realout,
+ };
+
+ $columnsize{$name}= \@realsize; # used for index calculations
+ }
+
+ # And now... the IndexMemory usage.
+ #
+ # Firstly, we assemble some information about the indexes.
+ # We use SHOW INDEX instead of using INFORMATION_SCHEMA so
+ # we can still connect to pre-5.0 mysqlds.
+ my %indexes;
+ {
+ my $sth= $dbh->prepare("show index from "$dbh->quote($table));
+ $sth->execute;
+ while(my $i = $sth->fetchrow_hashref)
+ {
+ $indexes{${%$i}{Key_name}}= {
+ type=>${%$i}{Index_type},
+ unique=>!${%$i}{Non_unique},
+ comment=>${%$i}{Comment},
+ } if !defined($indexes{${%$i}{Key_name}});
+
+ $indexes{${%$i}{Key_name}}{columns}[${%$i}{Seq_in_index}-1]=
+ ${%$i}{Column_name};
+ }
+ }
+
+ if(!defined($indexes{PRIMARY})) {
+ $indexes{PRIMARY}= {
+ type=>'BTREE',
+ unique=>1,
+ comment=>'Hidden pkey created by NDB',
+ columns=>['HIDDEN_NDB_PKEY'],
+ };
+ push @columns, {
+ name=>'HIDDEN_NDB_PKEY',
+ type=>'bigint',
+ size=>8,
+ key=>'PRI',
+ datamemory=>[{val=>8},{val=>8},{val=>8}],
+ };
+ $columnsize{'HIDDEN_NDB_PKEY'}= [8,8,8];
+ }
+
+ my @IndexDataMemory= ({val=>0},{val=>0},{val=>0});
+ my @RowIndexMemory= ({val=>0},{val=>0},{val=>0});
+
+ my @indexes;
+ foreach my $index (keys %indexes) {
+ my $im41= 25;
+ $im41+=$columnsize{$_}[0] foreach @{$indexes{$index}{columns}};
+ my @im = ({val=>$im41},{val=>25},{val=>25});
+ my @dm = ({val=>10},{val=>10},{val=>10});
+ push @indexes, {
+ name=>$index,
+ type=>$indexes{$index}{type},
+ columns=>join(',',@{$indexes{$index}{columns}}),
+ indexmemory=>\@im,
+ datamemory=>\@dm,
+ };
+ $IndexDataMemory[$_]{val}+=$dm[$_]{val} foreach 0..2;
+ $RowIndexMemory[$_]{val}+=$im[$_]{val} foreach 0..2;
+ }
+
+ # total size + 16 bytes overhead
+ my @TotalDataMemory;
+ $TotalDataMemory[$_]{val}=$IndexDataMemory[$_]{val}+$totalsize[$_]+16 foreach 0..2;
+
+ my @RowDataMemory;
+ push @RowDataMemory,{val=>$_} foreach @totalsize;
+
+ my @RowPerPage;
+ push @RowPerPage,{val=>(floor((32768-128)/$TotalDataMemory[$_]{val}))} foreach 0..$#TotalDataMemory;
+
+ my @RowPerIndexPage;
+ push @RowPerIndexPage,{val=>(floor(8192/$RowIndexMemory[$_]{val}))} foreach 0..$#TotalDataMemory;
+
+ my @DataMemory;
+ push @DataMemory,{val=>ceil(($count[0]/($RowPerPage[$_]{val})))*32} foreach 0..$#RowPerPage;
+
+ my @IndexMemory;
+ push @IndexMemory,{val=>ceil(($count[0]/($RowPerIndexPage[$_]{val})))*8} foreach 0..$#RowPerPage;
+
+ my $count= $count[0];
+ my @counts;
+ $counts[$_]{val}= $count foreach 0..$#releases;
+
+ push @table_size, {
+ table=>$table,
+ indexes=>\@indexes,
+ columns=>\@columns,
+ count=>\@counts,
+ RowDataMemory=>\@RowDataMemory,
+ releases=>\@releases,
+ IndexDataMemory=>\@IndexDataMemory,
+ TotalDataMemory=>\@TotalDataMemory,
+ RowPerPage=>\@RowPerPage,
+ DataMemory=>\@DataMemory,
+ RowIndexMemory=>\@RowIndexMemory,
+ RowPerIndexPage=>\@RowPerIndexPage,
+ IndexMemory=>\@IndexMemory,
+
+ };
+}
+
+$template->param(tables => \@table_size);
+print $template->output;
diff --git a/ndb/tools/ndb_size.tmpl b/ndb/tools/ndb_size.tmpl
new file mode 100644
index 00000000000..d83d5d2c6af
--- /dev/null
+++ b/ndb/tools/ndb_size.tmpl
@@ -0,0 +1,175 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/>
+ <meta name="keywords" content="MySQL Cluster" />
+ <title>MySQL Cluster size estimate for <TMPL_VAR NAME="db" ESCAPE="HTML"></title>
+<style type="text/css">
+table { border-collapse: collapse }
+td,th { border: 1px solid black }
+</style>
+ </head>
+<body>
+<h1>MySQL Cluster analysis for <TMPL_VAR NAME="db" escape="html"></h1>
+<p>This is an automated analysis of the <TMPL_VAR NAME="DSN" escape="html"> database for migration into <a href="http://www.mysql.com/">MySQL</a> Cluster. No warranty is made to the accuracy of the information.</p>
+
+<p>This information should be valid for MySQL 4.1</p>
+
+<ul>
+<TMPL_LOOP NAME="tables">
+<li><TMPL_VAR NAME="table"></li>
+</TMPL_LOOP>
+</ul>
+
+<hr/>
+
+<TMPL_LOOP NAME="tables">
+<h2><TMPL_VAR NAME="table"></h2>
+<table>
+ <tr>
+ <th>Column</th>
+ <th>Type</th>
+ <th>Size</th>
+ <th>Key</th>
+ <TMPL_LOOP NAME=releases>
+ <th><TMPL_VAR NAME=rel> NDB Size</th>
+ </TMPL_LOOP>
+ </tr>
+ <TMPL_LOOP NAME="columns">
+ <tr>
+ <td><TMPL_VAR NAME=name></td>
+ <td><TMPL_VAR NAME=type></td>
+ <td><TMPL_VAR NAME=size></td>
+ <td><TMPL_VAR NAME=key></td>
+ <TMPL_LOOP NAME=datamemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+ </tr>
+ </TMPL_LOOP>
+</table>
+
+<p>&nbsp;</p>
+
+<h3>Indexes</h3>
+
+<p>We assume that indexes are ORDERED (not created USING HASH). If order is not required, 10 bytes of data memory can be saved per row if the index is created USING HASH</p>
+<table>
+<tr>
+ <th>Index</th>
+ <th>Type</th>
+ <th>Columns</th>
+ <TMPL_LOOP NAME=releases>
+ <th><TMPL_VAR NAME=rel> IdxMem</th>
+ </TMPL_LOOP>
+ <TMPL_LOOP NAME=releases>
+ <th><TMPL_VAR NAME=rel> DatMem</th>
+ </TMPL_LOOP>
+</tr>
+<TMPL_LOOP NAME="indexes">
+ <tr>
+ <td><TMPL_VAR NAME=name></td>
+ <td><TMPL_VAR NAME=type></td>
+ <td><TMPL_VAR NAME=columns></td>
+ <TMPL_LOOP NAME=indexmemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+ <TMPL_LOOP NAME=datamemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+ </tr>
+</TMPL_LOOP>
+</table>
+
+<h3>DataMemory Usage</h3>
+<table>
+<tr>
+ <th>&nbsp;</th>
+ <TMPL_LOOP NAME=releases>
+ <th><TMPL_VAR NAME=rel></th>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Row Overhead</th>
+ <TMPL_LOOP NAME=releases>
+ <td>16</td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Column DataMemory/Row</th>
+ <TMPL_LOOP NAME=RowDataMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Index DataMemory/Row</th>
+ <TMPL_LOOP NAME=IndexDataMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Total DataMemory/Row</th>
+ <TMPL_LOOP NAME=TotalDataMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Rows per 32kb page</th>
+ <TMPL_LOOP NAME=RowPerPage>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Current number of rows</th>
+ <TMPL_LOOP NAME=count>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Total DataMemory (kb)</th>
+ <TMPL_LOOP NAME=DataMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+</table>
+
+<h3>IndexMemory Usage</h3>
+<table>
+<tr>
+ <th>&nbsp;</th>
+ <TMPL_LOOP NAME=releases>
+ <th><TMPL_VAR NAME=rel></th>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>IndexMemory/Row</th>
+ <TMPL_LOOP NAME=RowIndexMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Rows per 8kb page</th>
+ <TMPL_LOOP NAME=RowPerIndexPage>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Current number of rows</th>
+ <TMPL_LOOP NAME=count>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Total IndexMemory (kb)</th>
+ <TMPL_LOOP NAME=IndexMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+</table>
+
+<hr/>
+</TMPL_LOOP>
+
+<p>This is the output of ndb_size.pl.</p>
+</body>
+</html>
+
diff --git a/ndb/tools/restore/consumer_restore.cpp b/ndb/tools/restore/consumer_restore.cpp
index 5786bdac697..552246a4f9e 100644
--- a/ndb/tools/restore/consumer_restore.cpp
+++ b/ndb/tools/restore/consumer_restore.cpp
@@ -38,7 +38,7 @@ BackupRestore::init()
m_cluster_connection = new Ndb_cluster_connection(g_connect_string);
if(m_cluster_connection->connect(12, 5, 1) != 0)
{
- return -1;
+ return false;
}
m_ndb = new Ndb(m_cluster_connection);