1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
#include <Configuration.hpp>
19
#include <kernel_types.h>
20
#include <TransporterRegistry.hpp>
24
#include <SignalLoggerManager.hpp>
25
#include <FastScheduler.hpp>
27
#define DEBUG(x) { ndbout << "CMVMI::" << x << endl; }
29
#include <signaldata/TestOrd.hpp>
30
#include <signaldata/EventReport.hpp>
31
#include <signaldata/TamperOrd.hpp>
32
#include <signaldata/StartOrd.hpp>
33
#include <signaldata/CloseComReqConf.hpp>
34
#include <signaldata/SetLogLevelOrd.hpp>
35
#include <signaldata/EventSubscribeReq.hpp>
36
#include <signaldata/DumpStateOrd.hpp>
37
#include <signaldata/DisconnectRep.hpp>
39
#include <EventLogger.hpp>
40
#include <TimeQueue.hpp>
43
#include <SafeCounter.hpp>
45
// Used here only to print event reports on stdout/console.
46
EventLogger g_eventLogger;
47
extern int simulate_error_during_shutdown;
49
Cmvmi::Cmvmi(Block_context& ctx) :
50
SimulatedBlock(CMVMI, ctx)
51
,subscribers(subscriberPool)
53
BLOCK_CONSTRUCTOR(Cmvmi);
55
Uint32 long_sig_buffer_size;
56
const ndb_mgm_configuration_iterator * p =
57
m_ctx.m_config.getOwnConfigIterator();
60
ndb_mgm_get_int_parameter(p, CFG_DB_LONG_SIGNAL_BUFFER,
61
&long_sig_buffer_size);
63
long_sig_buffer_size= long_sig_buffer_size / 256;
64
g_sectionSegmentPool.setSize(long_sig_buffer_size,
65
false,true,true,CFG_DB_LONG_SIGNAL_BUFFER);
67
// Add received signals
68
addRecSignal(GSN_CONNECT_REP, &Cmvmi::execCONNECT_REP);
69
addRecSignal(GSN_DISCONNECT_REP, &Cmvmi::execDISCONNECT_REP);
71
addRecSignal(GSN_NDB_TAMPER, &Cmvmi::execNDB_TAMPER, true);
72
addRecSignal(GSN_SET_LOGLEVELORD, &Cmvmi::execSET_LOGLEVELORD);
73
addRecSignal(GSN_EVENT_REP, &Cmvmi::execEVENT_REP);
74
addRecSignal(GSN_STTOR, &Cmvmi::execSTTOR);
75
addRecSignal(GSN_READ_CONFIG_REQ, &Cmvmi::execREAD_CONFIG_REQ);
76
addRecSignal(GSN_CLOSE_COMREQ, &Cmvmi::execCLOSE_COMREQ);
77
addRecSignal(GSN_ENABLE_COMORD, &Cmvmi::execENABLE_COMORD);
78
addRecSignal(GSN_OPEN_COMREQ, &Cmvmi::execOPEN_COMREQ);
79
addRecSignal(GSN_TEST_ORD, &Cmvmi::execTEST_ORD);
81
addRecSignal(GSN_TAMPER_ORD, &Cmvmi::execTAMPER_ORD);
82
addRecSignal(GSN_STOP_ORD, &Cmvmi::execSTOP_ORD);
83
addRecSignal(GSN_START_ORD, &Cmvmi::execSTART_ORD);
84
addRecSignal(GSN_EVENT_SUBSCRIBE_REQ,
85
&Cmvmi::execEVENT_SUBSCRIBE_REQ);
87
addRecSignal(GSN_DUMP_STATE_ORD, &Cmvmi::execDUMP_STATE_ORD);
89
addRecSignal(GSN_TESTSIG, &Cmvmi::execTESTSIG);
90
addRecSignal(GSN_NODE_START_REP, &Cmvmi::execNODE_START_REP, true);
92
subscriberPool.setSize(5);
94
const ndb_mgm_configuration_iterator * db = m_ctx.m_config.getOwnConfigIterator();
95
for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){
97
if(!ndb_mgm_get_int_parameter(db, CFG_MIN_LOGLEVEL+j, &logLevel)){
98
clogLevel.setLogLevel((LogLevel::EventCategory)j,
103
ndb_mgm_configuration_iterator * iter = m_ctx.m_config.getClusterConfigIterator();
104
for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)){
109
ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_NODE_ID, &nodeId));
110
ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_TYPE_OF_SECTION,&nodeType));
114
c_dbNodes.set(nodeId);
122
setNodeInfo(nodeId).m_type = nodeType;
125
setNodeInfo(getOwnNodeId()).m_connected = true;
126
setNodeInfo(getOwnNodeId()).m_version = ndbGetOwnVersion();
131
m_shared_page_pool.clear();
135
NodeBitmask c_error_9000_nodes_mask;
136
extern Uint32 MAX_RECEIVED_SIGNALS;
139
void Cmvmi::execNDB_TAMPER(Signal* signal)
142
SET_ERROR_INSERT_VALUE(signal->theData[0]);
143
if(ERROR_INSERTED(9999)){
144
CRASH_INSERTION(9999);
147
if(ERROR_INSERTED(9998)){
148
while(true) NdbSleep_SecSleep(1);
151
if(ERROR_INSERTED(9997)){
156
if(ERROR_INSERTED(9996)){
157
simulate_error_during_shutdown= SIGSEGV;
161
if(ERROR_INSERTED(9995)){
162
simulate_error_during_shutdown= SIGSEGV;
163
kill(getpid(), SIGABRT);
168
if (signal->theData[0] == 9003)
170
if (MAX_RECEIVED_SIGNALS < 1024)
172
MAX_RECEIVED_SIGNALS = 1024;
176
MAX_RECEIVED_SIGNALS = 1 + (rand() % 128);
178
ndbout_c("MAX_RECEIVED_SIGNALS: %d", MAX_RECEIVED_SIGNALS);
179
CLEAR_ERROR_INSERT_VALUE;
184
void Cmvmi::execSET_LOGLEVELORD(Signal* signal)
186
SetLogLevelOrd * const llOrd = (SetLogLevelOrd *)&signal->theData[0];
187
LogLevel::EventCategory category;
191
for(unsigned int i = 0; i<llOrd->noOfEntries; i++){
192
category = (LogLevel::EventCategory)(llOrd->theData[i] >> 16);
193
level = llOrd->theData[i] & 0xFFFF;
195
clogLevel.setLogLevel(category, level);
197
}//execSET_LOGLEVELORD()
199
void Cmvmi::execEVENT_REP(Signal* signal)
201
//-----------------------------------------------------------------------
202
// This message is sent to report any types of events in NDB.
203
// Based on the log level they will be either ignored or
204
// reported. Currently they are printed, but they will be
205
// transferred to the management server for further distribution
206
// to the graphical management interface.
207
//-----------------------------------------------------------------------
208
EventReport * const eventReport = (EventReport *)&signal->theData[0];
209
Ndb_logevent_type eventType = eventReport->getEventType();
210
Uint32 nodeId= eventReport->getNodeId();
213
nodeId= refToNode(signal->getSendersBlockRef());
214
eventReport->setNodeId(nodeId);
220
* If entry is not found
223
LogLevel::EventCategory eventCategory;
224
Logger::LoggerLevel severity;
225
EventLoggerBase::EventTextFunction textF;
226
if (EventLoggerBase::event_lookup(eventType,eventCategory,threshold,severity,textF))
230
for(subscribers.first(ptr); ptr.i != RNIL; subscribers.next(ptr)){
231
if(ptr.p->logLevel.getLogLevel(eventCategory) < threshold){
235
sendSignal(ptr.p->blockRef, GSN_EVENT_REP, signal, signal->length(), JBB);
238
if(clogLevel.getLogLevel(eventCategory) < threshold){
242
// Print the event info
243
g_eventLogger.log(eventReport->getEventType(), signal->theData);
249
Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){
250
EventSubscribeReq * subReq = (EventSubscribeReq *)&signal->theData[0];
251
Uint32 senderRef = signal->getSendersBlockRef();
254
DBUG_ENTER("Cmvmi::execEVENT_SUBSCRIBE_REQ");
257
* Search for subcription
259
for(subscribers.first(ptr); ptr.i != RNIL; subscribers.next(ptr)){
260
if(ptr.p->blockRef == subReq->blockRef)
268
if(subscribers.seize(ptr) == false){
269
sendSignal(senderRef, GSN_EVENT_SUBSCRIBE_REF, signal, 1, JBB);
272
ptr.p->logLevel.clear();
273
ptr.p->blockRef = subReq->blockRef;
276
if(subReq->noOfEntries == 0){
278
* Cancel subscription
280
subscribers.release(ptr.i);
283
* Update subscription
285
LogLevel::EventCategory category;
287
for(Uint32 i = 0; i<subReq->noOfEntries; i++){
288
category = (LogLevel::EventCategory)(subReq->theData[i] >> 16);
289
level = subReq->theData[i] & 0xFFFF;
290
ptr.p->logLevel.setLogLevel(category, level);
291
DBUG_PRINT("info",("entry %d: level=%d, category= %d", i, level, category));
295
signal->theData[0] = ptr.i;
296
sendSignal(senderRef, GSN_EVENT_SUBSCRIBE_CONF, signal, 1, JBB);
301
Cmvmi::cancelSubscription(NodeId nodeId){
304
subscribers.first(ptr);
306
while(ptr.i != RNIL){
308
BlockReference blockRef = ptr.p->blockRef;
310
subscribers.next(ptr);
312
if(refToNode(blockRef) == nodeId){
313
subscribers.release(i);
318
void Cmvmi::sendSTTORRY(Signal* signal)
321
signal->theData[3] = 1;
322
signal->theData[4] = 3;
323
signal->theData[5] = 8;
324
signal->theData[6] = 255;
325
sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 7, JBB);
326
}//Cmvmi::sendSTTORRY
330
Cmvmi::execREAD_CONFIG_REQ(Signal* signal)
334
const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
336
Uint32 ref = req->senderRef;
337
Uint32 senderData = req->senderData;
339
const ndb_mgm_configuration_iterator * p =
340
m_ctx.m_config.getOwnConfigIterator();
343
Uint64 page_buffer = 64*1024*1024;
344
ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY, &page_buffer);
347
pages += page_buffer / GLOBAL_PAGE_SIZE; // in pages
348
pages += LCP_RESTORE_BUFFER;
349
m_global_page_pool.setSize(pages + 64, true);
351
Uint64 shared_mem = 8*1024*1024;
352
ndb_mgm_get_int64_parameter(p, CFG_DB_SGA, &shared_mem);
353
shared_mem /= GLOBAL_PAGE_SIZE;
358
rl.m_max = shared_mem;
359
rl.m_resource_id = 0;
360
m_ctx.m_mm.set_resource_limit(rl);
363
ndbrequire(m_ctx.m_mm.init());
365
void* ptr = m_ctx.m_mm.get_memroot();
366
m_shared_page_pool.set((GlobalPage*)ptr, ~0);
369
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
370
conf->senderRef = reference();
371
conf->senderData = senderData;
372
sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
373
ReadConfigConf::SignalLength, JBB);
376
void Cmvmi::execSTTOR(Signal* signal)
378
Uint32 theStartPhase = signal->theData[1];
381
if (theStartPhase == 1){
384
if(m_ctx.m_config.lockPagesInMainMemory() == 1)
386
int res = NdbMem_MemLockAll(0);
388
g_eventLogger.warning("Failed to memlock pages");
389
warningEvent("Failed to memlock pages");
395
} else if (theStartPhase == 3) {
397
globalData.activateSendPacked = 1;
399
} else if (theStartPhase == 8){
400
/*---------------------------------------------------*/
401
/* Open com to API + REP nodes */
402
/*---------------------------------------------------*/
403
signal->theData[0] = 0; // no answer
404
signal->theData[1] = 0; // no id
405
signal->theData[2] = NodeInfo::API;
406
execOPEN_COMREQ(signal);
407
globalData.theStartLevel = NodeState::SL_STARTED;
412
void Cmvmi::execCLOSE_COMREQ(Signal* signal)
414
// Close communication with the node and halt input/output from
415
// other blocks than QMGR
417
CloseComReqConf * const closeCom = (CloseComReqConf *)&signal->theData[0];
419
const BlockReference userRef = closeCom->xxxBlockRef;
420
Uint32 failNo = closeCom->failNo;
421
// Uint32 noOfNodes = closeCom->noOfNodes;
424
for (unsigned i = 0; i < MAX_NODES; i++)
426
if(NodeBitmask::get(closeCom->theNodes, i))
430
//-----------------------------------------------------
431
// Report that the connection to the node is closed
432
//-----------------------------------------------------
433
signal->theData[0] = NDB_LE_CommunicationClosed;
434
signal->theData[1] = i;
435
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
437
globalTransporterRegistry.setIOState(i, HaltIO);
438
globalTransporterRegistry.do_disconnect(i);
445
signal->theData[0] = userRef;
446
signal->theData[1] = failNo;
447
sendSignal(QMGR_REF, GSN_CLOSE_COMCONF, signal, 19, JBA);
451
void Cmvmi::execOPEN_COMREQ(Signal* signal)
453
// Connect to the specifed NDB node, only QMGR allowed communication
454
// so far with the node
456
const BlockReference userRef = signal->theData[0];
457
Uint32 tStartingNode = signal->theData[1];
458
Uint32 tData2 = signal->theData[2];
461
const Uint32 len = signal->getLength();
465
if (! ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002))
466
&& c_error_9000_nodes_mask.get(tStartingNode)))
469
if (globalData.theStartLevel != NodeState::SL_STARTED &&
470
(getNodeInfo(tStartingNode).m_type != NodeInfo::DB &&
471
getNodeInfo(tStartingNode).m_type != NodeInfo::MGM))
477
globalTransporterRegistry.do_connect(tStartingNode);
478
globalTransporterRegistry.setIOState(tStartingNode, HaltIO);
480
//-----------------------------------------------------
481
// Report that the connection to the node is opened
482
//-----------------------------------------------------
483
signal->theData[0] = NDB_LE_CommunicationOpened;
484
signal->theData[1] = tStartingNode;
485
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
486
//-----------------------------------------------------
489
for(unsigned int i = 1; i < MAX_NODES; i++ )
492
if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2)
497
if ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002))
498
&& c_error_9000_nodes_mask.get(i))
502
globalTransporterRegistry.do_connect(i);
503
globalTransporterRegistry.setIOState(i, HaltIO);
505
signal->theData[0] = NDB_LE_CommunicationOpened;
506
signal->theData[1] = i;
507
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
515
signal->theData[0] = tStartingNode;
516
signal->theData[1] = tData2;
517
sendSignal(userRef, GSN_OPEN_COMCONF, signal, len - 1,JBA);
521
void Cmvmi::execENABLE_COMORD(Signal* signal)
523
// Enable communication with all our NDB blocks to this node
525
Uint32 tStartingNode = signal->theData[0];
526
globalTransporterRegistry.setIOState(tStartingNode, NoHalt);
527
setNodeInfo(tStartingNode).m_connected = true;
528
//-----------------------------------------------------
529
// Report that the version of the node
530
//-----------------------------------------------------
531
signal->theData[0] = NDB_LE_ConnectedApiVersion;
532
signal->theData[1] = tStartingNode;
533
signal->theData[2] = getNodeInfo(tStartingNode).m_version;
535
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
536
//-----------------------------------------------------
541
void Cmvmi::execDISCONNECT_REP(Signal *signal)
543
const DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0];
544
const Uint32 hostId = rep->nodeId;
545
const Uint32 errNo = rep->err;
549
setNodeInfo(hostId).m_connected = false;
550
setNodeInfo(hostId).m_connectCount++;
551
const NodeInfo::NodeType type = getNodeInfo(hostId).getType();
552
ndbrequire(type != NodeInfo::INVALID);
554
sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal,
555
DisconnectRep::SignalLength, JBA);
557
cancelSubscription(hostId);
559
signal->theData[0] = NDB_LE_Disconnected;
560
signal->theData[1] = hostId;
561
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
564
void Cmvmi::execCONNECT_REP(Signal *signal){
565
const Uint32 hostId = signal->theData[0];
568
const NodeInfo::NodeType type = (NodeInfo::NodeType)getNodeInfo(hostId).m_type;
569
ndbrequire(type != NodeInfo::INVALID);
570
globalData.m_nodeInfo[hostId].m_version = 0;
571
globalData.m_nodeInfo[hostId].m_signalVersion = 0;
573
if(type == NodeInfo::DB || globalData.theStartLevel >= NodeState::SL_STARTED){
577
* Inform QMGR that client has connected
580
signal->theData[0] = hostId;
581
sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
582
} else if(globalData.theStartLevel == NodeState::SL_CMVMI ||
583
globalData.theStartLevel == NodeState::SL_STARTING) {
586
* Someone connected before start was finished
588
if(type == NodeInfo::MGM){
590
signal->theData[0] = hostId;
591
sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
594
* Dont allow api nodes to connect
596
ndbout_c("%d %d %d", hostId, type, globalData.theStartLevel);
598
globalTransporterRegistry.do_disconnect(hostId);
602
/* Automatically subscribe events for MGM nodes.
604
if(type == NodeInfo::MGM){
606
globalTransporterRegistry.setIOState(hostId, NoHalt);
609
//------------------------------------------
610
// Also report this event to the Event handler
611
//------------------------------------------
612
signal->theData[0] = NDB_LE_Connected;
613
signal->theData[1] = hostId;
614
signal->header.theLength = 2;
616
execEVENT_REP(signal);
621
modifySignalLogger(bool allBlocks, BlockNumber bno,
622
TestOrd::Command cmd,
623
TestOrd::SignalLoggerSpecification spec){
624
SignalLoggerManager::LogMode logMode;
627
* Mapping between SignalLoggerManager::LogMode and
628
* TestOrd::SignalLoggerSpecification
631
case TestOrd::InputSignals:
632
logMode = SignalLoggerManager::LogIn;
634
case TestOrd::OutputSignals:
635
logMode = SignalLoggerManager::LogOut;
637
case TestOrd::InputOutputSignals:
638
logMode = SignalLoggerManager::LogInOut;
647
globalSignalLoggers.logOn(allBlocks, bno, logMode);
650
globalSignalLoggers.logOff(allBlocks, bno, logMode);
652
case TestOrd::Toggle:
653
globalSignalLoggers.logToggle(allBlocks, bno, logMode);
655
case TestOrd::KeepUnchanged:
659
globalSignalLoggers.flushSignalLog();
664
Cmvmi::execTEST_ORD(Signal * signal){
668
TestOrd * const testOrd = (TestOrd *)&signal->theData[0];
670
TestOrd::Command cmd;
674
* Process Trace command
676
TestOrd::TraceSpecification traceSpec;
678
testOrd->getTraceCommand(cmd, traceSpec);
679
unsigned long traceVal = traceSpec;
680
unsigned long currentTraceVal = globalSignalLoggers.getTrace();
683
currentTraceVal |= traceVal;
686
currentTraceVal &= (~traceVal);
688
case TestOrd::Toggle:
689
currentTraceVal ^= traceVal;
691
case TestOrd::KeepUnchanged:
695
globalSignalLoggers.setTrace(currentTraceVal);
700
* Process Log command
702
TestOrd::SignalLoggerSpecification logSpec;
704
unsigned int loggers = testOrd->getNoOfSignalLoggerCommands();
706
if(loggers == (unsigned)~0){ // Apply command to all blocks
707
testOrd->getSignalLoggerCommand(0, bno, cmd, logSpec);
708
modifySignalLogger(true, bno, cmd, logSpec);
710
for(unsigned int i = 0; i<loggers; i++){
711
testOrd->getSignalLoggerCommand(i, bno, cmd, logSpec);
712
modifySignalLogger(false, bno, cmd, logSpec);
719
* Process test command
721
testOrd->getTestCommand(cmd);
731
case TestOrd::Toggle:{
732
TOGGLE_GLOBAL_TEST_FLAG;
735
case TestOrd::KeepUnchanged:
739
globalSignalLoggers.flushSignalLog();
745
void Cmvmi::execSTOP_ORD(Signal* signal)
748
globalData.theRestartFlag = perform_stop;
752
Cmvmi::execSTART_ORD(Signal* signal) {
754
StartOrd * const startOrd = (StartOrd *)&signal->theData[0];
757
Uint32 tmp = startOrd->restartInfo;
758
if(StopReq::getPerformRestart(tmp)){
763
NdbRestartType type = NRT_Default;
764
if(StopReq::getNoStart(tmp) && StopReq::getInitialStart(tmp))
765
type = NRT_NoStart_InitialStart;
766
if(StopReq::getNoStart(tmp) && !StopReq::getInitialStart(tmp))
767
type = NRT_NoStart_Restart;
768
if(!StopReq::getNoStart(tmp) && StopReq::getInitialStart(tmp))
769
type = NRT_DoStart_InitialStart;
770
if(!StopReq::getNoStart(tmp)&&!StopReq::getInitialStart(tmp))
771
type = NRT_DoStart_Restart;
772
NdbShutdown(NST_Restart, type);
775
if(globalData.theRestartFlag == system_started){
778
* START_ORD received when already started(ignored)
780
//ndbout << "START_ORD received when already started(ignored)" << endl;
784
if(globalData.theRestartFlag == perform_stop){
787
* START_ORD received when stopping(ignored)
789
//ndbout << "START_ORD received when stopping(ignored)" << endl;
793
if(globalData.theStartLevel == NodeState::SL_NOTHING){
795
globalData.theStartLevel = NodeState::SL_CMVMI;
797
* Open connections to management servers
799
for(unsigned int i = 1; i < MAX_NODES; i++ ){
800
if (getNodeInfo(i).m_type == NodeInfo::MGM){
801
if(!globalTransporterRegistry.is_connected(i)){
802
globalTransporterRegistry.do_connect(i);
803
globalTransporterRegistry.setIOState(i, NoHalt);
808
EXECUTE_DIRECT(QMGR, GSN_START_ORD, signal, 1);
812
if(globalData.theStartLevel == NodeState::SL_CMVMI){
815
if(m_ctx.m_config.lockPagesInMainMemory() == 2)
817
int res = NdbMem_MemLockAll(1);
820
g_eventLogger.warning("Failed to memlock pages");
821
warningEvent("Failed to memlock pages");
825
g_eventLogger.info("Locked future allocations");
829
globalData.theStartLevel = NodeState::SL_STARTING;
830
globalData.theRestartFlag = system_started;
837
// Disconnect all nodes as part of the system restart.
838
// We need to ensure that we are starting up
839
// without any connected nodes.
840
for(unsigned int i = 1; i < MAX_NODES; i++ ){
841
if (i != getOwnNodeId() && getNodeInfo(i).m_type != NodeInfo::MGM){
842
globalTransporterRegistry.do_disconnect(i);
843
globalTransporterRegistry.setIOState(i, HaltIO);
848
* Start running startphases
850
sendSignal(NDBCNTR_REF, GSN_START_ORD, signal, 1, JBA);
855
void Cmvmi::execTAMPER_ORD(Signal* signal)
858
// TODO We should maybe introduce a CONF and REF signal
859
// to be able to indicate if we really introduced an error.
861
TamperOrd* const tamperOrd = (TamperOrd*)&signal->theData[0];
862
signal->theData[2] = 0;
863
signal->theData[1] = tamperOrd->errorNo;
864
signal->theData[0] = 5;
865
sendSignal(DBDIH_REF, GSN_DIHNDBTAMPER, signal, 3,JBB);
871
class RefSignalTest {
888
recurse(char * buf, int loops, int arg){
889
char * tmp = (char*)alloca(arg);
890
printf("tmp = %p\n", tmp);
891
for(iii = 0; iii<arg; iii += 1024){
892
tmp[iii] = (iii % 23 + (arg & iii));
898
return tmp[arg/loops] + recurse(tmp, loops - 1, arg);
902
Cmvmi::execDUMP_STATE_ORD(Signal* signal)
905
sendSignal(QMGR_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
906
sendSignal(NDBCNTR_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
907
sendSignal(DBTC_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
908
sendSignal(DBDIH_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
909
sendSignal(DBDICT_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
910
sendSignal(DBLQH_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
911
sendSignal(DBTUP_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
912
sendSignal(DBACC_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
913
sendSignal(NDBFS_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
914
sendSignal(BACKUP_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
915
sendSignal(DBUTIL_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
916
sendSignal(SUMA_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
917
sendSignal(TRIX_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
918
sendSignal(DBTUX_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
919
sendSignal(LGMAN_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
920
sendSignal(TSMAN_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
921
sendSignal(PGMAN_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
925
* Here I can dump CMVMI state if needed
927
if(signal->theData[0] == 13){
930
int len = (10*1024*1024);
931
if(signal->getLength() > 1)
932
loop = signal->theData[1];
933
if(signal->getLength() > 2)
934
len = signal->theData[2];
936
ndbout_c("recurse(%d loop, %dkb per recurse)", loop, len/1024);
937
int a = recurse(0, loop, len);
938
ndbout_c("after...%d", a);
942
DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
943
Uint32 arg = dumpState->args[0];
944
if (arg == DumpStateOrd::CmvmiDumpConnections){
945
for(unsigned int i = 1; i < MAX_NODES; i++ ){
946
const char* nodeTypeStr = "";
947
switch(getNodeInfo(i).m_type){
957
case NodeInfo::INVALID:
961
nodeTypeStr = "<UNKNOWN>";
967
infoEvent("Connection to %d (%s) %s",
970
globalTransporterRegistry.getPerformStateString(i));
974
if (arg == DumpStateOrd::CmvmiDumpSubscriptions)
977
subscribers.first(ptr);
978
g_eventLogger.info("List subscriptions:");
981
g_eventLogger.info("Subscription: %u, nodeId: %u, ref: 0x%x",
982
ptr.i, refToNode(ptr.p->blockRef), ptr.p->blockRef);
983
for(Uint32 i = 0; i < LogLevel::LOGLEVEL_CATEGORIES; i++)
985
Uint32 level = ptr.p->logLevel.getLogLevel((LogLevel::EventCategory)i);
986
g_eventLogger.info("Category %u Level %u", i, level);
988
subscribers.next(ptr);
992
if (arg == DumpStateOrd::CmvmiDumpLongSignalMemory){
993
infoEvent("Cmvmi: g_sectionSegmentPool size: %d free: %d",
994
g_sectionSegmentPool.getSize(),
995
g_sectionSegmentPool.getNoOfFree());
998
if (dumpState->args[0] == 1000)
1000
Uint32 len = signal->getLength();
1001
if (signal->getLength() == 1)
1003
signal->theData[1] = 0;
1004
signal->theData[2] = ~0;
1005
sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 3, JBB);
1008
Uint32 id = signal->theData[1];
1010
if (!m_ctx.m_mm.get_resource_limit(id, rl))
1014
if (rl.m_min || rl.m_curr || rl.m_max)
1015
infoEvent("Resource %d min: %d max: %d curr: %d",
1016
id, rl.m_min, rl.m_max, rl.m_curr);
1021
signal->theData[0] = 1000;
1022
signal->theData[1] = id+1;
1023
signal->theData[2] = ~0;
1024
sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 3, JBB);
1029
if (arg == DumpStateOrd::CmvmiSetRestartOnErrorInsert)
1031
if(signal->getLength() == 1)
1033
Uint32 val = (Uint32)NRT_NoStart_Restart;
1034
const ndb_mgm_configuration_iterator * p =
1035
m_ctx.m_config.getOwnConfigIterator();
1038
if(!ndb_mgm_get_int_parameter(p, CFG_DB_STOP_ON_ERROR_INSERT, &val))
1040
m_ctx.m_config.setRestartOnErrorInsert(val);
1045
m_ctx.m_config.setRestartOnErrorInsert(signal->theData[1]);
1049
if (arg == DumpStateOrd::CmvmiTestLongSigWithDelay) {
1051
Uint32 loopCount = dumpState->args[1];
1052
const unsigned len0 = 11;
1053
const unsigned len1 = 123;
1056
for (i = 0; i < len0; i++)
1058
for (i = 0; i < len1; i++)
1060
Uint32* sig = signal->getDataPtrSend();
1061
sig[0] = reference();
1062
sig[1] = 20; // test type
1069
LinearSectionPtr ptr[3];
1074
sendSignal(reference(), GSN_TESTSIG, signal, 8, JBB, ptr, 2);
1078
if (arg == 9000 || arg == 9002)
1080
SET_ERROR_INSERT_VALUE(arg);
1081
for (Uint32 i = 1; i<signal->getLength(); i++)
1082
c_error_9000_nodes_mask.set(signal->theData[i]);
1087
CLEAR_ERROR_INSERT_VALUE;
1088
if (signal->getLength() == 1 || signal->theData[1])
1090
for (Uint32 i = 0; i<MAX_NODES; i++)
1092
if (c_error_9000_nodes_mask.get(i))
1094
signal->theData[0] = 0;
1095
signal->theData[1] = i;
1096
EXECUTE_DIRECT(CMVMI, GSN_OPEN_COMREQ, signal, 2);
1100
c_error_9000_nodes_mask.clear();
1107
SafeCounterManager mgr(* this); mgr.setSize(1);
1108
SafeCounterHandle handle;
1111
SafeCounter tmp(mgr, handle);
1112
tmp.init<RefSignalTest>(CMVMI, GSN_TESTSIG, /* senderData */ 13);
1113
tmp.setWaitingFor(3);
1114
ndbrequire(!tmp.done());
1115
ndbout_c("Allocted");
1117
ndbrequire(!handle.done());
1119
SafeCounter tmp(mgr, handle);
1120
tmp.clearWaitingFor(3);
1121
ndbrequire(tmp.done());
1122
ndbout_c("Deallocted");
1124
ndbrequire(handle.done());
1131
Uint32 delay = 1000;
1132
switch(signal->getLength()){
1136
delay = signal->theData[1];
1139
Uint32 dmin = signal->theData[1];
1140
Uint32 dmax = signal->theData[2];
1141
delay = dmin + (rand() % (dmax - dmin));
1146
signal->theData[0] = 9999;
1149
execNDB_TAMPER(signal);
1151
else if (delay < 10)
1153
sendSignal(reference(), GSN_NDB_TAMPER, signal, 1, JBB);
1157
sendSignalWithDelay(reference(), GSN_NDB_TAMPER, signal, delay, 1);
1160
}//Cmvmi::execDUMP_STATE_ORD()
1163
Cmvmi::execNODE_START_REP(Signal* signal)
1166
if (ERROR_INSERTED(9002) && signal->theData[0] == getOwnNodeId())
1168
signal->theData[0] = 9001;
1169
execDUMP_STATE_ORD(signal);
1174
BLOCK_FUNCTIONS(Cmvmi)
1176
static Uint32 g_print;
1177
static LinearSectionPtr g_test[3];
1180
Cmvmi::execTESTSIG(Signal* signal){
1183
* Test of SafeCounter
1187
if(!assembleFragments(signal)){
1192
Uint32 ref = signal->theData[0];
1193
Uint32 testType = signal->theData[1];
1194
Uint32 fragmentLength = signal->theData[2];
1195
g_print = signal->theData[3];
1196
// Uint32 returnCount = signal->theData[4];
1197
Uint32 * secSizes = &signal->theData[5];
1200
SignalLoggerManager::printSignalHeader(stdout,
1205
ndbout_c("-- Fixed section --");
1206
for(i = 0; i<signal->length(); i++){
1207
fprintf(stdout, "H'0x%.8x ", signal->theData[i]);
1208
if(((i + 1) % 6) == 0)
1209
fprintf(stdout, "\n");
1211
fprintf(stdout, "\n");
1213
for(i = 0; i<signal->header.m_noOfSections; i++){
1214
SegmentedSectionPtr ptr(0,0,0);
1215
ndbout_c("-- Section %d --", i);
1216
signal->getSection(ptr, i);
1217
ndbrequire(ptr.p != 0);
1219
ndbrequire(ptr.sz == secSizes[i]);
1226
for(i = 0; i<signal->header.m_noOfSections; i++){
1227
SegmentedSectionPtr ptr;
1228
signal->getSection(ptr, i);
1229
ndbrequire(ptr.p != 0);
1230
ndbrequire(ptr.sz == secSizes[i]);
1234
* Testing send with delay.
1236
if (testType == 20) {
1237
if (signal->theData[4] == 0) {
1238
releaseSections(signal);
1241
signal->theData[4]--;
1242
sendSignalWithDelay(reference(), GSN_TESTSIG, signal, 100, 8);
1246
NodeReceiverGroup rg(CMVMI, c_dbNodes);
1248
if(signal->getSendersBlockRef() == ref){
1250
* Signal from API (not via NodeReceiverGroup)
1252
if((testType % 2) == 1){
1253
signal->theData[4] = 1;
1255
signal->theData[1] --;
1256
signal->theData[4] = rg.m_nodes.count();
1262
sendSignal(ref, GSN_TESTSIG, signal, signal->length(), JBB);
1265
sendSignal(rg, GSN_TESTSIG, signal, signal->length(), JBB);
1269
LinearSectionPtr ptr[3];
1270
const Uint32 secs = signal->getNoOfSections();
1271
for(i = 0; i<secs; i++){
1272
SegmentedSectionPtr sptr(0,0,0);
1273
signal->getSection(sptr, i);
1274
ptr[i].sz = sptr.sz;
1275
ptr[i].p = new Uint32[sptr.sz];
1276
copy(ptr[i].p, sptr);
1280
sendSignal(ref, GSN_TESTSIG, signal, signal->length(), JBB, ptr, secs);
1282
sendSignal(rg, GSN_TESTSIG, signal, signal->length(), JBB, ptr, secs);
1284
for(Uint32 i = 0; i<secs; i++){
1292
NodeReceiverGroup tmp;
1299
FragmentSendInfo fragSend;
1300
sendFirstFragment(fragSend,
1308
while(fragSend.m_status != FragmentSendInfo::SendComplete){
1311
ndbout_c("Sending fragment %d", count);
1312
sendNextSegmentedFragment(signal, fragSend);
1318
LinearSectionPtr ptr[3];
1319
const Uint32 secs = signal->getNoOfSections();
1320
for(i = 0; i<secs; i++){
1321
SegmentedSectionPtr sptr(0,0,0);
1322
signal->getSection(sptr, i);
1323
ptr[i].sz = sptr.sz;
1324
ptr[i].p = new Uint32[sptr.sz];
1325
copy(ptr[i].p, sptr);
1328
NodeReceiverGroup tmp;
1335
FragmentSendInfo fragSend;
1336
sendFirstFragment(fragSend,
1347
while(fragSend.m_status != FragmentSendInfo::SendComplete){
1350
ndbout_c("Sending fragment %d", count);
1351
sendNextLinearFragment(signal, fragSend);
1354
for(i = 0; i<secs; i++){
1362
Callback m_callBack;
1363
m_callBack.m_callbackFunction =
1364
safe_cast(&Cmvmi::sendFragmentedComplete);
1367
m_callBack.m_callbackData = 9;
1368
sendFragmentedSignal(ref,
1369
GSN_TESTSIG, signal, signal->length(), JBB,
1373
m_callBack.m_callbackData = 10;
1374
sendFragmentedSignal(rg,
1375
GSN_TESTSIG, signal, signal->length(), JBB,
1384
const Uint32 secs = signal->getNoOfSections();
1385
memset(g_test, 0, sizeof(g_test));
1386
for(i = 0; i<secs; i++){
1387
SegmentedSectionPtr sptr(0,0,0);
1388
signal->getSection(sptr, i);
1389
g_test[i].sz = sptr.sz;
1390
g_test[i].p = new Uint32[sptr.sz];
1391
copy(g_test[i].p, sptr);
1395
Callback m_callBack;
1396
m_callBack.m_callbackFunction =
1397
safe_cast(&Cmvmi::sendFragmentedComplete);
1400
m_callBack.m_callbackData = 11;
1401
sendFragmentedSignal(ref,
1402
GSN_TESTSIG, signal, signal->length(), JBB,
1407
m_callBack.m_callbackData = 12;
1408
sendFragmentedSignal(rg,
1409
GSN_TESTSIG, signal, signal->length(), JBB,
1417
ndbrequire(signal->getNoOfSections() == 0);
1418
Uint32 loop = signal->theData[9];
1420
signal->theData[9] --;
1421
sendSignal(CMVMI_REF, GSN_TESTSIG, signal, signal->length(), JBB);
1424
sendSignal(ref, GSN_TESTSIG, signal, signal->length(), JBB);
1428
Uint32 count = signal->theData[8];
1429
signal->theData[10] = count * rg.m_nodes.count();
1430
for(i = 0; i<count; i++){
1431
sendSignal(rg, GSN_TESTSIG, signal, signal->length(), JBB);
1443
Cmvmi::sendFragmentedComplete(Signal* signal, Uint32 data, Uint32 returnCode){
1445
ndbout_c("sendFragmentedComplete: %d", data);
1446
if(data == 11 || data == 12){
1447
for(Uint32 i = 0; i<3; i++){
1448
if(g_test[i].p != 0)
1449
delete[] g_test[i].p;