1 /*
2 Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #define NDBCNTR_C
26 #include "Ndbcntr.hpp"
27
28 #include <ndb_limits.h>
29 #include <ndb_version.h>
30 #include <SimpleProperties.hpp>
31 #include <signaldata/DictTabInfo.hpp>
32 #include <signaldata/SchemaTrans.hpp>
33 #include <signaldata/CreateTable.hpp>
34 #include <signaldata/CreateHashMap.hpp>
35 #include <signaldata/ReadNodesConf.hpp>
36 #include <signaldata/NodeFailRep.hpp>
37 #include <signaldata/TcKeyReq.hpp>
38 #include <signaldata/TcKeyConf.hpp>
39 #include <signaldata/EventReport.hpp>
40 #include <signaldata/NodeStateSignalData.hpp>
41 #include <signaldata/StopPerm.hpp>
42 #include <signaldata/StopMe.hpp>
43 #include <signaldata/WaitGCP.hpp>
44 #include <signaldata/CheckNodeGroups.hpp>
45 #include <signaldata/StartOrd.hpp>
46 #include <signaldata/AbortAll.hpp>
47 #include <signaldata/SystemError.hpp>
48 #include <signaldata/NdbSttor.hpp>
49 #include <signaldata/CntrStart.hpp>
50 #include <signaldata/DumpStateOrd.hpp>
51
52 #include <signaldata/FsRemoveReq.hpp>
53 #include <signaldata/ReadConfig.hpp>
54
55 #include <signaldata/FailRep.hpp>
56
57 #include <AttributeHeader.hpp>
58 #include <Configuration.hpp>
59 #include <DebuggerNames.hpp>
60 #include <signaldata/DihRestart.hpp>
61
62 #include <NdbOut.hpp>
63 #include <NdbTick.h>
64
65 #include <signaldata/TakeOver.hpp>
66 #include <signaldata/CreateNodegroupImpl.hpp>
67 #include <signaldata/DropNodegroupImpl.hpp>
68 #include <signaldata/CreateFilegroup.hpp>
69
70 #include <EventLogger.hpp>
71
72 extern EventLogger * g_eventLogger;
73
74 // used during shutdown for reporting current startphase
75 // accessed from Emulator.cpp, NdbShutdown()
76 Uint32 g_currentStartPhase;
77
78 /**
79 * ALL_BLOCKS Used during start phases and while changing node state
80 *
81 * NDBFS_REF Has to be before NDBCNTR_REF (due to "ndb -i" stuff)
82 */
83 struct BlockInfo {
84 BlockReference Ref; // BlockReference
85 Uint32 NextSP; // Next start phase
86 Uint32 ErrorInsertStart;
87 Uint32 ErrorInsertStop;
88 };
89
90 static BlockInfo ALL_BLOCKS[] = {
91 { NDBFS_REF, 0 , 2000, 2999 },
92 { DBTC_REF, 1 , 8000, 8035 },
93 { DBDIH_REF, 1 , 7000, 7173 },
94 { DBLQH_REF, 1 , 5000, 5030 },
95 { DBACC_REF, 1 , 3000, 3999 },
96 { DBTUP_REF, 1 , 4000, 4007 },
97 { DBDICT_REF, 1 , 6000, 6003 },
98 { NDBCNTR_REF, 0 , 1000, 1999 },
99 { CMVMI_REF, 1 , 9000, 9999 }, // before QMGR
100 { QMGR_REF, 1 , 1, 999 },
101 { TRIX_REF, 1 , 0, 0 },
102 { BACKUP_REF, 1 , 10000, 10999 },
103 { DBUTIL_REF, 1 , 11000, 11999 },
104 { SUMA_REF, 1 , 13000, 13999 },
105 { DBTUX_REF, 1 , 12000, 12999 }
106 ,{ TSMAN_REF, 1 , 0, 0 }
107 ,{ LGMAN_REF, 1 , 0, 0 }
108 ,{ PGMAN_REF, 1 , 0, 0 }
109 ,{ RESTORE_REF,1 , 0, 0 }
110 ,{ DBINFO_REF,1 , 0, 0 }
111 ,{ DBSPJ_REF,1 , 0, 0 }
112 };
113
114 static const Uint32 ALL_BLOCKS_SZ = sizeof(ALL_BLOCKS)/sizeof(BlockInfo);
115
116 static BlockReference readConfigOrder[ALL_BLOCKS_SZ] = {
117 CMVMI_REF,
118 NDBFS_REF,
119 DBINFO_REF,
120 DBTUP_REF,
121 DBACC_REF,
122 DBTC_REF,
123 DBLQH_REF,
124 DBTUX_REF,
125 DBDICT_REF,
126 DBDIH_REF,
127 NDBCNTR_REF,
128 QMGR_REF,
129 TRIX_REF,
130 BACKUP_REF,
131 DBUTIL_REF,
132 SUMA_REF,
133 TSMAN_REF,
134 LGMAN_REF,
135 PGMAN_REF,
136 RESTORE_REF,
137 DBSPJ_REF
138 };
139
140 /*******************************/
141 /* CONTINUEB */
142 /*******************************/
execCONTINUEB(Signal * signal)143 void Ndbcntr::execCONTINUEB(Signal* signal)
144 {
145 jamEntry();
146 UintR Ttemp1 = signal->theData[0];
147 switch (Ttemp1) {
148 case ZSTARTUP:{
149 if(getNodeState().startLevel == NodeState::SL_STARTED){
150 jam();
151 return;
152 }
153
154 if(cmasterNodeId == getOwnNodeId() && c_start.m_starting.isclear()){
155 jam();
156 trySystemRestart(signal);
157 // Fall-through
158 }
159
160 Uint64 now = NdbTick_CurrentMillisecond();
161 if(now > c_start.m_startFailureTimeout)
162 {
163 jam();
164 Uint32 to_3= 0;
165 const ndb_mgm_configuration_iterator * p =
166 m_ctx.m_config.getOwnConfigIterator();
167 ndb_mgm_get_int_parameter(p, CFG_DB_START_FAILURE_TIMEOUT, &to_3);
168 BaseString tmp;
169 tmp.append("Shutting down node as total restart time exceeds "
170 " StartFailureTimeout as set in config file ");
171 if(to_3 == 0)
172 tmp.append(" 0 (inifinite)");
173 else
174 tmp.appfmt(" %d", to_3);
175
176 progError(__LINE__, NDBD_EXIT_RESTART_TIMEOUT, tmp.c_str());
177 }
178
179 signal->theData[0] = ZSTARTUP;
180 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 1);
181 break;
182 }
183 case ZSHUTDOWN:
184 jam();
185 c_stopRec.checkTimeout(signal);
186 break;
187 case ZBLOCK_STTOR:
188 if (ERROR_INSERTED(1002))
189 {
190 signal->theData[0] = ZBLOCK_STTOR;
191 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
192 return;
193 }
194 else
195 {
196 c_missra.sendNextSTTOR(signal);
197 }
198 return;
199 default:
200 jam();
201 systemErrorLab(signal, __LINE__);
202 return;
203 break;
204 }//switch
205 }//Ndbcntr::execCONTINUEB()
206
207 void
execAPI_START_REP(Signal * signal)208 Ndbcntr::execAPI_START_REP(Signal* signal)
209 {
210 if(refToBlock(signal->getSendersBlockRef()) == QMGR)
211 {
212 for(Uint32 i = 0; i<ALL_BLOCKS_SZ; i++){
213 sendSignal(ALL_BLOCKS[i].Ref, GSN_API_START_REP, signal, 1, JBB);
214 }
215 }
216 }
217 /*******************************/
218 /* SYSTEM_ERROR */
219 /*******************************/
execSYSTEM_ERROR(Signal * signal)220 void Ndbcntr::execSYSTEM_ERROR(Signal* signal)
221 {
222 const SystemError * const sysErr = (SystemError *)signal->getDataPtr();
223 char buf[100];
224 int killingNode = refToNode(sysErr->errorRef);
225 Uint32 data1 = sysErr->data[0];
226
227 jamEntry();
228 switch (sysErr->errorCode){
229 case SystemError::GCPStopDetected:
230 {
231 BaseString::snprintf(buf, sizeof(buf),
232 "Node %d killed this node because "
233 "GCP stop was detected",
234 killingNode);
235 signal->theData[0] = 7025;
236 EXECUTE_DIRECT(DBDIH, GSN_DUMP_STATE_ORD, signal, 1);
237 jamEntry();
238
239 {
240 signal->theData[0] = 12002;
241 EXECUTE_DIRECT(LGMAN, GSN_DUMP_STATE_ORD, signal, 1, 0);
242 }
243
244 jamEntry();
245 break;
246 }
247 case SystemError::CopyFragRefError:
248 CRASH_INSERTION(1000);
249 BaseString::snprintf(buf, sizeof(buf),
250 "Killed by node %d as "
251 "copyfrag failed, error: %u",
252 killingNode, data1);
253 break;
254
255 case SystemError::StartFragRefError:
256 BaseString::snprintf(buf, sizeof(buf),
257 "Node %d killed this node because "
258 "it replied StartFragRef error code: %u.",
259 killingNode, data1);
260 break;
261
262 case SystemError::CopySubscriptionRef:
263 BaseString::snprintf(buf, sizeof(buf),
264 "Node %d killed this node because "
265 "it could not copy a subscription during node restart. "
266 "Copy subscription error code: %u.",
267 killingNode, data1);
268 break;
269 case SystemError::CopySubscriberRef:
270 BaseString::snprintf(buf, sizeof(buf),
271 "Node %d killed this node because "
272 "it could not start a subscriber during node restart. "
273 "Copy subscription error code: %u.",
274 killingNode, data1);
275 break;
276 default:
277 BaseString::snprintf(buf, sizeof(buf), "System error %d, "
278 " this node was killed by node %d",
279 sysErr->errorCode, killingNode);
280 break;
281 }
282
283 progError(__LINE__, NDBD_EXIT_SYSTEM_ERROR, buf);
284 return;
285 }//Ndbcntr::execSYSTEM_ERROR()
286
287
288 struct ddentry
289 {
290 Uint32 type;
291 const char * name;
292 Uint64 size;
293 };
294
295 /**
296 * f_dd[] = {
297 * { DictTabInfo::LogfileGroup, "DEFAULT-LG", 32*1024*1024 },
298 * { DictTabInfo::Undofile, "undofile.dat", 64*1024*1024 },
299 * { DictTabInfo::Tablespace, "DEFAULT-TS", 1024*1024 },
300 * { DictTabInfo::Datafile, "datafile.dat", 64*1024*1024 },
301 * { ~0, 0, 0 }
302 * };
303 */
304 Vector<ddentry> f_dd;
305
306 Uint64
parse_size(const char * src)307 parse_size(const char * src)
308 {
309 Uint64 num = 0;
310 char * endptr = 0;
311 num = strtoll(src, &endptr, 10);
312
313 if (endptr)
314 {
315 switch(* endptr){
316 case 'k':
317 case 'K':
318 num *= 1024;
319 break;
320 case 'm':
321 case 'M':
322 num *= 1024;
323 num *= 1024;
324 break;
325 case 'g':
326 case 'G':
327 num *= 1024;
328 num *= 1024;
329 num *= 1024;
330 break;
331 }
332 }
333 return num;
334 }
335
336 static
337 int
parse_spec(Vector<ddentry> & dst,const char * src,Uint32 type)338 parse_spec(Vector<ddentry> & dst,
339 const char * src,
340 Uint32 type)
341 {
342 const char * key;
343 Uint32 filetype;
344
345 struct ddentry group;
346 if (type == DictTabInfo::LogfileGroup)
347 {
348 key = "undo_buffer_size=";
349 group.size = 64*1024*1024;
350 group.name = "DEFAULT-LG";
351 group.type = type;
352 filetype = DictTabInfo::Undofile;
353 }
354 else
355 {
356 key = "extent_size=";
357 group.size = 1024*1024;
358 group.name = "DEFAULT-TS";
359 group.type = type;
360 filetype = DictTabInfo::Datafile;
361 }
362 size_t keylen = strlen(key);
363
364 BaseString arg(src);
365 Vector<BaseString> list;
366 arg.split(list, ";");
367
368 bool first = true;
369 for (Uint32 i = 0; i<list.size(); i++)
370 {
371 list[i].trim();
372 if (strncasecmp(list[i].c_str(), "name=", sizeof("name=")-1) == 0)
373 {
374 group.name= strdup(list[i].c_str() + sizeof("name=")-1);
375 }
376 else if (strncasecmp(list[i].c_str(), key, keylen) == 0)
377 {
378 group.size = parse_size(list[i].c_str() + keylen);
379 }
380 else if (strlen(list[i].c_str()) == 0 && (i + 1) == list.size())
381 {
382 /**
383 * ignore stray ";"
384 */
385 }
386 else
387 {
388 /**
389 * interpret as filespec
390 */
391 struct ddentry entry;
392 const char * path = list[i].c_str();
393 char * sizeptr = const_cast<char*>(strchr(path, ':'));
394 if (sizeptr == 0)
395 {
396 return -1;
397 }
398 * sizeptr = 0;
399
400 entry.name = strdup(path);
401 entry.size = parse_size(sizeptr + 1);
402 entry.type = filetype;
403
404 if (first)
405 {
406 /**
407 * push group aswell
408 */
409 first = false;
410 dst.push_back(group);
411 }
412 dst.push_back(entry);
413 }
414 }
415 return 0;
416 }
417
418 void
execREAD_CONFIG_REQ(Signal * signal)419 Ndbcntr::execREAD_CONFIG_REQ(Signal* signal)
420 {
421 jamEntry();
422
423 const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
424
425 Uint32 ref = req->senderRef;
426 Uint32 senderData = req->senderData;
427
428 const ndb_mgm_configuration_iterator * p =
429 m_ctx.m_config.getOwnConfigIterator();
430 ndbrequire(p != 0);
431
432 Uint32 dl = 0;
433 ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl);
434 if (dl == 0)
435 {
436 const char * lgspec = 0;
437 char buf[1024];
438 if (!ndb_mgm_get_string_parameter(p, CFG_DB_DD_LOGFILEGROUP_SPEC, &lgspec))
439 {
440 jam();
441
442 if (parse_spec(f_dd, lgspec, DictTabInfo::LogfileGroup))
443 {
444 BaseString::snprintf(buf, sizeof(buf),
445 "Unable to parse InitialLogfileGroup: %s", lgspec);
446 progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
447 }
448 }
449
450 const char * tsspec = 0;
451 if (!ndb_mgm_get_string_parameter(p, CFG_DB_DD_TABLEPACE_SPEC, &tsspec))
452 {
453 if (f_dd.size() == 0)
454 {
455 warningEvent("InitialTablespace specified, "
456 "but InitialLogfileGroup is not!");
457 warningEvent("Ignoring InitialTablespace: %s",
458 tsspec);
459 }
460 else
461 {
462 if (parse_spec(f_dd, tsspec, DictTabInfo::Tablespace))
463 {
464 BaseString::snprintf(buf, sizeof(buf),
465 "Unable to parse InitialTablespace: %s", tsspec);
466 progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
467 }
468 }
469 }
470 }
471
472 struct ddentry empty;
473 empty.type = ~0;
474 f_dd.push_back(empty);
475
476 if (true)
477 {
478 // TODO: add config parameter
479 // remove ATTRIBUTE_MASK2
480 g_sysTable_NDBEVENTS_0.columnCount--;
481 }
482
483 ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
484 conf->senderRef = reference();
485 conf->senderData = senderData;
486 sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
487 ReadConfigConf::SignalLength, JBB);
488 }
489
execSTTOR(Signal * signal)490 void Ndbcntr::execSTTOR(Signal* signal)
491 {
492 jamEntry();
493 cstartPhase = signal->theData[1];
494
495 cndbBlocksCount = 0;
496 cinternalStartphase = cstartPhase - 1;
497
498 switch (cstartPhase) {
499 case 0:
500 if(m_ctx.m_config.getInitialStart()){
501 jam();
502 c_fsRemoveCount = 0;
503 clearFilesystem(signal);
504 return;
505 }
506 sendSttorry(signal);
507 break;
508 case ZSTART_PHASE_1:
509 jam();
510 startPhase1Lab(signal);
511 break;
512 case ZSTART_PHASE_2:
513 jam();
514 startPhase2Lab(signal);
515 break;
516 case ZSTART_PHASE_3:
517 jam();
518 startPhase3Lab(signal);
519 break;
520 case ZSTART_PHASE_4:
521 jam();
522 startPhase4Lab(signal);
523 break;
524 case ZSTART_PHASE_5:
525 jam();
526 startPhase5Lab(signal);
527 break;
528 case 6:
529 jam();
530 getNodeGroup(signal);
531 sendSttorry(signal);
532 break;
533 case ZSTART_PHASE_8:
534 jam();
535 startPhase8Lab(signal);
536 break;
537 case ZSTART_PHASE_9:
538 jam();
539 startPhase9Lab(signal);
540 break;
541 default:
542 jam();
543 sendSttorry(signal);
544 break;
545 }//switch
546 }//Ndbcntr::execSTTOR()
547
548 void
getNodeGroup(Signal * signal)549 Ndbcntr::getNodeGroup(Signal* signal){
550 jam();
551 CheckNodeGroups * sd = (CheckNodeGroups*)signal->getDataPtrSend();
552 sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::GetNodeGroup;
553 EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
554 CheckNodeGroups::SignalLength);
555 jamEntry();
556 c_nodeGroup = sd->output;
557 }
558
559 /*******************************/
560 /* NDB_STTORRY */
561 /*******************************/
execNDB_STTORRY(Signal * signal)562 void Ndbcntr::execNDB_STTORRY(Signal* signal)
563 {
564 jamEntry();
565 switch (cstartPhase) {
566 case ZSTART_PHASE_2:
567 jam();
568 ph2GLab(signal);
569 return;
570 break;
571 case ZSTART_PHASE_3:
572 jam();
573 ph3ALab(signal);
574 return;
575 break;
576 case ZSTART_PHASE_4:
577 jam();
578 ph4BLab(signal);
579 return;
580 break;
581 case ZSTART_PHASE_5:
582 jam();
583 ph5ALab(signal);
584 return;
585 break;
586 case ZSTART_PHASE_6:
587 jam();
588 ph6ALab(signal);
589 return;
590 break;
591 case ZSTART_PHASE_7:
592 jam();
593 ph6BLab(signal);
594 return;
595 break;
596 case ZSTART_PHASE_8:
597 jam();
598 ph7ALab(signal);
599 return;
600 break;
601 case ZSTART_PHASE_9:
602 jam();
603 ph8ALab(signal);
604 return;
605 break;
606 default:
607 jam();
608 systemErrorLab(signal, __LINE__);
609 return;
610 break;
611 }//switch
612 }//Ndbcntr::execNDB_STTORRY()
613
startPhase1Lab(Signal * signal)614 void Ndbcntr::startPhase1Lab(Signal* signal)
615 {
616 jamEntry();
617
618 initData(signal);
619
620 cdynamicNodeId = 0;
621
622 NdbBlocksRecPtr ndbBlocksPtr;
623 ndbBlocksPtr.i = 0;
624 ptrAss(ndbBlocksPtr, ndbBlocksRec);
625 ndbBlocksPtr.p->blockref = DBLQH_REF;
626 ndbBlocksPtr.i = 1;
627 ptrAss(ndbBlocksPtr, ndbBlocksRec);
628 ndbBlocksPtr.p->blockref = DBDICT_REF;
629 ndbBlocksPtr.i = 2;
630 ptrAss(ndbBlocksPtr, ndbBlocksRec);
631 ndbBlocksPtr.p->blockref = DBTUP_REF;
632 ndbBlocksPtr.i = 3;
633 ptrAss(ndbBlocksPtr, ndbBlocksRec);
634 ndbBlocksPtr.p->blockref = DBACC_REF;
635 ndbBlocksPtr.i = 4;
636 ptrAss(ndbBlocksPtr, ndbBlocksRec);
637 ndbBlocksPtr.p->blockref = DBTC_REF;
638 ndbBlocksPtr.i = 5;
639 ptrAss(ndbBlocksPtr, ndbBlocksRec);
640 ndbBlocksPtr.p->blockref = DBDIH_REF;
641 sendSttorry(signal);
642 return;
643 }
644
execREAD_NODESREF(Signal * signal)645 void Ndbcntr::execREAD_NODESREF(Signal* signal)
646 {
647 jamEntry();
648 systemErrorLab(signal, __LINE__);
649 return;
650 }//Ndbcntr::execREAD_NODESREF()
651
652
653 /*******************************/
654 /* NDB_STARTREF */
655 /*******************************/
execNDB_STARTREF(Signal * signal)656 void Ndbcntr::execNDB_STARTREF(Signal* signal)
657 {
658 jamEntry();
659 systemErrorLab(signal, __LINE__);
660 return;
661 }//Ndbcntr::execNDB_STARTREF()
662
663 /*******************************/
664 /* STTOR */
665 /*******************************/
startPhase2Lab(Signal * signal)666 void Ndbcntr::startPhase2Lab(Signal* signal)
667 {
668 c_start.m_lastGci = 0;
669 c_start.m_lastGciNodeId = getOwnNodeId();
670
671 DihRestartReq * req = CAST_PTR(DihRestartReq, signal->getDataPtrSend());
672 req->senderRef = reference();
673 sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal,
674 DihRestartReq::SignalLength, JBB);
675 return;
676 }//Ndbcntr::startPhase2Lab()
677
678 /*******************************/
679 /* DIH_RESTARTCONF */
680 /*******************************/
execDIH_RESTARTCONF(Signal * signal)681 void Ndbcntr::execDIH_RESTARTCONF(Signal* signal)
682 {
683 jamEntry();
684
685 const DihRestartConf * conf = CAST_CONSTPTR(DihRestartConf,
686 signal->getDataPtrSend());
687 c_start.m_lastGci = conf->latest_gci;
688 ctypeOfStart = NodeState::ST_SYSTEM_RESTART;
689 cdihStartType = ctypeOfStart;
690 ph2ALab(signal);
691 return;
692 }//Ndbcntr::execDIH_RESTARTCONF()
693
694 /*******************************/
695 /* DIH_RESTARTREF */
696 /*******************************/
execDIH_RESTARTREF(Signal * signal)697 void Ndbcntr::execDIH_RESTARTREF(Signal* signal)
698 {
699 jamEntry();
700 ctypeOfStart = NodeState::ST_INITIAL_START;
701 cdihStartType = ctypeOfStart;
702 ph2ALab(signal);
703 return;
704 }//Ndbcntr::execDIH_RESTARTREF()
705
ph2ALab(Signal * signal)706 void Ndbcntr::ph2ALab(Signal* signal)
707 {
708 /******************************/
709 /* request configured nodes */
710 /* from QMGR */
711 /* READ_NODESREQ */
712 /******************************/
713 signal->theData[0] = reference();
714 sendSignal(QMGR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
715 return;
716 }//Ndbcntr::ph2ALab()
717
718 inline
719 Uint64
setTimeout(Uint64 time,Uint32 timeoutValue)720 setTimeout(Uint64 time, Uint32 timeoutValue){
721 if(timeoutValue == 0)
722 return ~(Uint64)0;
723 return time + timeoutValue;
724 }
725
726 /*******************************/
727 /* READ_NODESCONF */
728 /*******************************/
execREAD_NODESCONF(Signal * signal)729 void Ndbcntr::execREAD_NODESCONF(Signal* signal)
730 {
731 jamEntry();
732 const ReadNodesConf * readNodes = (ReadNodesConf *)&signal->theData[0];
733
734 cmasterNodeId = readNodes->masterNodeId;
735 cdynamicNodeId = readNodes->ndynamicId;
736
737 /**
738 * All defined nodes...
739 */
740 c_allDefinedNodes.assign(NdbNodeBitmask::Size, readNodes->allNodes);
741 c_clusterNodes.assign(NdbNodeBitmask::Size, readNodes->clusterNodes);
742
743 Uint32 to_1 = 30000;
744 Uint32 to_2 = 0;
745 Uint32 to_3 = 0;
746
747 const ndb_mgm_configuration_iterator * p =
748 m_ctx.m_config.getOwnConfigIterator();
749
750 ndbrequire(p != 0);
751 ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTIAL_TIMEOUT, &to_1);
752 ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTITION_TIMEOUT, &to_2);
753 ndb_mgm_get_int_parameter(p, CFG_DB_START_FAILURE_TIMEOUT, &to_3);
754
755 c_start.m_startTime = NdbTick_CurrentMillisecond();
756 c_start.m_startPartialTimeout = setTimeout(c_start.m_startTime, to_1);
757 c_start.m_startPartitionedTimeout = setTimeout(c_start.m_startTime, to_2);
758 c_start.m_startFailureTimeout = setTimeout(c_start.m_startTime, to_3);
759
760 sendCntrStartReq(signal);
761
762 signal->theData[0] = ZSTARTUP;
763 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 1);
764
765 return;
766 }
767
768 void
execCM_ADD_REP(Signal * signal)769 Ndbcntr::execCM_ADD_REP(Signal* signal){
770 jamEntry();
771 c_clusterNodes.set(signal->theData[0]);
772 }
773
774 void
sendCntrStartReq(Signal * signal)775 Ndbcntr::sendCntrStartReq(Signal * signal){
776 jamEntry();
777
778 CntrStartReq * req = (CntrStartReq*)signal->getDataPtrSend();
779 req->startType = ctypeOfStart;
780 req->lastGci = c_start.m_lastGci;
781 req->nodeId = getOwnNodeId();
782 sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_START_REQ,
783 signal, CntrStartReq::SignalLength, JBB);
784 }
785
786 void
execCNTR_START_REF(Signal * signal)787 Ndbcntr::execCNTR_START_REF(Signal * signal){
788 jamEntry();
789 const CntrStartRef * ref = (CntrStartRef*)signal->getDataPtr();
790
791 switch(ref->errorCode){
792 case CntrStartRef::NotMaster:
793 jam();
794 cmasterNodeId = ref->masterNodeId;
795 sendCntrStartReq(signal);
796 return;
797 case CntrStartRef::StopInProgress:
798 jam();
799 progError(__LINE__, NDBD_EXIT_RESTART_DURING_SHUTDOWN);
800 }
801 ndbrequire(false);
802 }
803
804 void
reset()805 Ndbcntr::StartRecord::reset(){
806 m_starting.clear();
807 m_waiting.clear();
808 m_withLog.clear();
809 m_withoutLog.clear();
810 m_waitTO.clear();
811 m_lastGci = m_lastGciNodeId = 0;
812 m_startPartialTimeout = ~0;
813 m_startPartitionedTimeout = ~0;
814 m_startFailureTimeout = ~0;
815
816 m_logNodesCount = 0;
817 bzero(m_wait_sp, sizeof(m_wait_sp));
818 }
819
820 void
execCNTR_START_CONF(Signal * signal)821 Ndbcntr::execCNTR_START_CONF(Signal * signal){
822 jamEntry();
823 const CntrStartConf * conf = (CntrStartConf*)signal->getDataPtr();
824
825 cnoStartNodes = conf->noStartNodes;
826 ctypeOfStart = (NodeState::StartType)conf->startType;
827 cdihStartType = ctypeOfStart;
828 c_start.m_lastGci = conf->startGci;
829 cmasterNodeId = conf->masterNodeId;
830 NdbNodeBitmask tmp;
831 tmp.assign(NdbNodeBitmask::Size, conf->startedNodes);
832 c_startedNodes.bitOR(tmp);
833 c_start.m_starting.assign(NdbNodeBitmask::Size, conf->startingNodes);
834 m_cntr_start_conf = true;
835 ph2GLab(signal);
836 }
837
838 /**
839 * Tried with parallell nr, but it crashed in DIH
840 * so I turned it off, as I don't want to debug DIH now...
841 * Jonas 19/11-03
842 *
843 * After trying for 2 hours, I gave up.
844 * DIH is not designed to support it, and
845 * it requires quite of lot of changes to
846 * make it work
847 * Jonas 5/12-03
848 */
849 #define PARALLELL_NR 0
850
851 #if PARALLELL_NR
852 const bool parallellNR = true;
853 #else
854 const bool parallellNR = false;
855 #endif
856
857 void
execCNTR_START_REP(Signal * signal)858 Ndbcntr::execCNTR_START_REP(Signal* signal){
859 jamEntry();
860 Uint32 nodeId = signal->theData[0];
861
862 c_startedNodes.set(nodeId);
863 c_start.m_starting.clear(nodeId);
864
865 /**
866 * Inform all interested blocks that node has started
867 */
868 for(Uint32 i = 0; i<ALL_BLOCKS_SZ; i++){
869 sendSignal(ALL_BLOCKS[i].Ref, GSN_NODE_START_REP, signal, 1, JBB);
870 }
871
872 signal->theData[0] = nodeId;
873 execSTART_PERMREP(signal);
874 }
875
876 void
execSTART_PERMREP(Signal * signal)877 Ndbcntr::execSTART_PERMREP(Signal* signal)
878 {
879 Uint32 nodeId = signal->theData[0];
880 c_startedNodes.set(nodeId);
881 c_start.m_starting.clear(nodeId);
882
883 if(!c_start.m_starting.isclear()){
884 jam();
885 return;
886 }
887
888 if(cmasterNodeId != getOwnNodeId()){
889 jam();
890 c_start.reset();
891 return;
892 }
893
894 if(c_start.m_waiting.isclear()){
895 jam();
896 c_start.reset();
897 return;
898 }
899
900 startWaitingNodes(signal);
901 }
902
903 void
execCNTR_START_REQ(Signal * signal)904 Ndbcntr::execCNTR_START_REQ(Signal * signal){
905 jamEntry();
906 const CntrStartReq * req = (CntrStartReq*)signal->getDataPtr();
907
908 const Uint32 nodeId = req->nodeId;
909 const Uint32 lastGci = req->lastGci;
910 const NodeState::StartType st = (NodeState::StartType)req->startType;
911
912 if(cmasterNodeId == 0){
913 jam();
914 // Has not completed READNODES yet
915 sendSignalWithDelay(reference(), GSN_CNTR_START_REQ, signal, 100,
916 signal->getLength());
917 return;
918 }
919
920 if(cmasterNodeId != getOwnNodeId()){
921 jam();
922 sendCntrStartRef(signal, nodeId, CntrStartRef::NotMaster);
923 return;
924 }
925
926 const NodeState & nodeState = getNodeState();
927 switch(nodeState.startLevel){
928 case NodeState::SL_NOTHING:
929 case NodeState::SL_CMVMI:
930 jam();
931 ndbrequire(false);
932 case NodeState::SL_STARTING:
933 case NodeState::SL_STARTED:
934 jam();
935 break;
936
937 case NodeState::SL_STOPPING_1:
938 case NodeState::SL_STOPPING_2:
939 case NodeState::SL_STOPPING_3:
940 case NodeState::SL_STOPPING_4:
941 jam();
942 sendCntrStartRef(signal, nodeId, CntrStartRef::StopInProgress);
943 return;
944 }
945
946 /**
947 * Am I starting (or started)
948 */
949 const bool starting = (nodeState.startLevel != NodeState::SL_STARTED);
950
951 c_start.m_waiting.set(nodeId);
952 switch(st){
953 case NodeState::ST_INITIAL_START:
954 jam();
955 c_start.m_withoutLog.set(nodeId);
956 break;
957 case NodeState::ST_SYSTEM_RESTART:
958 jam();
959 c_start.m_withLog.set(nodeId);
960 if(starting && lastGci > c_start.m_lastGci){
961 jam();
962 CntrStartRef * ref = (CntrStartRef*)signal->getDataPtrSend();
963 ref->errorCode = CntrStartRef::NotMaster;
964 ref->masterNodeId = nodeId;
965 NodeReceiverGroup rg (NDBCNTR, c_start.m_waiting);
966 sendSignal(rg, GSN_CNTR_START_REF, signal,
967 CntrStartRef::SignalLength, JBB);
968 return;
969 }
970 if(starting){
971 jam();
972 Uint32 i = c_start.m_logNodesCount++;
973 c_start.m_logNodes[i].m_nodeId = nodeId;
974 c_start.m_logNodes[i].m_lastGci = req->lastGci;
975 }
976 break;
977 case NodeState::ST_NODE_RESTART:
978 case NodeState::ST_INITIAL_NODE_RESTART:
979 case NodeState::ST_ILLEGAL_TYPE:
980 ndbrequire(false);
981 }
982
983 const bool startInProgress = !c_start.m_starting.isclear();
984
985 if((starting && startInProgress) || (startInProgress && !parallellNR)){
986 jam();
987 // We're already starting together with a bunch of nodes
988 // Let this node wait...
989 return;
990 }
991
992 if(starting){
993 jam();
994 trySystemRestart(signal);
995 } else {
996 jam();
997 startWaitingNodes(signal);
998 }
999 return;
1000 }
1001
1002 void
startWaitingNodes(Signal * signal)1003 Ndbcntr::startWaitingNodes(Signal * signal){
1004
1005 #if ! PARALLELL_NR
1006 if (!c_start.m_waitTO.isclear())
1007 {
1008 jam();
1009
1010 {
1011 char buf[100];
1012 ndbout_c("starting (TO) %s", c_start.m_waitTO.getText(buf));
1013 }
1014
1015 /**
1016 * TO during SR
1017 * this can run in parallel (nowadays :-)
1018 */
1019 NodeReceiverGroup rg(NDBCNTR, c_start.m_waitTO);
1020 c_start.m_starting.bitOR(c_start.m_waitTO);
1021 c_start.m_waiting.bitANDC(c_start.m_waitTO);
1022 c_start.m_waitTO.clear();
1023
1024 /**
1025 * They are stuck in CntrWaitRep::ZWAITPOINT_4_1
1026 * have all meta data ok...but needs START_COPYREQ
1027 */
1028 CntrWaitRep* rep = (CntrWaitRep*)signal->getDataPtrSend();
1029 rep->nodeId = getOwnNodeId();
1030 rep->waitPoint = CntrWaitRep::ZWAITPOINT_4_2_TO;
1031 sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB);
1032 return;
1033 }
1034
1035 const Uint32 nodeId = c_start.m_waiting.find(0);
1036 const Uint32 Tref = calcNdbCntrBlockRef(nodeId);
1037 ndbrequire(nodeId != c_start.m_waiting.NotFound);
1038
1039 NodeState::StartType nrType = NodeState::ST_NODE_RESTART;
1040 if(c_start.m_withoutLog.get(nodeId))
1041 {
1042 jam();
1043 nrType = NodeState::ST_INITIAL_NODE_RESTART;
1044 }
1045
1046 /**
1047 * Let node perform restart
1048 */
1049 CntrStartConf * conf = (CntrStartConf*)signal->getDataPtrSend();
1050 conf->noStartNodes = 1;
1051 conf->startType = nrType;
1052 conf->startGci = ~0; // Not used
1053 conf->masterNodeId = getOwnNodeId();
1054 BitmaskImpl::clear(NdbNodeBitmask::Size, conf->startingNodes);
1055 BitmaskImpl::set(NdbNodeBitmask::Size, conf->startingNodes, nodeId);
1056 c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes);
1057 sendSignal(Tref, GSN_CNTR_START_CONF, signal,
1058 CntrStartConf::SignalLength, JBB);
1059
1060 c_start.m_waiting.clear(nodeId);
1061 c_start.m_withLog.clear(nodeId);
1062 c_start.m_withoutLog.clear(nodeId);
1063 c_start.m_starting.set(nodeId);
1064 #else
1065 // Parallell nr
1066
1067 c_start.m_starting = c_start.m_waiting;
1068 c_start.m_waiting.clear();
1069
1070 CntrStartConf * conf = (CntrStartConf*)signal->getDataPtrSend();
1071 conf->noStartNodes = 1;
1072 conf->startGci = ~0; // Not used
1073 conf->masterNodeId = getOwnNodeId();
1074 c_start.m_starting.copyto(NdbNodeBitmask::Size, conf->startingNodes);
1075 c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes);
1076
1077 char buf[100];
1078 if(!c_start.m_withLog.isclear()){
1079 jam();
1080 ndbout_c("Starting nodes w/ log: %s", c_start.m_withLog.getText(buf));
1081
1082 NodeReceiverGroup rg(NDBCNTR, c_start.m_withLog);
1083 conf->startType = NodeState::ST_NODE_RESTART;
1084
1085 sendSignal(rg, GSN_CNTR_START_CONF, signal,
1086 CntrStartConf::SignalLength, JBB);
1087 }
1088
1089 if(!c_start.m_withoutLog.isclear()){
1090 jam();
1091 ndbout_c("Starting nodes wo/ log: %s", c_start.m_withoutLog.getText(buf));
1092 NodeReceiverGroup rg(NDBCNTR, c_start.m_withoutLog);
1093 conf->startType = NodeState::ST_INITIAL_NODE_RESTART;
1094
1095 sendSignal(rg, GSN_CNTR_START_CONF, signal,
1096 CntrStartConf::SignalLength, JBB);
1097 }
1098
1099 c_start.m_waiting.clear();
1100 c_start.m_withLog.clear();
1101 c_start.m_withoutLog.clear();
1102 #endif
1103 }
1104
1105 void
sendCntrStartRef(Signal * signal,Uint32 nodeId,CntrStartRef::ErrorCode code)1106 Ndbcntr::sendCntrStartRef(Signal * signal,
1107 Uint32 nodeId, CntrStartRef::ErrorCode code){
1108 CntrStartRef * ref = (CntrStartRef*)signal->getDataPtrSend();
1109 ref->errorCode = code;
1110 ref->masterNodeId = cmasterNodeId;
1111 sendSignal(calcNdbCntrBlockRef(nodeId), GSN_CNTR_START_REF, signal,
1112 CntrStartRef::SignalLength, JBB);
1113 }
1114
1115 CheckNodeGroups::Output
checkNodeGroups(Signal * signal,const NdbNodeBitmask & mask)1116 Ndbcntr::checkNodeGroups(Signal* signal, const NdbNodeBitmask & mask){
1117 CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
1118 sd->blockRef = reference();
1119 sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck;
1120 sd->mask = mask;
1121 EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
1122 CheckNodeGroups::SignalLength);
1123 jamEntry();
1124 return (CheckNodeGroups::Output)sd->output;
1125 }
1126
1127 bool
trySystemRestart(Signal * signal)1128 Ndbcntr::trySystemRestart(Signal* signal){
1129 /**
1130 * System restart something
1131 */
1132 const bool allNodes = c_start.m_waiting.equal(c_allDefinedNodes);
1133 const bool allClusterNodes = c_start.m_waiting.equal(c_clusterNodes);
1134
1135 if(!allClusterNodes){
1136 jam();
1137 return false;
1138 }
1139
1140 NodeState::StartType srType = NodeState::ST_SYSTEM_RESTART;
1141 if(c_start.m_waiting.equal(c_start.m_withoutLog))
1142 {
1143 jam();
1144 srType = NodeState::ST_INITIAL_START;
1145 c_start.m_starting = c_start.m_withoutLog; // Used for starting...
1146 c_start.m_withoutLog.clear();
1147 } else {
1148
1149 CheckNodeGroups::Output wLog = checkNodeGroups(signal, c_start.m_withLog);
1150
1151 switch (wLog) {
1152 case CheckNodeGroups::Win:
1153 jam();
1154 break;
1155 case CheckNodeGroups::Lose:
1156 jam();
1157 // If we lose with all nodes, then we're in trouble
1158 ndbrequire(!allNodes);
1159 return false;
1160 case CheckNodeGroups::Partitioning:
1161 jam();
1162 bool allowPartition = (c_start.m_startPartitionedTimeout != (Uint64)~0);
1163
1164 if(allNodes){
1165 if(allowPartition){
1166 jam();
1167 break;
1168 }
1169 ndbrequire(false); // All nodes -> partitioning, which is not allowed
1170 }
1171
1172 break;
1173 }
1174
1175 // For now only with the "logged"-ones.
1176 // Let the others do node restart afterwards...
1177 c_start.m_starting = c_start.m_withLog;
1178 c_start.m_withLog.clear();
1179 }
1180
1181 /**
1182 * Okidoki, we try to start
1183 */
1184 CntrStartConf * conf = (CntrStartConf*)signal->getDataPtr();
1185 conf->noStartNodes = c_start.m_starting.count();
1186 conf->startType = srType;
1187 conf->startGci = c_start.m_lastGci;
1188 conf->masterNodeId = c_start.m_lastGciNodeId;
1189 c_start.m_starting.copyto(NdbNodeBitmask::Size, conf->startingNodes);
1190 c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes);
1191
1192 ndbrequire(c_start.m_lastGciNodeId == getOwnNodeId());
1193
1194 NodeReceiverGroup rg(NDBCNTR, c_start.m_starting);
1195 sendSignal(rg, GSN_CNTR_START_CONF, signal, CntrStartConf::SignalLength,JBB);
1196
1197 c_start.m_waiting.bitANDC(c_start.m_starting);
1198
1199 return true;
1200 }
1201
ph2GLab(Signal * signal)1202 void Ndbcntr::ph2GLab(Signal* signal)
1203 {
1204 if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
1205 jam();
1206 sendNdbSttor(signal);
1207 return;
1208 }//if
1209 sendSttorry(signal);
1210 return;
1211 }//Ndbcntr::ph2GLab()
1212
1213 /*
1214 4.4 START PHASE 3 */
1215 /*###########################################################################*/
1216 // SEND SIGNAL NDBSTTOR TO ALL BLOCKS, ACC, DICT, DIH, LQH, TC AND TUP
1217 // WHEN ALL BLOCKS HAVE RETURNED THEIR NDB_STTORRY ALL BLOCK HAVE FINISHED
1218 // THEIR LOCAL CONNECTIONs SUCESSFULLY
1219 // AND THEN WE CAN SEND APPL_STARTREG TO INFORM QMGR THAT WE ARE READY TO
1220 // SET UP DISTRIBUTED CONNECTIONS.
1221 /*--------------------------------------------------------------*/
1222 // THIS IS NDB START PHASE 3.
1223 /*--------------------------------------------------------------*/
1224 /*******************************/
1225 /* STTOR */
1226 /*******************************/
startPhase3Lab(Signal * signal)1227 void Ndbcntr::startPhase3Lab(Signal* signal)
1228 {
1229 ph3ALab(signal);
1230 return;
1231 }//Ndbcntr::startPhase3Lab()
1232
1233 /*******************************/
1234 /* NDB_STTORRY */
1235 /*******************************/
ph3ALab(Signal * signal)1236 void Ndbcntr::ph3ALab(Signal* signal)
1237 {
1238 if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
1239 jam();
1240 sendNdbSttor(signal);
1241 return;
1242 }//if
1243
1244 sendSttorry(signal);
1245 return;
1246 }//Ndbcntr::ph3ALab()
1247
1248 /*
1249 4.5 START PHASE 4 */
1250 /*###########################################################################*/
1251 // WAIT FOR ALL NODES IN CLUSTER TO CHANGE STATE INTO ZSTART ,
1252 // APPL_CHANGEREP IS ALWAYS SENT WHEN SOMEONE HAVE
1253 // CHANGED THEIR STATE. APPL_STARTCONF INDICATES THAT ALL NODES ARE IN START
1254 // STATE SEND NDB_STARTREQ TO DIH AND THEN WAIT FOR NDB_STARTCONF
1255 /*---------------------------------------------------------------------------*/
1256 /*******************************/
1257 /* STTOR */
1258 /*******************************/
startPhase4Lab(Signal * signal)1259 void Ndbcntr::startPhase4Lab(Signal* signal)
1260 {
1261 ph4ALab(signal);
1262 }//Ndbcntr::startPhase4Lab()
1263
1264
ph4ALab(Signal * signal)1265 void Ndbcntr::ph4ALab(Signal* signal)
1266 {
1267 ph4BLab(signal);
1268 return;
1269 }//Ndbcntr::ph4ALab()
1270
1271 /*******************************/
1272 /* NDB_STTORRY */
1273 /*******************************/
ph4BLab(Signal * signal)1274 void Ndbcntr::ph4BLab(Signal* signal)
1275 {
1276 /*--------------------------------------*/
1277 /* CASE: CSTART_PHASE = ZSTART_PHASE_4 */
1278 /*--------------------------------------*/
1279 if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
1280 jam();
1281 sendNdbSttor(signal);
1282 return;
1283 }//if
1284 if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
1285 (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
1286 jam();
1287 sendSttorry(signal);
1288 return;
1289 }//if
1290 waitpoint41Lab(signal);
1291 return;
1292 }//Ndbcntr::ph4BLab()
1293
waitpoint41Lab(Signal * signal)1294 void Ndbcntr::waitpoint41Lab(Signal* signal)
1295 {
1296 if (getOwnNodeId() == cmasterNodeId) {
1297 jam();
1298 /*--------------------------------------*/
1299 /* MASTER WAITS UNTIL ALL SLAVES HAS */
1300 /* SENT THE REPORTS */
1301 /*--------------------------------------*/
1302 cnoWaitrep++;
1303 if (cnoWaitrep == cnoStartNodes) {
1304 jam();
1305 cnoWaitrep = 0;
1306 /*---------------------------------------------------------------------------*/
1307 // NDB_STARTREQ STARTS UP ALL SET UP OF DISTRIBUTION INFORMATION IN DIH AND
1308 // DICT. AFTER SETTING UP THIS
1309 // DATA IT USES THAT DATA TO SET UP WHICH FRAGMENTS THAT ARE TO START AND
1310 // WHERE THEY ARE TO START. THEN
1311 // IT SETS UP THE FRAGMENTS AND RECOVERS THEM BY:
1312 // 1) READING A LOCAL CHECKPOINT FROM DISK.
1313 // 2) EXECUTING THE UNDO LOG ON INDEX AND DATA.
1314 // 3) EXECUTING THE FRAGMENT REDO LOG FROM ONE OR SEVERAL NODES TO
1315 // RESTORE THE RESTART CONFIGURATION OF DATA IN NDB CLUSTER.
1316 /*---------------------------------------------------------------------------*/
1317 signal->theData[0] = reference();
1318 signal->theData[1] = ctypeOfStart;
1319 sendSignal(DBDIH_REF, GSN_NDB_STARTREQ, signal, 2, JBB);
1320 }//if
1321 } else {
1322 jam();
1323 /*--------------------------------------*/
1324 /* SLAVE NODES WILL PASS HERE ONCE AND */
1325 /* SEND A WAITPOINT REPORT TO MASTER. */
1326 /* SLAVES WONT DO ANYTHING UNTIL THEY */
1327 /* RECEIVE A WAIT REPORT FROM THE MASTER*/
1328 /*--------------------------------------*/
1329 signal->theData[0] = getOwnNodeId();
1330 signal->theData[1] = CntrWaitRep::ZWAITPOINT_4_1;
1331 sendSignal(calcNdbCntrBlockRef(cmasterNodeId),
1332 GSN_CNTR_WAITREP, signal, 2, JBB);
1333 }//if
1334 return;
1335 }//Ndbcntr::waitpoint41Lab()
1336
1337 void
waitpoint42To(Signal * signal)1338 Ndbcntr::waitpoint42To(Signal* signal)
1339 {
1340 jam();
1341
1342 /**
1343 * This is a ugly hack
1344 * To "easy" enable TO during SR
1345 * a better solution would be to move "all" start handling
1346 * from DIH to cntr...which knows what's going on
1347 */
1348 cdihStartType = NodeState::ST_SYSTEM_RESTART;
1349 ctypeOfStart = NodeState::ST_NODE_RESTART;
1350
1351 /**
1352 * This is immensely ugly...but makes TUX work (yuck)
1353 */
1354 {
1355 NodeStateRep* rep = (NodeStateRep*)signal->getDataPtrSend();
1356 rep->nodeState = getNodeState();
1357 rep->nodeState.masterNodeId = cmasterNodeId;
1358 rep->nodeState.setNodeGroup(c_nodeGroup);
1359 rep->nodeState.starting.restartType = NodeState::ST_NODE_RESTART;
1360
1361 sendSignal(DBTUX_REF, GSN_NODE_STATE_REP, signal,
1362 NodeStateRep::SignalLength, JBB);
1363 }
1364
1365 /**
1366 * We were forced to perform TO
1367 */
1368 StartCopyReq* req = (StartCopyReq*)signal->getDataPtrSend();
1369 req->senderRef = reference();
1370 req->senderData = RNIL;
1371 req->flags = StartCopyReq::WAIT_LCP;
1372 req->startingNodeId = getOwnNodeId();
1373 sendSignal(DBDIH_REF, GSN_START_COPYREQ, signal,
1374 StartCopyReq::SignalLength, JBB);
1375 }
1376
1377 void
execSTART_COPYREF(Signal * signal)1378 Ndbcntr::execSTART_COPYREF(Signal* signal)
1379 {
1380
1381 }
1382
1383 void
execSTART_COPYCONF(Signal * signal)1384 Ndbcntr::execSTART_COPYCONF(Signal* signal)
1385 {
1386 sendSttorry(signal);
1387 }
1388
1389
1390 /*******************************/
1391 /* NDB_STARTCONF */
1392 /*******************************/
execNDB_STARTCONF(Signal * signal)1393 void Ndbcntr::execNDB_STARTCONF(Signal* signal)
1394 {
1395 jamEntry();
1396
1397 NdbNodeBitmask tmp;
1398 if (signal->getLength() >= 1 + NdbNodeBitmask::Size)
1399 {
1400 jam();
1401 tmp.assign(NdbNodeBitmask::Size, signal->theData+1);
1402 if (!c_start.m_starting.equal(tmp))
1403 {
1404 /**
1405 * Some nodes has been "excluded" from SR
1406 */
1407 char buf0[100], buf1[100];
1408 ndbout_c("execNDB_STARTCONF: changing from %s to %s",
1409 c_start.m_starting.getText(buf0),
1410 tmp.getText(buf1));
1411
1412 NdbNodeBitmask waiting = c_start.m_starting;
1413 waiting.bitANDC(tmp);
1414
1415 c_start.m_waiting.bitOR(waiting);
1416 c_start.m_waitTO.bitOR(waiting);
1417
1418 c_start.m_starting.assign(tmp);
1419 cnoStartNodes = c_start.m_starting.count();
1420 }
1421 }
1422
1423 NodeReceiverGroup rg(NDBCNTR, c_start.m_starting);
1424 signal->theData[0] = getOwnNodeId();
1425 signal->theData[1] = CntrWaitRep::ZWAITPOINT_4_2;
1426 c_start.m_starting.copyto(NdbNodeBitmask::Size, signal->theData+2);
1427 sendSignal(rg, GSN_CNTR_WAITREP, signal, 2 + NdbNodeBitmask::Size,
1428 JBB);
1429 return;
1430 }//Ndbcntr::execNDB_STARTCONF()
1431
1432 /*
1433 4.6 START PHASE 5 */
1434 /*###########################################################################*/
1435 // SEND APPL_RUN TO THE QMGR IN THIS BLOCK
1436 // SEND NDB_STTOR ALL BLOCKS ACC, DICT, DIH, LQH, TC AND TUP THEN WAIT FOR
1437 // THEIR NDB_STTORRY
1438 /*---------------------------------------------------------------------------*/
1439 /*******************************/
1440 /* STTOR */
1441 /*******************************/
startPhase5Lab(Signal * signal)1442 void Ndbcntr::startPhase5Lab(Signal* signal)
1443 {
1444 ph5ALab(signal);
1445 return;
1446 }//Ndbcntr::startPhase5Lab()
1447
1448 /*******************************/
1449 /* NDB_STTORRY */
1450 /*******************************/
1451 /*---------------------------------------------------------------------------*/
1452 // THIS IS NDB START PHASE 5.
1453 /*---------------------------------------------------------------------------*/
1454 // IN THIS START PHASE TUP INITIALISES DISK FILES FOR DISK STORAGE IF INITIAL
1455 // START. DIH WILL START UP
1456 // THE GLOBAL CHECKPOINT PROTOCOL AND WILL CONCLUDE ANY UNFINISHED TAKE OVERS
1457 // THAT STARTED BEFORE THE SYSTEM CRASH.
1458 /*---------------------------------------------------------------------------*/
ph5ALab(Signal * signal)1459 void Ndbcntr::ph5ALab(Signal* signal)
1460 {
1461 if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
1462 jam();
1463 sendNdbSttor(signal);
1464 return;
1465 }//if
1466
1467 cstartPhase = cstartPhase + 1;
1468 cinternalStartphase = cstartPhase - 1;
1469 if (getOwnNodeId() == cmasterNodeId) {
1470 switch(ctypeOfStart){
1471 case NodeState::ST_INITIAL_START:
1472 jam();
1473 /*--------------------------------------*/
1474 /* MASTER CNTR IS RESPONSIBLE FOR */
1475 /* CREATING SYSTEM TABLES */
1476 /*--------------------------------------*/
1477 beginSchemaTransLab(signal);
1478 return;
1479 case NodeState::ST_SYSTEM_RESTART:
1480 jam();
1481 waitpoint52Lab(signal);
1482 return;
1483 case NodeState::ST_NODE_RESTART:
1484 case NodeState::ST_INITIAL_NODE_RESTART:
1485 jam();
1486 break;
1487 case NodeState::ST_ILLEGAL_TYPE:
1488 jam();
1489 break;
1490 }
1491 ndbrequire(false);
1492 }
1493
1494 /**
1495 * Not master
1496 */
1497 NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend();
1498 switch(ctypeOfStart){
1499 case NodeState::ST_NODE_RESTART:
1500 case NodeState::ST_INITIAL_NODE_RESTART:
1501 jam();
1502 /*----------------------------------------------------------------------*/
1503 // SEND NDB START PHASE 5 IN NODE RESTARTS TO COPY DATA TO THE NEWLY
1504 // STARTED NODE.
1505 /*----------------------------------------------------------------------*/
1506 req->senderRef = reference();
1507 req->nodeId = getOwnNodeId();
1508 req->internalStartPhase = cinternalStartphase;
1509 req->typeOfStart = cdihStartType;
1510 req->masterNodeId = cmasterNodeId;
1511
1512 //#define TRACE_STTOR
1513 #ifdef TRACE_STTOR
1514 ndbout_c("sending NDB_STTOR(%d) to DIH", cinternalStartphase);
1515 #endif
1516 sendSignal(DBDIH_REF, GSN_NDB_STTOR, signal,
1517 NdbSttor::SignalLength, JBB);
1518 return;
1519 case NodeState::ST_INITIAL_START:
1520 case NodeState::ST_SYSTEM_RESTART:
1521 jam();
1522 /*--------------------------------------*/
1523 /* DURING SYSTEMRESTART AND INITALSTART:*/
1524 /* SLAVE NODES WILL PASS HERE ONCE AND */
1525 /* SEND A WAITPOINT REPORT TO MASTER. */
1526 /* SLAVES WONT DO ANYTHING UNTIL THEY */
1527 /* RECEIVE A WAIT REPORT FROM THE MASTER*/
1528 /* WHEN THE MASTER HAS FINISHED HIS WORK*/
1529 /*--------------------------------------*/
1530 signal->theData[0] = getOwnNodeId();
1531 signal->theData[1] = CntrWaitRep::ZWAITPOINT_5_2;
1532 sendSignal(calcNdbCntrBlockRef(cmasterNodeId),
1533 GSN_CNTR_WAITREP, signal, 2, JBB);
1534 return;
1535 default:
1536 ndbrequire(false);
1537 }
1538 }//Ndbcntr::ph5ALab()
1539
waitpoint52Lab(Signal * signal)1540 void Ndbcntr::waitpoint52Lab(Signal* signal)
1541 {
1542 cnoWaitrep = cnoWaitrep + 1;
1543 /*---------------------------------------------------------------------------*/
1544 // THIS WAITING POINT IS ONLY USED BY A MASTER NODE. WE WILL EXECUTE NDB START
1545 // PHASE 5 FOR DIH IN THE
1546 // MASTER. THIS WILL START UP LOCAL CHECKPOINTS AND WILL ALSO CONCLUDE ANY
1547 // UNFINISHED LOCAL CHECKPOINTS
1548 // BEFORE THE SYSTEM CRASH. THIS WILL ENSURE THAT WE ALWAYS RESTART FROM A
1549 // WELL KNOWN STATE.
1550 /*---------------------------------------------------------------------------*/
1551 /*--------------------------------------*/
1552 /* MASTER WAITS UNTIL HE RECEIVED WAIT */
1553 /* REPORTS FROM ALL SLAVE CNTR */
1554 /*--------------------------------------*/
1555 if (cnoWaitrep == cnoStartNodes) {
1556 jam();
1557 cnoWaitrep = 0;
1558
1559 NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend();
1560 req->senderRef = reference();
1561 req->nodeId = getOwnNodeId();
1562 req->internalStartPhase = cinternalStartphase;
1563 req->typeOfStart = cdihStartType;
1564 req->masterNodeId = cmasterNodeId;
1565 #ifdef TRACE_STTOR
1566 ndbout_c("sending NDB_STTOR(%d) to DIH", cinternalStartphase);
1567 #endif
1568 sendSignal(DBDIH_REF, GSN_NDB_STTOR, signal,
1569 NdbSttor::SignalLength, JBB);
1570 }//if
1571 return;
1572 }//Ndbcntr::waitpoint52Lab()
1573
1574 /*******************************/
1575 /* NDB_STTORRY */
1576 /*******************************/
ph6ALab(Signal * signal)1577 void Ndbcntr::ph6ALab(Signal* signal)
1578 {
1579 if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
1580 (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
1581 jam();
1582 waitpoint51Lab(signal);
1583 return;
1584 }//if
1585
1586 NodeReceiverGroup rg(NDBCNTR, c_start.m_starting);
1587 rg.m_nodes.clear(getOwnNodeId());
1588 signal->theData[0] = getOwnNodeId();
1589 signal->theData[1] = CntrWaitRep::ZWAITPOINT_5_1;
1590 sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB);
1591
1592 waitpoint51Lab(signal);
1593 return;
1594 }//Ndbcntr::ph6ALab()
1595
waitpoint51Lab(Signal * signal)1596 void Ndbcntr::waitpoint51Lab(Signal* signal)
1597 {
1598 cstartPhase = cstartPhase + 1;
1599 /*---------------------------------------------------------------------------*/
1600 // A FINAL STEP IS NOW TO SEND NDB_STTOR TO TC. THIS MAKES IT POSSIBLE TO
1601 // CONNECT TO TC FOR APPLICATIONS.
1602 // THIS IS NDB START PHASE 6 WHICH IS FOR ALL BLOCKS IN ALL NODES.
1603 /*---------------------------------------------------------------------------*/
1604 cinternalStartphase = cstartPhase - 1;
1605 cndbBlocksCount = 0;
1606 ph6BLab(signal);
1607 return;
1608 }//Ndbcntr::waitpoint51Lab()
1609
ph6BLab(Signal * signal)1610 void Ndbcntr::ph6BLab(Signal* signal)
1611 {
1612 // c_missra.currentStartPhase - cstartPhase - cinternalStartphase =
1613 // 5 - 7 - 6
1614 if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
1615 jam();
1616 sendNdbSttor(signal);
1617 return;
1618 }//if
1619 if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
1620 (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
1621 jam();
1622 sendSttorry(signal);
1623 return;
1624 }
1625 waitpoint61Lab(signal);
1626 }
1627
waitpoint61Lab(Signal * signal)1628 void Ndbcntr::waitpoint61Lab(Signal* signal)
1629 {
1630 if (getOwnNodeId() == cmasterNodeId) {
1631 jam();
1632 cnoWaitrep6++;
1633 if (cnoWaitrep6 == cnoStartNodes) {
1634 jam();
1635 NodeReceiverGroup rg(NDBCNTR, c_start.m_starting);
1636 rg.m_nodes.clear(getOwnNodeId());
1637 signal->theData[0] = getOwnNodeId();
1638 signal->theData[1] = CntrWaitRep::ZWAITPOINT_6_2;
1639 sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB);
1640 sendSttorry(signal);
1641 }
1642 } else {
1643 jam();
1644 signal->theData[0] = getOwnNodeId();
1645 signal->theData[1] = CntrWaitRep::ZWAITPOINT_6_1;
1646 sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_WAITREP, signal, 2, JBB);
1647 }
1648 }
1649
1650 // Start phase 8 (internal 7)
startPhase8Lab(Signal * signal)1651 void Ndbcntr::startPhase8Lab(Signal* signal)
1652 {
1653 cinternalStartphase = cstartPhase - 1;
1654 cndbBlocksCount = 0;
1655 ph7ALab(signal);
1656 }
1657
ph7ALab(Signal * signal)1658 void Ndbcntr::ph7ALab(Signal* signal)
1659 {
1660 while (cndbBlocksCount < ZNO_NDB_BLOCKS) {
1661 jam();
1662 sendNdbSttor(signal);
1663 return;
1664 }
1665 if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
1666 (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
1667 jam();
1668 sendSttorry(signal);
1669 return;
1670 }
1671 waitpoint71Lab(signal);
1672 }
1673
waitpoint71Lab(Signal * signal)1674 void Ndbcntr::waitpoint71Lab(Signal* signal)
1675 {
1676 if (getOwnNodeId() == cmasterNodeId) {
1677 jam();
1678 cnoWaitrep7++;
1679 if (cnoWaitrep7 == cnoStartNodes) {
1680 jam();
1681 NodeReceiverGroup rg(NDBCNTR, c_start.m_starting);
1682 rg.m_nodes.clear(getOwnNodeId());
1683 signal->theData[0] = getOwnNodeId();
1684 signal->theData[1] = CntrWaitRep::ZWAITPOINT_7_2;
1685 sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB);
1686 sendSttorry(signal);
1687 }
1688 } else {
1689 jam();
1690 signal->theData[0] = getOwnNodeId();
1691 signal->theData[1] = CntrWaitRep::ZWAITPOINT_7_1;
1692 sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_WAITREP, signal, 2, JBB);
1693 }
1694 }
1695
1696 // Start phase 9 (internal 8)
startPhase9Lab(Signal * signal)1697 void Ndbcntr::startPhase9Lab(Signal* signal)
1698 {
1699 cinternalStartphase = cstartPhase - 1;
1700 cndbBlocksCount = 0;
1701 ph8ALab(signal);
1702 }
1703
ph8ALab(Signal * signal)1704 void Ndbcntr::ph8ALab(Signal* signal)
1705 {
1706 /*---------------------------------------------------------------------------*/
1707 // NODES WHICH PERFORM A NODE RESTART NEEDS TO GET THE DYNAMIC ID'S
1708 // OF THE OTHER NODES HERE.
1709 /*---------------------------------------------------------------------------*/
1710 sendSttorry(signal);
1711 resetStartVariables(signal);
1712 return;
1713 }//Ndbcntr::ph8BLab()
1714
1715 bool
wait_sp(Signal * signal,Uint32 sp)1716 Ndbcntr::wait_sp(Signal* signal, Uint32 sp)
1717 {
1718 if (sp <= 2)
1719 return false;
1720
1721 switch(ctypeOfStart){
1722 case NodeState::ST_SYSTEM_RESTART:
1723 case NodeState::ST_INITIAL_START:
1724 /**
1725 * synchronized...
1726 */
1727 break;
1728 default:
1729 return false;
1730 }
1731
1732 if (!ndb_wait_sp(getNodeInfo(cmasterNodeId).m_version))
1733 return false;
1734
1735 CntrWaitRep* rep = (CntrWaitRep*)signal->getDataPtrSend();
1736 rep->nodeId = getOwnNodeId();
1737 rep->waitPoint = RNIL;
1738 rep->request = CntrWaitRep::WaitFor;
1739 rep->sp = sp;
1740
1741 sendSignal(calcNdbCntrBlockRef(cmasterNodeId),
1742 GSN_CNTR_WAITREP, signal, CntrWaitRep::SignalLength, JBB);
1743
1744 return true; // wait
1745 }
1746
1747 void
wait_sp_rep(Signal * signal)1748 Ndbcntr::wait_sp_rep(Signal* signal)
1749 {
1750 CntrWaitRep rep = *(CntrWaitRep*)signal->getDataPtrSend();
1751 switch(rep.request){
1752 case CntrWaitRep::WaitFor:
1753 jam();
1754 ndbrequire(cmasterNodeId == getOwnNodeId());
1755 break;
1756 case CntrWaitRep::Grant:
1757 jam();
1758 /**
1759 * We're allowed to proceed
1760 */
1761 c_missra.sendNextSTTOR(signal);
1762 return;
1763 }
1764
1765 c_start.m_wait_sp[rep.nodeId] = rep.sp;
1766
1767 /**
1768 * Check if we should allow someone to start...
1769 */
1770 Uint32 node = c_start.m_starting.find(0);
1771 ndbrequire(node < NDB_ARRAY_SIZE(c_start.m_wait_sp));
1772 Uint32 min = c_start.m_wait_sp[node];
1773 for (; node != NdbNodeBitmask::NotFound;
1774 node = c_start.m_starting.find(node + 1))
1775 {
1776 if (!ndb_wait_sp(getNodeInfo(node).m_version))
1777 continue;
1778
1779 if (c_start.m_wait_sp[node] < min)
1780 {
1781 min = c_start.m_wait_sp[node];
1782 }
1783 }
1784
1785 if (min == 0)
1786 {
1787 /**
1788 * wait for more
1789 */
1790 return;
1791 }
1792
1793 NdbNodeBitmask grantnodes;
1794 node = c_start.m_starting.find(0);
1795 for (; node != NdbNodeBitmask::NotFound;
1796 node = c_start.m_starting.find(node + 1))
1797 {
1798 if (!ndb_wait_sp(getNodeInfo(node).m_version))
1799 continue;
1800
1801 if (c_start.m_wait_sp[node] == min)
1802 {
1803 grantnodes.set(node);
1804 c_start.m_wait_sp[node] = 0;
1805 }
1806 }
1807
1808 NodeReceiverGroup rg(NDBCNTR, grantnodes);
1809 CntrWaitRep * conf = (CntrWaitRep*)signal->getDataPtrSend();
1810 conf->nodeId = getOwnNodeId();
1811 conf->waitPoint = RNIL;
1812 conf->request = CntrWaitRep::Grant;
1813 conf->sp = min;
1814 sendSignal(rg, GSN_CNTR_WAITREP, signal, CntrWaitRep::SignalLength, JBB);
1815 }
1816
1817 /*******************************/
1818 /* CNTR_WAITREP */
1819 /*******************************/
execCNTR_WAITREP(Signal * signal)1820 void Ndbcntr::execCNTR_WAITREP(Signal* signal)
1821 {
1822 jamEntry();
1823 CntrWaitRep* rep = (CntrWaitRep*)signal->getDataPtr();
1824
1825 Uint32 twaitPoint = rep->waitPoint;
1826 switch (twaitPoint) {
1827 case CntrWaitRep::ZWAITPOINT_4_1:
1828 jam();
1829 waitpoint41Lab(signal);
1830 break;
1831 case CntrWaitRep::ZWAITPOINT_4_2:
1832 jam();
1833 c_start.m_starting.assign(NdbNodeBitmask::Size, signal->theData + 2);
1834 sendSttorry(signal);
1835 break;
1836 case CntrWaitRep::ZWAITPOINT_5_1:
1837 jam();
1838 waitpoint51Lab(signal);
1839 break;
1840 case CntrWaitRep::ZWAITPOINT_5_2:
1841 jam();
1842 waitpoint52Lab(signal);
1843 break;
1844 case CntrWaitRep::ZWAITPOINT_6_1:
1845 jam();
1846 waitpoint61Lab(signal);
1847 break;
1848 case CntrWaitRep::ZWAITPOINT_6_2:
1849 jam();
1850 sendSttorry(signal);
1851 break;
1852 case CntrWaitRep::ZWAITPOINT_7_1:
1853 jam();
1854 waitpoint71Lab(signal);
1855 break;
1856 case CntrWaitRep::ZWAITPOINT_7_2:
1857 jam();
1858 sendSttorry(signal);
1859 break;
1860 case CntrWaitRep::ZWAITPOINT_4_2_TO:
1861 jam();
1862 waitpoint42To(signal);
1863 break;
1864 case RNIL:
1865 ndbrequire(signal->getLength() >= CntrWaitRep::SignalLength);
1866 wait_sp_rep(signal);
1867 return;
1868 default:
1869 jam();
1870 systemErrorLab(signal, __LINE__);
1871 break;
1872 }//switch
1873 }//Ndbcntr::execCNTR_WAITREP()
1874
1875 /*******************************/
1876 /* NODE_FAILREP */
1877 /*******************************/
execNODE_FAILREP(Signal * signal)1878 void Ndbcntr::execNODE_FAILREP(Signal* signal)
1879 {
1880 jamEntry();
1881
1882 if (ERROR_INSERTED(1001))
1883 {
1884 sendSignalWithDelay(reference(), GSN_NODE_FAILREP, signal, 100,
1885 signal->getLength());
1886 return;
1887 }
1888
1889 const NodeFailRep * nodeFail = (NodeFailRep *)&signal->theData[0];
1890 NdbNodeBitmask allFailed;
1891 allFailed.assign(NdbNodeBitmask::Size, nodeFail->theNodes);
1892
1893 NdbNodeBitmask failedStarted = c_startedNodes;
1894 NdbNodeBitmask failedStarting = c_start.m_starting;
1895 NdbNodeBitmask failedWaiting = c_start.m_waiting;
1896
1897 failedStarted.bitAND(allFailed);
1898 failedStarting.bitAND(allFailed);
1899 failedWaiting.bitAND(allFailed);
1900
1901 const bool tMasterFailed = allFailed.get(cmasterNodeId);
1902 const bool tStarted = !failedStarted.isclear();
1903 const bool tStarting = !failedStarting.isclear();
1904
1905 if(tMasterFailed){
1906 jam();
1907 /**
1908 * If master has failed choose qmgr president as master
1909 */
1910 cmasterNodeId = nodeFail->masterNodeId;
1911 }
1912
1913 /**
1914 * Clear node bitmasks from failed nodes
1915 */
1916 c_start.m_starting.bitANDC(allFailed);
1917 c_start.m_waiting.bitANDC(allFailed);
1918 c_start.m_withLog.bitANDC(allFailed);
1919 c_start.m_withoutLog.bitANDC(allFailed);
1920 c_start.m_waitTO.bitANDC(allFailed);
1921 c_clusterNodes.bitANDC(allFailed);
1922 c_startedNodes.bitANDC(allFailed);
1923
1924 const NodeState & st = getNodeState();
1925 if(st.startLevel == st.SL_STARTING){
1926 jam();
1927
1928 const Uint32 phase = st.starting.startPhase;
1929
1930 const bool tStartConf = (phase > 2) || (phase == 2 && cndbBlocksCount > 0);
1931
1932 if(tMasterFailed){
1933 progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED,
1934 "Unhandled node failure during restart");
1935 }
1936
1937 if(tStartConf && tStarting){
1938 // One of other starting nodes has crashed...
1939 progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED,
1940 "Unhandled node failure of starting node during restart");
1941 }
1942
1943 if(tStartConf && tStarted){
1944 // One of other started nodes has crashed...
1945 progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED,
1946 "Unhandled node failure of started node during restart");
1947 }
1948
1949 Uint32 nodeId = 0;
1950 while(!allFailed.isclear()){
1951 nodeId = allFailed.find(nodeId + 1);
1952 allFailed.clear(nodeId);
1953 signal->theData[0] = nodeId;
1954 sendSignal(QMGR_REF, GSN_NDB_FAILCONF, signal, 1, JBB);
1955 }//for
1956
1957 return;
1958 }
1959
1960 ndbrequire(!allFailed.get(getOwnNodeId()));
1961
1962 NodeFailRep * rep = (NodeFailRep *)&signal->theData[0];
1963 rep->masterNodeId = cmasterNodeId;
1964
1965 sendSignal(DBTC_REF, GSN_NODE_FAILREP, signal,
1966 NodeFailRep::SignalLength, JBB);
1967
1968 sendSignal(DBLQH_REF, GSN_NODE_FAILREP, signal,
1969 NodeFailRep::SignalLength, JBB);
1970
1971 sendSignal(DBDIH_REF, GSN_NODE_FAILREP, signal,
1972 NodeFailRep::SignalLength, JBB);
1973
1974 sendSignal(DBDICT_REF, GSN_NODE_FAILREP, signal,
1975 NodeFailRep::SignalLength, JBB);
1976
1977 sendSignal(BACKUP_REF, GSN_NODE_FAILREP, signal,
1978 NodeFailRep::SignalLength, JBB);
1979
1980 sendSignal(SUMA_REF, GSN_NODE_FAILREP, signal,
1981 NodeFailRep::SignalLength, JBB);
1982
1983 sendSignal(QMGR_REF, GSN_NODE_FAILREP, signal,
1984 NodeFailRep::SignalLength, JBB);
1985
1986 sendSignal(DBUTIL_REF, GSN_NODE_FAILREP, signal,
1987 NodeFailRep::SignalLength, JBB);
1988
1989 sendSignal(DBTUP_REF, GSN_NODE_FAILREP, signal,
1990 NodeFailRep::SignalLength, JBB);
1991
1992 sendSignal(TSMAN_REF, GSN_NODE_FAILREP, signal,
1993 NodeFailRep::SignalLength, JBB);
1994
1995 sendSignal(LGMAN_REF, GSN_NODE_FAILREP, signal,
1996 NodeFailRep::SignalLength, JBB);
1997
1998 sendSignal(DBSPJ_REF, GSN_NODE_FAILREP, signal,
1999 NodeFailRep::SignalLength, JBB);
2000
2001 if (c_stopRec.stopReq.senderRef)
2002 {
2003 jam();
2004 switch(c_stopRec.m_state){
2005 case StopRecord::SR_WAIT_NODE_FAILURES:
2006 {
2007 jam();
2008 NdbNodeBitmask tmp;
2009 tmp.assign(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
2010 tmp.bitANDC(allFailed);
2011 tmp.copyto(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
2012
2013 if (tmp.isclear())
2014 {
2015 jam();
2016 if (c_stopRec.stopReq.senderRef != RNIL)
2017 {
2018 jam();
2019 StopConf * const stopConf = (StopConf *)&signal->theData[0];
2020 stopConf->senderData = c_stopRec.stopReq.senderData;
2021 stopConf->nodeState = (Uint32) NodeState::SL_SINGLEUSER;
2022 sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_CONF, signal,
2023 StopConf::SignalLength, JBB);
2024 }
2025
2026 c_stopRec.stopReq.senderRef = 0;
2027 WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
2028 req->senderRef = reference();
2029 req->senderData = StopRecord::SR_UNBLOCK_GCP_START_GCP;
2030 req->requestType = WaitGCPReq::UnblockStartGcp;
2031 sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
2032 WaitGCPReq::SignalLength, JBA);
2033 }
2034 break;
2035 }
2036 case StopRecord::SR_QMGR_STOP_REQ:
2037 {
2038 NdbNodeBitmask tmp;
2039 tmp.assign(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
2040 tmp.bitANDC(allFailed);
2041
2042 if (tmp.isclear())
2043 {
2044 Uint32 nodeId = allFailed.find(0);
2045 tmp.set(nodeId);
2046
2047 StopConf* conf = (StopConf*)signal->getDataPtrSend();
2048 conf->senderData = c_stopRec.stopReq.senderData;
2049 conf->nodeId = nodeId;
2050 sendSignal(reference(),
2051 GSN_STOP_CONF, signal, StopConf::SignalLength, JBB);
2052 }
2053
2054 tmp.copyto(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
2055
2056 break;
2057 }
2058 case StopRecord::SR_BLOCK_GCP_START_GCP:
2059 case StopRecord::SR_WAIT_COMPLETE_GCP:
2060 case StopRecord::SR_UNBLOCK_GCP_START_GCP:
2061 case StopRecord::SR_CLUSTER_SHUTDOWN:
2062 break;
2063 }
2064 }
2065
2066 signal->theData[0] = NDB_LE_NODE_FAILREP;
2067 signal->theData[2] = 0;
2068
2069 Uint32 nodeId = 0;
2070 while(!allFailed.isclear()){
2071 nodeId = allFailed.find(nodeId + 1);
2072 allFailed.clear(nodeId);
2073 signal->theData[1] = nodeId;
2074 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
2075 }//for
2076
2077 return;
2078 }//Ndbcntr::execNODE_FAILREP()
2079
2080 /*******************************/
2081 /* READ_NODESREQ */
2082 /*******************************/
execREAD_NODESREQ(Signal * signal)2083 void Ndbcntr::execREAD_NODESREQ(Signal* signal)
2084 {
2085 jamEntry();
2086
2087 /*----------------------------------------------------------------------*/
2088 // ANY BLOCK MAY SEND A REQUEST ABOUT NDB NODES AND VERSIONS IN THE
2089 // SYSTEM. THIS REQUEST CAN ONLY BE HANDLED IN
2090 // ABSOLUTE STARTPHASE 3 OR LATER
2091 /*----------------------------------------------------------------------*/
2092 BlockReference TuserBlockref = signal->theData[0];
2093 ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
2094
2095 /**
2096 * Prepare inactiveNodes bitmask.
2097 * The concept as such is by the way pretty useless.
2098 * It makes parallell starts more or less impossible...
2099 */
2100 NdbNodeBitmask tmp1;
2101 tmp1.bitOR(c_startedNodes);
2102 if(!getNodeState().getNodeRestartInProgress()){
2103 tmp1.bitOR(c_start.m_starting);
2104 } else {
2105 tmp1.set(getOwnNodeId());
2106 }
2107
2108 NdbNodeBitmask tmp2;
2109 tmp2.bitOR(c_allDefinedNodes);
2110 tmp2.bitANDC(tmp1);
2111 /**
2112 * Fill in return signal
2113 */
2114 tmp2.copyto(NdbNodeBitmask::Size, readNodes->inactiveNodes);
2115 c_allDefinedNodes.copyto(NdbNodeBitmask::Size, readNodes->allNodes);
2116 c_clusterNodes.copyto(NdbNodeBitmask::Size, readNodes->clusterNodes);
2117 c_startedNodes.copyto(NdbNodeBitmask::Size, readNodes->startedNodes);
2118 c_start.m_starting.copyto(NdbNodeBitmask::Size, readNodes->startingNodes);
2119
2120 readNodes->noOfNodes = c_allDefinedNodes.count();
2121 readNodes->masterNodeId = cmasterNodeId;
2122 readNodes->ndynamicId = cdynamicNodeId;
2123 if (m_cntr_start_conf)
2124 {
2125 jam();
2126 sendSignal(TuserBlockref, GSN_READ_NODESCONF, signal,
2127 ReadNodesConf::SignalLength, JBB);
2128
2129 } else {
2130 jam();
2131 signal->theData[0] = ZNOT_AVAILABLE;
2132 sendSignal(TuserBlockref, GSN_READ_NODESREF, signal, 1, JBB);
2133 }//if
2134 }//Ndbcntr::execREAD_NODESREQ()
2135
2136 /*----------------------------------------------------------------------*/
2137 // SENDS APPL_ERROR TO QMGR AND THEN SET A POINTER OUT OF BOUNDS
2138 /*----------------------------------------------------------------------*/
systemErrorLab(Signal * signal,int line)2139 void Ndbcntr::systemErrorLab(Signal* signal, int line)
2140 {
2141 progError(line, NDBD_EXIT_NDBREQUIRE); /* BUG INSERTION */
2142 return;
2143 }//Ndbcntr::systemErrorLab()
2144
2145 /*###########################################################################*/
2146 /* CNTR MASTER CREATES AND INITIALIZES A SYSTEMTABLE AT INITIALSTART */
2147 /* |-2048| # 1 00000001 | */
2148 /* | : | : | */
2149 /* | -1 | # 1 00000001 | */
2150 /* | 1 | 0 | tupleid sequence now created on first use */
2151 /* | : | : | v */
2152 /* | 2048| 0 | v */
2153 /*---------------------------------------------------------------------------*/
beginSchemaTransLab(Signal * signal)2154 void Ndbcntr::beginSchemaTransLab(Signal* signal)
2155 {
2156 c_schemaTransId = reference();
2157
2158 SchemaTransBeginReq* req =
2159 (SchemaTransBeginReq*)signal->getDataPtrSend();
2160 req->clientRef = reference();
2161 req->transId = c_schemaTransId;
2162 req->requestInfo = 0;
2163 sendSignal(DBDICT_REF, GSN_SCHEMA_TRANS_BEGIN_REQ, signal,
2164 SchemaTransBeginReq::SignalLength, JBB);
2165 }
2166
execSCHEMA_TRANS_BEGIN_CONF(Signal * signal)2167 void Ndbcntr::execSCHEMA_TRANS_BEGIN_CONF(Signal* signal)
2168 {
2169 const SchemaTransBeginConf* conf =
2170 (SchemaTransBeginConf*)signal->getDataPtr();
2171 ndbrequire(conf->transId == c_schemaTransId);
2172 c_schemaTransKey = conf->transKey;
2173
2174 createHashMap(signal, 0);
2175 }
2176
execSCHEMA_TRANS_BEGIN_REF(Signal * signal)2177 void Ndbcntr::execSCHEMA_TRANS_BEGIN_REF(Signal* signal)
2178 {
2179 ndbrequire(false);
2180 }
2181
2182 void
createHashMap(Signal * signal,Uint32 idx)2183 Ndbcntr::createHashMap(Signal* signal, Uint32 idx)
2184 {
2185 CreateHashMapReq* const req = (CreateHashMapReq*)signal->getDataPtrSend();
2186 req->clientRef = reference();
2187 req->clientData = idx;
2188 req->requestInfo = 0;
2189 req->transId = c_schemaTransId;
2190 req->transKey = c_schemaTransKey;
2191 req->buckets = 240;
2192 req->fragments = 0;
2193 sendSignal(DBDICT_REF, GSN_CREATE_HASH_MAP_REQ, signal,
2194 CreateHashMapReq::SignalLength, JBB);
2195 }
2196
2197 void
execCREATE_HASH_MAP_REF(Signal * signal)2198 Ndbcntr::execCREATE_HASH_MAP_REF(Signal* signal)
2199 {
2200 jamEntry();
2201
2202 ndbrequire(false);
2203 }
2204
2205 void
execCREATE_HASH_MAP_CONF(Signal * signal)2206 Ndbcntr::execCREATE_HASH_MAP_CONF(Signal* signal)
2207 {
2208 jamEntry();
2209 CreateHashMapConf* conf = (CreateHashMapConf*)signal->getDataPtrSend();
2210
2211 if (conf->senderData == 0)
2212 {
2213 jam();
2214 c_hashMapId = conf->objectId;
2215 c_hashMapVersion = conf->objectVersion;
2216 }
2217
2218 createSystableLab(signal, 0);
2219 }
2220
endSchemaTransLab(Signal * signal)2221 void Ndbcntr::endSchemaTransLab(Signal* signal)
2222 {
2223 SchemaTransEndReq* req =
2224 (SchemaTransEndReq*)signal->getDataPtrSend();
2225 req->clientRef = reference();
2226 req->transId = c_schemaTransId;
2227 req->requestInfo = 0;
2228 req->transKey = c_schemaTransKey;
2229 req->flags = 0;
2230 sendSignal(DBDICT_REF, GSN_SCHEMA_TRANS_END_REQ, signal,
2231 SchemaTransEndReq::SignalLength, JBB);
2232 }
2233
execSCHEMA_TRANS_END_CONF(Signal * signal)2234 void Ndbcntr::execSCHEMA_TRANS_END_CONF(Signal* signal)
2235 {
2236 c_schemaTransId = 0;
2237 c_schemaTransKey = RNIL;
2238 startInsertTransactions(signal);
2239 }
2240
execSCHEMA_TRANS_END_REF(Signal * signal)2241 void Ndbcntr::execSCHEMA_TRANS_END_REF(Signal* signal)
2242 {
2243 jamEntry();
2244 SchemaTransEndRef * ref = (SchemaTransEndRef*)signal->getDataPtr();
2245 char buf[256];
2246 BaseString::snprintf(buf, sizeof(buf),
2247 "Failed to commit schema trans, err: %u",
2248 ref->errorCode);
2249 progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
2250 ndbrequire(false);
2251 }
2252
2253 void
createDDObjects(Signal * signal,unsigned index)2254 Ndbcntr::createDDObjects(Signal * signal, unsigned index)
2255 {
2256 const ndb_mgm_configuration_iterator * p =
2257 m_ctx.m_config.getOwnConfigIterator();
2258 ndbrequire(p != 0);
2259
2260 Uint32 propPage[256];
2261 LinearWriter w(propPage, 256);
2262
2263 const ddentry* entry = &f_dd[index];
2264
2265 switch(entry->type){
2266 case DictTabInfo::LogfileGroup:
2267 case DictTabInfo::Tablespace:
2268 {
2269 jam();
2270
2271 DictFilegroupInfo::Filegroup fg; fg.init();
2272 BaseString::snprintf(fg.FilegroupName, sizeof(fg.FilegroupName),
2273 "%s", entry->name);
2274 fg.FilegroupType = entry->type;
2275 if (entry->type == DictTabInfo::LogfileGroup)
2276 {
2277 jam();
2278 fg.LF_UndoBufferSize = Uint32(entry->size);
2279 }
2280 else
2281 {
2282 jam();
2283 fg.TS_ExtentSize = Uint32(entry->size);
2284 fg.TS_LogfileGroupId = RNIL;
2285 fg.TS_LogfileGroupVersion = RNIL;
2286 }
2287
2288 SimpleProperties::UnpackStatus s;
2289 s = SimpleProperties::pack(w,
2290 &fg,
2291 DictFilegroupInfo::Mapping,
2292 DictFilegroupInfo::MappingSize, true);
2293
2294
2295 Uint32 length = w.getWordsUsed();
2296 LinearSectionPtr ptr[3];
2297 ptr[0].p = &propPage[0];
2298 ptr[0].sz = length;
2299
2300 CreateFilegroupReq * req = (CreateFilegroupReq*)signal->getDataPtrSend();
2301 req->senderRef = reference();
2302 req->senderData = index;
2303 req->objType = entry->type;
2304 req->transId = c_schemaTransId;
2305 req->transKey = c_schemaTransKey;
2306 req->requestInfo = 0;
2307 sendSignal(DBDICT_REF, GSN_CREATE_FILEGROUP_REQ, signal,
2308 CreateFilegroupReq::SignalLength, JBB, ptr, 1);
2309 return;
2310 }
2311 case DictTabInfo::Undofile:
2312 case DictTabInfo::Datafile:
2313 {
2314 jam();
2315 Uint32 propPage[256];
2316 LinearWriter w(propPage, 256);
2317 DictFilegroupInfo::File f; f.init();
2318 BaseString::snprintf(f.FileName, sizeof(f.FileName), "%s", entry->name);
2319 f.FileType = entry->type;
2320 f.FilegroupId = RNIL;
2321 f.FilegroupVersion = RNIL;
2322 f.FileSizeHi = Uint32(entry->size >> 32);
2323 f.FileSizeLo = Uint32(entry->size);
2324
2325 SimpleProperties::UnpackStatus s;
2326 s = SimpleProperties::pack(w,
2327 &f,
2328 DictFilegroupInfo::FileMapping,
2329 DictFilegroupInfo::FileMappingSize, true);
2330
2331 Uint32 length = w.getWordsUsed();
2332 LinearSectionPtr ptr[3];
2333 ptr[0].p = &propPage[0];
2334 ptr[0].sz = length;
2335
2336 CreateFileReq * req = (CreateFileReq*)signal->getDataPtrSend();
2337 req->senderRef = reference();
2338 req->senderData = index;
2339 req->objType = entry->type;
2340 req->transId = c_schemaTransId;
2341 req->transKey = c_schemaTransKey;
2342 req->requestInfo = CreateFileReq::ForceCreateFile;
2343 sendSignal(DBDICT_REF, GSN_CREATE_FILE_REQ, signal,
2344 CreateFileReq::SignalLength, JBB, ptr, 1);
2345 return;
2346 }
2347 default:
2348 break;
2349 }
2350
2351 endSchemaTransLab(signal);
2352 }
2353
2354 void
execCREATE_FILEGROUP_REF(Signal * signal)2355 Ndbcntr::execCREATE_FILEGROUP_REF(Signal* signal)
2356 {
2357 jamEntry();
2358 CreateFilegroupRef* ref = (CreateFilegroupRef*)signal->getDataPtr();
2359 char buf[1024];
2360
2361 const ddentry* entry = &f_dd[ref->senderData];
2362
2363 if (entry->type == DictTabInfo::LogfileGroup)
2364 {
2365 BaseString::snprintf(buf, sizeof(buf), "create logfilegroup err %u",
2366 ref->errorCode);
2367 }
2368 else if (entry->type == DictTabInfo::Tablespace)
2369 {
2370 BaseString::snprintf(buf, sizeof(buf), "create tablespace err %u",
2371 ref->errorCode);
2372 }
2373 progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
2374 }
2375
2376 void
execCREATE_FILEGROUP_CONF(Signal * signal)2377 Ndbcntr::execCREATE_FILEGROUP_CONF(Signal* signal)
2378 {
2379 jamEntry();
2380 CreateFilegroupConf* conf = (CreateFilegroupConf*)signal->getDataPtr();
2381 createDDObjects(signal, conf->senderData + 1);
2382 }
2383
2384 void
execCREATE_FILE_REF(Signal * signal)2385 Ndbcntr::execCREATE_FILE_REF(Signal* signal)
2386 {
2387 jamEntry();
2388 CreateFileRef* ref = (CreateFileRef*)signal->getDataPtr();
2389 char buf[1024];
2390
2391 const ddentry* entry = &f_dd[ref->senderData];
2392
2393 if (entry->type == DictTabInfo::Undofile)
2394 {
2395 BaseString::snprintf(buf, sizeof(buf), "create undofile %s err %u",
2396 entry->name,
2397 ref->errorCode);
2398 }
2399 else if (entry->type == DictTabInfo::Datafile)
2400 {
2401 BaseString::snprintf(buf, sizeof(buf), "create datafile %s err %u",
2402 entry->name,
2403 ref->errorCode);
2404 }
2405 progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
2406 }
2407
2408 void
execCREATE_FILE_CONF(Signal * signal)2409 Ndbcntr::execCREATE_FILE_CONF(Signal* signal)
2410 {
2411 jamEntry();
2412 CreateFileConf* conf = (CreateFileConf*)signal->getDataPtr();
2413 createDDObjects(signal, conf->senderData + 1);
2414 }
2415
createSystableLab(Signal * signal,unsigned index)2416 void Ndbcntr::createSystableLab(Signal* signal, unsigned index)
2417 {
2418 if (index >= g_sysTableCount) {
2419 ndbassert(index == g_sysTableCount);
2420 createDDObjects(signal, 0);
2421 return;
2422 }
2423 const SysTable& table = *g_sysTableList[index];
2424 Uint32 propPage[256];
2425 LinearWriter w(propPage, 256);
2426
2427 // XXX remove commented-out lines later
2428
2429 w.first();
2430 w.add(DictTabInfo::TableName, table.name);
2431 w.add(DictTabInfo::TableLoggedFlag, table.tableLoggedFlag);
2432 //w.add(DictTabInfo::TableKValue, 6);
2433 //w.add(DictTabInfo::MinLoadFactor, 70);
2434 //w.add(DictTabInfo::MaxLoadFactor, 80);
2435 w.add(DictTabInfo::FragmentTypeVal, (Uint32)table.fragmentType);
2436 //w.add(DictTabInfo::NoOfKeyAttr, 1);
2437 w.add(DictTabInfo::NoOfAttributes, (Uint32)table.columnCount);
2438 //w.add(DictTabInfo::NoOfNullable, (Uint32)0);
2439 //w.add(DictTabInfo::NoOfVariable, (Uint32)0);
2440 //w.add(DictTabInfo::KeyLength, 1);
2441 w.add(DictTabInfo::TableTypeVal, (Uint32)table.tableType);
2442 w.add(DictTabInfo::SingleUserMode, (Uint32)NDB_SUM_READ_WRITE);
2443 w.add(DictTabInfo::HashMapObjectId, c_hashMapId);
2444 w.add(DictTabInfo::HashMapVersion, c_hashMapVersion);
2445
2446 for (unsigned i = 0; i < table.columnCount; i++) {
2447 const SysColumn& column = table.columnList[i];
2448 ndbassert(column.pos == i);
2449 w.add(DictTabInfo::AttributeName, column.name);
2450 w.add(DictTabInfo::AttributeId, (Uint32)i);
2451 w.add(DictTabInfo::AttributeKeyFlag, (Uint32)column.keyFlag);
2452 w.add(DictTabInfo::AttributeStorageType,
2453 (Uint32)NDB_STORAGETYPE_MEMORY);
2454 switch(column.type){
2455 case DictTabInfo::ExtVarbinary:
2456 jam();
2457 w.add(DictTabInfo::AttributeArrayType,
2458 (Uint32)NDB_ARRAYTYPE_SHORT_VAR);
2459 break;
2460 case DictTabInfo::ExtLongvarbinary:
2461 jam();
2462 w.add(DictTabInfo::AttributeArrayType,
2463 (Uint32)NDB_ARRAYTYPE_MEDIUM_VAR);
2464 break;
2465 default:
2466 jam();
2467 w.add(DictTabInfo::AttributeArrayType,
2468 (Uint32)NDB_ARRAYTYPE_FIXED);
2469 break;
2470 }
2471 w.add(DictTabInfo::AttributeNullableFlag, (Uint32)column.nullable);
2472 w.add(DictTabInfo::AttributeExtType, (Uint32)column.type);
2473 w.add(DictTabInfo::AttributeExtLength, (Uint32)column.length);
2474 w.add(DictTabInfo::AttributeEnd, (Uint32)true);
2475 }
2476 w.add(DictTabInfo::TableEnd, (Uint32)true);
2477
2478 Uint32 length = w.getWordsUsed();
2479 LinearSectionPtr ptr[3];
2480 ptr[0].p = &propPage[0];
2481 ptr[0].sz = length;
2482
2483 CreateTableReq* const req = (CreateTableReq*)signal->getDataPtrSend();
2484 req->clientRef = reference();
2485 req->clientData = index;
2486 req->requestInfo = 0;
2487 req->transId = c_schemaTransId;
2488 req->transKey = c_schemaTransKey;
2489 sendSignal(DBDICT_REF, GSN_CREATE_TABLE_REQ, signal,
2490 CreateTableReq::SignalLength, JBB, ptr, 1);
2491 return;
2492 }//Ndbcntr::createSystableLab()
2493
execCREATE_TABLE_REF(Signal * signal)2494 void Ndbcntr::execCREATE_TABLE_REF(Signal* signal)
2495 {
2496 jamEntry();
2497 progError(__LINE__,NDBD_EXIT_NDBREQUIRE, "CREATE_TABLE_REF");
2498 return;
2499 }//Ndbcntr::execDICTTABREF()
2500
execCREATE_TABLE_CONF(Signal * signal)2501 void Ndbcntr::execCREATE_TABLE_CONF(Signal* signal)
2502 {
2503 jamEntry();
2504 const CreateTableConf* conf = (const CreateTableConf*)signal->getDataPtr();
2505 //csystabId = conf->tableId;
2506 ndbrequire(conf->transId == c_schemaTransId);
2507 ndbrequire(conf->senderData < g_sysTableCount);
2508 const SysTable& table = *g_sysTableList[conf->senderData];
2509 table.tableId = conf->tableId;
2510 table.tableVersion = conf->tableVersion;
2511 createSystableLab(signal, conf->senderData + 1);
2512 //startInsertTransactions(signal);
2513 return;
2514 }//Ndbcntr::execDICTTABCONF()
2515
2516 /*******************************/
2517 /* DICTRELEASECONF */
2518 /*******************************/
startInsertTransactions(Signal * signal)2519 void Ndbcntr::startInsertTransactions(Signal* signal)
2520 {
2521 jamEntry();
2522
2523 ckey = 1;
2524 ctransidPhase = ZTRUE;
2525 signal->theData[0] = 0;
2526 signal->theData[1] = reference();
2527 sendSignal(DBTC_REF, GSN_TCSEIZEREQ, signal, 2, JBB);
2528 return;
2529 }//Ndbcntr::startInsertTransactions()
2530
2531 /*******************************/
2532 /* TCSEIZECONF */
2533 /*******************************/
execTCSEIZECONF(Signal * signal)2534 void Ndbcntr::execTCSEIZECONF(Signal* signal)
2535 {
2536 jamEntry();
2537 ctcConnectionP = signal->theData[1];
2538 ctcReference = signal->theData[2];
2539 crSystab7Lab(signal);
2540 return;
2541 }//Ndbcntr::execTCSEIZECONF()
2542
2543 const unsigned int RowsPerCommit = 16;
crSystab7Lab(Signal * signal)2544 void Ndbcntr::crSystab7Lab(Signal* signal)
2545 {
2546 UintR tkey;
2547 UintR Tmp;
2548
2549 TcKeyReq * const tcKeyReq = (TcKeyReq *)&signal->theData[0];
2550
2551 UintR reqInfo_Start = 0;
2552 tcKeyReq->setOperationType(reqInfo_Start, ZINSERT); // Insert
2553 tcKeyReq->setKeyLength (reqInfo_Start, 1);
2554 tcKeyReq->setAIInTcKeyReq (reqInfo_Start, 5);
2555 tcKeyReq->setAbortOption (reqInfo_Start, TcKeyReq::AbortOnError);
2556
2557 /* KEY LENGTH = 1, ATTRINFO LENGTH IN TCKEYREQ = 5 */
2558 cresponses = 0;
2559 const UintR guard0 = ckey + (RowsPerCommit - 1);
2560 for (Tmp = ckey; Tmp <= guard0; Tmp++) {
2561 UintR reqInfo = reqInfo_Start;
2562 if (Tmp == ckey) { // First iteration, Set start flag
2563 jam();
2564 tcKeyReq->setStartFlag(reqInfo, 1);
2565 } //if
2566 if (Tmp == guard0) { // Last iteration, Set commit flag
2567 jam();
2568 tcKeyReq->setCommitFlag(reqInfo, 1);
2569 tcKeyReq->setExecuteFlag(reqInfo, 1);
2570 } //if
2571 if (ctransidPhase == ZTRUE) {
2572 jam();
2573 tkey = 0;
2574 tkey = tkey - Tmp;
2575 } else {
2576 jam();
2577 tkey = Tmp;
2578 }//if
2579
2580 tcKeyReq->apiConnectPtr = ctcConnectionP;
2581 tcKeyReq->attrLen = 5;
2582 tcKeyReq->tableId = g_sysTable_SYSTAB_0.tableId;
2583 tcKeyReq->requestInfo = reqInfo;
2584 tcKeyReq->tableSchemaVersion = g_sysTable_SYSTAB_0.tableVersion;
2585 tcKeyReq->transId1 = 0;
2586 tcKeyReq->transId2 = ckey;
2587
2588 //-------------------------------------------------------------
2589 // There is no optional part in this TCKEYREQ. There is one
2590 // key word and five ATTRINFO words.
2591 //-------------------------------------------------------------
2592 Uint32* tKeyDataPtr = &tcKeyReq->scanInfo;
2593 Uint32* tAIDataPtr = &tKeyDataPtr[1];
2594
2595 tKeyDataPtr[0] = tkey;
2596
2597 AttributeHeader::init(&tAIDataPtr[0], 0, 1 << 2);
2598 tAIDataPtr[1] = tkey;
2599 AttributeHeader::init(&tAIDataPtr[2], 1, 2 << 2);
2600 tAIDataPtr[3] = (tkey << 16);
2601 tAIDataPtr[4] = 1;
2602 sendSignal(ctcReference, GSN_TCKEYREQ, signal,
2603 TcKeyReq::StaticLength + 6, JBB);
2604 }//for
2605 ckey = ckey + RowsPerCommit;
2606 return;
2607 }//Ndbcntr::crSystab7Lab()
2608
2609 /*******************************/
2610 /* TCKEYCONF09 */
2611 /*******************************/
execTCKEYCONF(Signal * signal)2612 void Ndbcntr::execTCKEYCONF(Signal* signal)
2613 {
2614 const TcKeyConf * const keyConf = (TcKeyConf *)&signal->theData[0];
2615
2616 jamEntry();
2617 cgciSystab = keyConf->gci_hi;
2618 UintR confInfo = keyConf->confInfo;
2619
2620 if (TcKeyConf::getMarkerFlag(confInfo)){
2621 Uint32 transId1 = keyConf->transId1;
2622 Uint32 transId2 = keyConf->transId2;
2623 signal->theData[0] = transId1;
2624 signal->theData[1] = transId2;
2625 sendSignal(ctcReference, GSN_TC_COMMIT_ACK, signal, 2, JBB);
2626 }//if
2627
2628 cresponses = cresponses + TcKeyConf::getNoOfOperations(confInfo);
2629 if (TcKeyConf::getCommitFlag(confInfo)){
2630 jam();
2631 ndbrequire(cresponses == RowsPerCommit);
2632
2633 crSystab8Lab(signal);
2634 return;
2635 }
2636 return;
2637 }//Ndbcntr::tckeyConfLab()
2638
crSystab8Lab(Signal * signal)2639 void Ndbcntr::crSystab8Lab(Signal* signal)
2640 {
2641 if (ckey < ZSIZE_SYSTAB) {
2642 jam();
2643 crSystab7Lab(signal);
2644 return;
2645 } else if (ctransidPhase == ZTRUE) {
2646 jam();
2647 ckey = 1;
2648 ctransidPhase = ZFALSE;
2649 // skip 2nd loop - tupleid sequence now created on first use
2650 }//if
2651 signal->theData[0] = ctcConnectionP;
2652 signal->theData[1] = reference();
2653 signal->theData[2] = 0;
2654 sendSignal(ctcReference, GSN_TCRELEASEREQ, signal, 2, JBB);
2655 return;
2656 }//Ndbcntr::crSystab8Lab()
2657
2658 /*******************************/
2659 /* TCRELEASECONF */
2660 /*******************************/
execTCRELEASECONF(Signal * signal)2661 void Ndbcntr::execTCRELEASECONF(Signal* signal)
2662 {
2663 jamEntry();
2664 waitpoint52Lab(signal);
2665 return;
2666 }//Ndbcntr::execTCRELEASECONF()
2667
crSystab9Lab(Signal * signal)2668 void Ndbcntr::crSystab9Lab(Signal* signal)
2669 {
2670 signal->theData[0] = 0; // user ptr
2671 signal->theData[1] = reference();
2672 signal->theData[2] = 0;
2673 sendSignalWithDelay(DBDIH_REF, GSN_GETGCIREQ, signal, 100, 3);
2674 return;
2675 }//Ndbcntr::crSystab9Lab()
2676
2677 /*******************************/
2678 /* GETGCICONF */
2679 /*******************************/
execGETGCICONF(Signal * signal)2680 void Ndbcntr::execGETGCICONF(Signal* signal)
2681 {
2682 jamEntry();
2683
2684 #ifndef NO_GCP
2685 if (signal->theData[1] < cgciSystab) {
2686 jam();
2687 /*--------------------------------------*/
2688 /* MAKE SURE THAT THE SYSTABLE IS */
2689 /* NOW SAFE ON DISK */
2690 /*--------------------------------------*/
2691 crSystab9Lab(signal);
2692 return;
2693 }//if
2694 #endif
2695 waitpoint52Lab(signal);
2696 return;
2697 }//Ndbcntr::execGETGCICONF()
2698
execTCKEYREF(Signal * signal)2699 void Ndbcntr::execTCKEYREF(Signal* signal)
2700 {
2701 jamEntry();
2702 systemErrorLab(signal, __LINE__);
2703 return;
2704 }//Ndbcntr::execTCKEYREF()
2705
execTCROLLBACKREP(Signal * signal)2706 void Ndbcntr::execTCROLLBACKREP(Signal* signal)
2707 {
2708 jamEntry();
2709 systemErrorLab(signal, __LINE__);
2710 return;
2711 }//Ndbcntr::execTCROLLBACKREP()
2712
execTCRELEASEREF(Signal * signal)2713 void Ndbcntr::execTCRELEASEREF(Signal* signal)
2714 {
2715 jamEntry();
2716 systemErrorLab(signal, __LINE__);
2717 return;
2718 }//Ndbcntr::execTCRELEASEREF()
2719
execTCSEIZEREF(Signal * signal)2720 void Ndbcntr::execTCSEIZEREF(Signal* signal)
2721 {
2722 jamEntry();
2723 systemErrorLab(signal, __LINE__);
2724 return;
2725 }//Ndbcntr::execTCSEIZEREF()
2726
2727
2728 /*---------------------------------------------------------------------------*/
2729 /*INITIALIZE VARIABLES AND RECORDS */
2730 /*---------------------------------------------------------------------------*/
initData(Signal * signal)2731 void Ndbcntr::initData(Signal* signal)
2732 {
2733 c_start.reset();
2734 cmasterNodeId = 0;
2735 cnoStartNodes = 0;
2736 cnoWaitrep = 0;
2737 }//Ndbcntr::initData()
2738
2739
2740 /*---------------------------------------------------------------------------*/
2741 /*RESET VARIABLES USED DURING THE START */
2742 /*---------------------------------------------------------------------------*/
resetStartVariables(Signal * signal)2743 void Ndbcntr::resetStartVariables(Signal* signal)
2744 {
2745 cnoStartNodes = 0;
2746 cnoWaitrep6 = cnoWaitrep7 = 0;
2747 }//Ndbcntr::resetStartVariables()
2748
2749
2750 /*---------------------------------------------------------------------------*/
2751 // SEND THE SIGNAL
2752 // INPUT CNDB_BLOCKS_COUNT
2753 /*---------------------------------------------------------------------------*/
sendNdbSttor(Signal * signal)2754 void Ndbcntr::sendNdbSttor(Signal* signal)
2755 {
2756 NdbBlocksRecPtr ndbBlocksPtr;
2757
2758 ndbBlocksPtr.i = cndbBlocksCount;
2759 ptrCheckGuard(ndbBlocksPtr, ZSIZE_NDB_BLOCKS_REC, ndbBlocksRec);
2760
2761 NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend();
2762 req->senderRef = reference();
2763 req->nodeId = getOwnNodeId();
2764 req->internalStartPhase = cinternalStartphase;
2765 req->typeOfStart = ctypeOfStart;
2766 req->masterNodeId = cmasterNodeId;
2767
2768 for (int i = 0; i < 16; i++) {
2769 // Garbage
2770 req->config[i] = 0x88776655;
2771 //cfgBlockPtr.p->cfgData[i];
2772 }
2773
2774 //#define MAX_STARTPHASE 2
2775 #ifdef TRACE_STTOR
2776 ndbout_c("sending NDB_STTOR(%d) to %s",
2777 cinternalStartphase,
2778 getBlockName( refToBlock(ndbBlocksPtr.p->blockref)));
2779 #endif
2780 if (refToBlock(ndbBlocksPtr.p->blockref) == DBDIH)
2781 req->typeOfStart = cdihStartType;
2782 sendSignal(ndbBlocksPtr.p->blockref, GSN_NDB_STTOR, signal, 22, JBB);
2783 cndbBlocksCount++;
2784 }//Ndbcntr::sendNdbSttor()
2785
2786 /*---------------------------------------------------------------------------*/
2787 // JUST SEND THE SIGNAL
2788 /*---------------------------------------------------------------------------*/
sendSttorry(Signal * signal)2789 void Ndbcntr::sendSttorry(Signal* signal)
2790 {
2791 signal->theData[3] = ZSTART_PHASE_1;
2792 signal->theData[4] = ZSTART_PHASE_2;
2793 signal->theData[5] = ZSTART_PHASE_3;
2794 signal->theData[6] = ZSTART_PHASE_4;
2795 signal->theData[7] = ZSTART_PHASE_5;
2796 signal->theData[8] = ZSTART_PHASE_6;
2797 // skip simulated phase 7
2798 signal->theData[9] = ZSTART_PHASE_8;
2799 signal->theData[10] = ZSTART_PHASE_9;
2800 signal->theData[11] = ZSTART_PHASE_END;
2801 sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 12, JBB);
2802 }//Ndbcntr::sendSttorry()
2803
2804 void
execDUMP_STATE_ORD(Signal * signal)2805 Ndbcntr::execDUMP_STATE_ORD(Signal* signal)
2806 {
2807 DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
2808 Uint32 arg = dumpState->args[0];
2809
2810 if(arg == 13){
2811 infoEvent("Cntr: cstartPhase = %d, cinternalStartphase = %d, block = %d",
2812 cstartPhase, cinternalStartphase, cndbBlocksCount);
2813 infoEvent("Cntr: cmasterNodeId = %d", cmasterNodeId);
2814 }
2815
2816 if (arg == DumpStateOrd::NdbcntrTestStopOnError){
2817 if (m_ctx.m_config.stopOnError() == true)
2818 ((Configuration&)m_ctx.m_config).stopOnError(false);
2819
2820 const BlockReference tblockref = calcNdbCntrBlockRef(getOwnNodeId());
2821
2822 SystemError * const sysErr = (SystemError*)&signal->theData[0];
2823 sysErr->errorCode = SystemError::TestStopOnError;
2824 sysErr->errorRef = reference();
2825 sendSignal(tblockref, GSN_SYSTEM_ERROR, signal,
2826 SystemError::SignalLength, JBA);
2827 }
2828
2829 if (arg == DumpStateOrd::NdbcntrStopNodes)
2830 {
2831 NdbNodeBitmask mask;
2832 for(Uint32 i = 1; i<signal->getLength(); i++)
2833 mask.set(signal->theData[i]);
2834
2835 StopReq* req = (StopReq*)signal->getDataPtrSend();
2836 req->senderRef = RNIL;
2837 req->senderData = 123;
2838 req->requestInfo = 0;
2839 req->singleuser = 0;
2840 req->singleUserApi = 0;
2841 mask.copyto(NdbNodeBitmask::Size, req->nodes);
2842 StopReq::setPerformRestart(req->requestInfo, 1);
2843 StopReq::setNoStart(req->requestInfo, 1);
2844 StopReq::setStopNodes(req->requestInfo, 1);
2845 StopReq::setStopAbort(req->requestInfo, 1);
2846
2847 sendSignal(reference(), GSN_STOP_REQ, signal,
2848 StopReq::SignalLength, JBB);
2849 return;
2850 }
2851
2852 if (arg == 71)
2853 {
2854 #ifdef ERROR_INSERT
2855 if (signal->getLength() == 2)
2856 {
2857 c_error_insert_extra = signal->theData[1];
2858 SET_ERROR_INSERT_VALUE(1002);
2859 }
2860 else if (ERROR_INSERTED(1002))
2861 {
2862 CLEAR_ERROR_INSERT_VALUE;
2863 }
2864 #endif
2865 }
2866
2867 }//Ndbcntr::execDUMP_STATE_ORD()
2868
updateNodeState(Signal * signal,const NodeState & newState) const2869 void Ndbcntr::updateNodeState(Signal* signal, const NodeState& newState) const{
2870 NodeStateRep * const stateRep = (NodeStateRep *)&signal->theData[0];
2871
2872 if (newState.startLevel == NodeState::SL_STARTED)
2873 {
2874 CRASH_INSERTION(1000);
2875 }
2876
2877 stateRep->nodeState = newState;
2878 stateRep->nodeState.masterNodeId = cmasterNodeId;
2879 stateRep->nodeState.setNodeGroup(c_nodeGroup);
2880
2881 for(Uint32 i = 0; i<ALL_BLOCKS_SZ; i++){
2882 sendSignal(ALL_BLOCKS[i].Ref, GSN_NODE_STATE_REP, signal,
2883 NodeStateRep::SignalLength, JBB);
2884 }
2885 }
2886
2887 void
execRESUME_REQ(Signal * signal)2888 Ndbcntr::execRESUME_REQ(Signal* signal){
2889 //ResumeReq * const req = (ResumeReq *)&signal->theData[0];
2890 //ResumeRef * const ref = (ResumeRef *)&signal->theData[0];
2891
2892 jamEntry();
2893
2894 signal->theData[0] = NDB_LE_SingleUser;
2895 signal->theData[1] = 2;
2896 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
2897
2898 //Uint32 senderData = req->senderData;
2899 //BlockReference senderRef = req->senderRef;
2900 NodeState newState(NodeState::SL_STARTED);
2901 updateNodeState(signal, newState);
2902 c_stopRec.stopReq.senderRef=0;
2903 }
2904
2905 void
execSTOP_REQ(Signal * signal)2906 Ndbcntr::execSTOP_REQ(Signal* signal){
2907 StopReq * const req = (StopReq *)&signal->theData[0];
2908 StopRef * const ref = (StopRef *)&signal->theData[0];
2909 Uint32 singleuser = req->singleuser;
2910 jamEntry();
2911 Uint32 senderData = req->senderData;
2912 BlockReference senderRef = req->senderRef;
2913 bool abort = StopReq::getStopAbort(req->requestInfo);
2914 bool stopnodes = StopReq::getStopNodes(req->requestInfo);
2915
2916 if(!singleuser &&
2917 (getNodeState().startLevel < NodeState::SL_STARTED ||
2918 (abort && !stopnodes)))
2919 {
2920 /**
2921 * Node is not started yet
2922 *
2923 * So stop it quickly
2924 */
2925 jam();
2926 const Uint32 reqInfo = req->requestInfo;
2927 if(StopReq::getPerformRestart(reqInfo)){
2928 jam();
2929 StartOrd * startOrd = (StartOrd *)&signal->theData[0];
2930 startOrd->restartInfo = reqInfo;
2931 sendSignal(CMVMI_REF, GSN_START_ORD, signal, 1, JBA);
2932 } else {
2933 jam();
2934 sendSignal(CMVMI_REF, GSN_STOP_ORD, signal, 1, JBA);
2935 }
2936 return;
2937 }
2938
2939 if(c_stopRec.stopReq.senderRef != 0 ||
2940 (cmasterNodeId == getOwnNodeId() && !c_start.m_starting.isclear()))
2941 {
2942 /**
2943 * Requested a system shutdown
2944 */
2945 if(!singleuser && StopReq::getSystemStop(req->requestInfo)){
2946 jam();
2947 sendSignalWithDelay(reference(), GSN_STOP_REQ, signal, 100,
2948 StopReq::SignalLength);
2949 return;
2950 }
2951
2952 /**
2953 * Requested a node shutdown
2954 */
2955 if(c_stopRec.stopReq.senderRef &&
2956 StopReq::getSystemStop(c_stopRec.stopReq.requestInfo))
2957 ref->errorCode = StopRef::SystemShutdownInProgress;
2958 else
2959 ref->errorCode = StopRef::NodeShutdownInProgress;
2960 ref->senderData = senderData;
2961 ref->masterNodeId = cmasterNodeId;
2962
2963 if (senderRef != RNIL)
2964 sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
2965 return;
2966 }
2967
2968 if (stopnodes && !abort)
2969 {
2970 jam();
2971 ref->errorCode = StopRef::UnsupportedNodeShutdown;
2972 ref->senderData = senderData;
2973 ref->masterNodeId = cmasterNodeId;
2974 if (senderRef != RNIL)
2975 sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
2976 return;
2977 }
2978
2979 if (stopnodes && cmasterNodeId != getOwnNodeId())
2980 {
2981 jam();
2982 ref->errorCode = StopRef::MultiNodeShutdownNotMaster;
2983 ref->senderData = senderData;
2984 ref->masterNodeId = cmasterNodeId;
2985 if (senderRef != RNIL)
2986 sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
2987 return;
2988 }
2989
2990 c_stopRec.stopReq = * req;
2991 c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
2992
2993 if (stopnodes)
2994 {
2995 jam();
2996
2997 if(!c_stopRec.checkNodeFail(signal))
2998 {
2999 jam();
3000 return;
3001 }
3002
3003 char buf[100];
3004 NdbNodeBitmask mask;
3005 mask.assign(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
3006 infoEvent("Initiating shutdown abort of %s", mask.getText(buf));
3007 ndbout_c("Initiating shutdown abort of %s", mask.getText(buf));
3008
3009 WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
3010 req->senderRef = reference();
3011 req->senderData = StopRecord::SR_BLOCK_GCP_START_GCP;
3012 req->requestType = WaitGCPReq::BlockStartGcp;
3013 sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
3014 WaitGCPReq::SignalLength, JBB);
3015 return;
3016 }
3017 else if(!singleuser)
3018 {
3019 if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo))
3020 {
3021 jam();
3022 if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo))
3023 {
3024 ((Configuration&)m_ctx.m_config).stopOnError(false);
3025 }
3026 }
3027 if(!c_stopRec.checkNodeFail(signal))
3028 {
3029 jam();
3030 return;
3031 }
3032 signal->theData[0] = NDB_LE_NDBStopStarted;
3033 signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0;
3034 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
3035 }
3036 else
3037 {
3038 signal->theData[0] = NDB_LE_SingleUser;
3039 signal->theData[1] = 0;
3040 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
3041 }
3042
3043 NodeState newState(NodeState::SL_STOPPING_1,
3044 StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
3045
3046 if(singleuser) {
3047 newState.setSingleUser(true);
3048 newState.setSingleUserApi(c_stopRec.stopReq.singleUserApi);
3049 }
3050 updateNodeState(signal, newState);
3051 signal->theData[0] = ZSHUTDOWN;
3052 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
3053 }
3054
3055 void
checkTimeout(Signal * signal)3056 Ndbcntr::StopRecord::checkTimeout(Signal* signal){
3057 jamEntry();
3058
3059 if(!cntr.getNodeState().getSingleUserMode())
3060 if(!checkNodeFail(signal)){
3061 jam();
3062 return;
3063 }
3064
3065 switch(cntr.getNodeState().startLevel){
3066 case NodeState::SL_STOPPING_1:
3067 checkApiTimeout(signal);
3068 break;
3069 case NodeState::SL_STOPPING_2:
3070 checkTcTimeout(signal);
3071 break;
3072 case NodeState::SL_STOPPING_3:
3073 checkLqhTimeout_1(signal);
3074 break;
3075 case NodeState::SL_STOPPING_4:
3076 checkLqhTimeout_2(signal);
3077 break;
3078 case NodeState::SL_SINGLEUSER:
3079 break;
3080 default:
3081 ndbrequire(false);
3082 }
3083 }
3084
3085 bool
checkNodeFail(Signal * signal)3086 Ndbcntr::StopRecord::checkNodeFail(Signal* signal){
3087 jam();
3088 if(StopReq::getSystemStop(stopReq.requestInfo)){
3089 jam();
3090 return true;
3091 }
3092
3093 /**
3094 * Check if I can survive me stopping
3095 */
3096 NdbNodeBitmask ndbMask;
3097 ndbMask.assign(cntr.c_startedNodes);
3098
3099 if (StopReq::getStopNodes(stopReq.requestInfo))
3100 {
3101 NdbNodeBitmask tmp;
3102 tmp.assign(NdbNodeBitmask::Size, stopReq.nodes);
3103
3104 NdbNodeBitmask ndbStopNodes;
3105 ndbStopNodes.assign(NdbNodeBitmask::Size, stopReq.nodes);
3106 ndbStopNodes.bitAND(ndbMask);
3107 ndbStopNodes.copyto(NdbNodeBitmask::Size, stopReq.nodes);
3108
3109 ndbMask.bitANDC(tmp);
3110
3111 bool allNodesStopped = true;
3112 int i ;
3113 for( i = 0; i < (int) NdbNodeBitmask::Size; i++ ){
3114 if ( stopReq.nodes[i] != 0 ){
3115 allNodesStopped = false;
3116 break;
3117 }
3118 }
3119
3120 if ( allNodesStopped ) {
3121 StopConf * const stopConf = (StopConf *)&signal->theData[0];
3122 stopConf->senderData = stopReq.senderData;
3123 stopConf->nodeState = (Uint32) NodeState::SL_NOTHING;
3124 cntr.sendSignal(stopReq.senderRef, GSN_STOP_CONF, signal,
3125 StopConf::SignalLength, JBB);
3126 stopReq.senderRef = 0;
3127 return false;
3128 }
3129
3130 }
3131 else
3132 {
3133 ndbMask.clear(cntr.getOwnNodeId());
3134 }
3135
3136 CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
3137 sd->blockRef = cntr.reference();
3138 sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck;
3139 sd->mask = ndbMask;
3140 cntr.EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
3141 CheckNodeGroups::SignalLength);
3142 jamEntry();
3143 switch (sd->output) {
3144 case CheckNodeGroups::Win:
3145 case CheckNodeGroups::Partitioning:
3146 return true;
3147 break;
3148 }
3149
3150 StopRef * const ref = (StopRef *)&signal->theData[0];
3151
3152 ref->senderData = stopReq.senderData;
3153 ref->errorCode = StopRef::NodeShutdownWouldCauseSystemCrash;
3154 ref->masterNodeId = cntr.cmasterNodeId;
3155
3156 const BlockReference bref = stopReq.senderRef;
3157 if (bref != RNIL)
3158 cntr.sendSignal(bref, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
3159
3160 stopReq.senderRef = 0;
3161
3162 if (cntr.getNodeState().startLevel != NodeState::SL_SINGLEUSER)
3163 {
3164 NodeState newState(NodeState::SL_STARTED);
3165 cntr.updateNodeState(signal, newState);
3166 }
3167
3168 signal->theData[0] = NDB_LE_NDBStopAborted;
3169 cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
3170
3171 return false;
3172 }
3173
3174 void
checkApiTimeout(Signal * signal)3175 Ndbcntr::StopRecord::checkApiTimeout(Signal* signal){
3176 const Int32 timeout = stopReq.apiTimeout;
3177 const NDB_TICKS alarm = stopInitiatedTime + (NDB_TICKS)timeout;
3178 const NDB_TICKS now = NdbTick_CurrentMillisecond();
3179 if((timeout >= 0 && now >= alarm)){
3180 // || checkWithApiInSomeMagicWay)
3181 jam();
3182 NodeState newState(NodeState::SL_STOPPING_2,
3183 StopReq::getSystemStop(stopReq.requestInfo));
3184 if(stopReq.singleuser) {
3185 newState.setSingleUser(true);
3186 newState.setSingleUserApi(stopReq.singleUserApi);
3187 }
3188 cntr.updateNodeState(signal, newState);
3189
3190 stopInitiatedTime = now;
3191 }
3192
3193 signal->theData[0] = ZSHUTDOWN;
3194 cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
3195 }
3196
3197 void
checkTcTimeout(Signal * signal)3198 Ndbcntr::StopRecord::checkTcTimeout(Signal* signal){
3199 const Int32 timeout = stopReq.transactionTimeout;
3200 const NDB_TICKS alarm = stopInitiatedTime + (NDB_TICKS)timeout;
3201 const NDB_TICKS now = NdbTick_CurrentMillisecond();
3202 if((timeout >= 0 && now >= alarm)){
3203 // || checkWithTcInSomeMagicWay)
3204 jam();
3205 if(stopReq.getSystemStop(stopReq.requestInfo) || stopReq.singleuser){
3206 jam();
3207 if(stopReq.singleuser)
3208 {
3209 jam();
3210 AbortAllReq * req = (AbortAllReq*)&signal->theData[0];
3211 req->senderRef = cntr.reference();
3212 req->senderData = 12;
3213 cntr.sendSignal(DBTC_REF, GSN_ABORT_ALL_REQ, signal,
3214 AbortAllReq::SignalLength, JBB);
3215 }
3216 else
3217 {
3218 WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
3219 req->senderRef = cntr.reference();
3220 req->senderData = StopRecord::SR_CLUSTER_SHUTDOWN;
3221 req->requestType = WaitGCPReq::CompleteForceStart;
3222 cntr.sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
3223 WaitGCPReq::SignalLength, JBB);
3224 }
3225 } else {
3226 jam();
3227 StopPermReq * req = (StopPermReq*)&signal->theData[0];
3228 req->senderRef = cntr.reference();
3229 req->senderData = 12;
3230 cntr.sendSignal(DBDIH_REF, GSN_STOP_PERM_REQ, signal,
3231 StopPermReq::SignalLength, JBB);
3232 }
3233 return;
3234 }
3235 signal->theData[0] = ZSHUTDOWN;
3236 cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
3237 }
3238
execSTOP_PERM_REF(Signal * signal)3239 void Ndbcntr::execSTOP_PERM_REF(Signal* signal){
3240 //StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
3241
3242 jamEntry();
3243
3244 signal->theData[0] = ZSHUTDOWN;
3245 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
3246 }
3247
execSTOP_PERM_CONF(Signal * signal)3248 void Ndbcntr::execSTOP_PERM_CONF(Signal* signal){
3249 jamEntry();
3250
3251 AbortAllReq * req = (AbortAllReq*)&signal->theData[0];
3252 req->senderRef = reference();
3253 req->senderData = 12;
3254 sendSignal(DBTC_REF, GSN_ABORT_ALL_REQ, signal,
3255 AbortAllReq::SignalLength, JBB);
3256 }
3257
execABORT_ALL_CONF(Signal * signal)3258 void Ndbcntr::execABORT_ALL_CONF(Signal* signal){
3259 jamEntry();
3260 if(c_stopRec.stopReq.singleuser) {
3261 jam();
3262
3263 NodeState newState(NodeState::SL_SINGLEUSER);
3264 newState.setSingleUser(true);
3265 newState.setSingleUserApi(c_stopRec.stopReq.singleUserApi);
3266 updateNodeState(signal, newState);
3267 c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
3268
3269 StopConf * const stopConf = (StopConf *)&signal->theData[0];
3270 stopConf->senderData = c_stopRec.stopReq.senderData;
3271 stopConf->nodeState = (Uint32) NodeState::SL_SINGLEUSER;
3272 sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_CONF, signal, StopConf::SignalLength, JBB);
3273
3274 c_stopRec.stopReq.senderRef = 0; // the command is done
3275
3276 signal->theData[0] = NDB_LE_SingleUser;
3277 signal->theData[1] = 1;
3278 signal->theData[2] = c_stopRec.stopReq.singleUserApi;
3279 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
3280 }
3281 else
3282 {
3283 jam();
3284 NodeState newState(NodeState::SL_STOPPING_3,
3285 StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
3286 updateNodeState(signal, newState);
3287
3288 c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
3289
3290 signal->theData[0] = ZSHUTDOWN;
3291 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
3292 }
3293 }
3294
execABORT_ALL_REF(Signal * signal)3295 void Ndbcntr::execABORT_ALL_REF(Signal* signal){
3296 jamEntry();
3297
3298 StopRef * const stopRef = (StopRef *)&signal->theData[0];
3299 stopRef->senderData = c_stopRec.stopReq.senderData;
3300 stopRef->errorCode = StopRef::TransactionAbortFailed;
3301 stopRef->masterNodeId = cmasterNodeId;
3302 sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
3303 }
3304
3305 void
checkLqhTimeout_1(Signal * signal)3306 Ndbcntr::StopRecord::checkLqhTimeout_1(Signal* signal){
3307 const Int32 timeout = stopReq.readOperationTimeout;
3308 const NDB_TICKS alarm = stopInitiatedTime + (NDB_TICKS)timeout;
3309 const NDB_TICKS now = NdbTick_CurrentMillisecond();
3310
3311 if((timeout >= 0 && now >= alarm)){
3312 // || checkWithLqhInSomeMagicWay)
3313 jam();
3314
3315 ChangeNodeStateReq * req = (ChangeNodeStateReq*)&signal->theData[0];
3316
3317 NodeState newState(NodeState::SL_STOPPING_4,
3318 StopReq::getSystemStop(stopReq.requestInfo));
3319 req->nodeState = newState;
3320 req->senderRef = cntr.reference();
3321 req->senderData = 12;
3322 cntr.sendSignal(DBLQH_REF, GSN_CHANGE_NODE_STATE_REQ, signal,
3323 ChangeNodeStateReq::SignalLength, JBB);
3324 return;
3325 }
3326 signal->theData[0] = ZSHUTDOWN;
3327 cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
3328 }
3329
3330 void
execCHANGE_NODE_STATE_CONF(Signal * signal)3331 Ndbcntr::execCHANGE_NODE_STATE_CONF(Signal* signal)
3332 {
3333 jamEntry();
3334
3335 /**
3336 * stop replication stream
3337 */
3338 signal->theData[0] = reference();
3339 signal->theData[1] = 12;
3340 sendSignal(SUMA_REF, GSN_STOP_ME_REQ, signal, 2, JBB);
3341 }
3342
execSTOP_ME_REF(Signal * signal)3343 void Ndbcntr::execSTOP_ME_REF(Signal* signal){
3344 jamEntry();
3345 ndbrequire(false);
3346 }
3347
3348
execSTOP_ME_CONF(Signal * signal)3349 void Ndbcntr::execSTOP_ME_CONF(Signal* signal){
3350 jamEntry();
3351
3352 const StopMeConf * conf = CAST_CONSTPTR(StopMeConf, signal->getDataPtr());
3353 if (conf->senderData == 12)
3354 {
3355 /**
3356 * Remove node from transactions
3357 */
3358 signal->theData[0] = reference();
3359 signal->theData[1] = 13;
3360 sendSignal(DBDIH_REF, GSN_STOP_ME_REQ, signal, 2, JBB);
3361 return;
3362 }
3363
3364 NodeState newState(NodeState::SL_STOPPING_4,
3365 StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
3366 updateNodeState(signal, newState);
3367
3368 c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
3369 signal->theData[0] = ZSHUTDOWN;
3370 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
3371 }
3372
3373 void
checkLqhTimeout_2(Signal * signal)3374 Ndbcntr::StopRecord::checkLqhTimeout_2(Signal* signal){
3375 const Int32 timeout = stopReq.operationTimeout;
3376 const NDB_TICKS alarm = stopInitiatedTime + (NDB_TICKS)timeout;
3377 const NDB_TICKS now = NdbTick_CurrentMillisecond();
3378
3379 if((timeout >= 0 && now >= alarm)){
3380 // || checkWithLqhInSomeMagicWay)
3381 jam();
3382 if(StopReq::getPerformRestart(stopReq.requestInfo)){
3383 jam();
3384 StartOrd * startOrd = (StartOrd *)&signal->theData[0];
3385 startOrd->restartInfo = stopReq.requestInfo;
3386 cntr.sendSignal(CMVMI_REF, GSN_START_ORD, signal, 2, JBA);
3387 } else {
3388 jam();
3389 cntr.sendSignal(CMVMI_REF, GSN_STOP_ORD, signal, 1, JBA);
3390 }
3391 return;
3392 }
3393 signal->theData[0] = ZSHUTDOWN;
3394 cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
3395 }
3396
execWAIT_GCP_REF(Signal * signal)3397 void Ndbcntr::execWAIT_GCP_REF(Signal* signal){
3398 jamEntry();
3399
3400 //WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
3401
3402 WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
3403 req->senderRef = reference();
3404 req->senderData = StopRecord::SR_CLUSTER_SHUTDOWN;
3405 req->requestType = WaitGCPReq::CompleteForceStart;
3406 sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
3407 WaitGCPReq::SignalLength, JBB);
3408 }
3409
execWAIT_GCP_CONF(Signal * signal)3410 void Ndbcntr::execWAIT_GCP_CONF(Signal* signal){
3411 jamEntry();
3412
3413 WaitGCPConf* conf = (WaitGCPConf*)signal->getDataPtr();
3414
3415 switch(conf->senderData){
3416 case StopRecord::SR_BLOCK_GCP_START_GCP:
3417 {
3418 jam();
3419 /**
3420 *
3421 */
3422 if(!c_stopRec.checkNodeFail(signal))
3423 {
3424 jam();
3425 goto unblock;
3426 }
3427
3428 WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
3429 req->senderRef = reference();
3430 req->senderData = StopRecord::SR_WAIT_COMPLETE_GCP;
3431 req->requestType = WaitGCPReq::CompleteIfRunning;
3432
3433 sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
3434 WaitGCPReq::SignalLength, JBB);
3435 return;
3436 }
3437 case StopRecord::SR_UNBLOCK_GCP_START_GCP:
3438 {
3439 jam();
3440 return;
3441 }
3442 case StopRecord::SR_WAIT_COMPLETE_GCP:
3443 {
3444 jam();
3445 if(!c_stopRec.checkNodeFail(signal))
3446 {
3447 jam();
3448 goto unblock;
3449 }
3450
3451 NdbNodeBitmask tmp;
3452 tmp.assign(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
3453 c_stopRec.m_stop_req_counter = tmp;
3454 NodeReceiverGroup rg(QMGR, tmp);
3455 StopReq * stopReq = (StopReq *)&signal->theData[0];
3456 * stopReq = c_stopRec.stopReq;
3457 stopReq->senderRef = reference();
3458 sendSignal(rg, GSN_STOP_REQ, signal, StopReq::SignalLength, JBA);
3459 c_stopRec.m_state = StopRecord::SR_QMGR_STOP_REQ;
3460 return;
3461 }
3462 case StopRecord::SR_CLUSTER_SHUTDOWN:
3463 {
3464 jam();
3465 break;
3466 }
3467 }
3468
3469 {
3470 ndbrequire(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
3471 NodeState newState(NodeState::SL_STOPPING_3, true);
3472
3473 /**
3474 * Inform QMGR so that arbitrator won't kill us
3475 */
3476 NodeStateRep * rep = (NodeStateRep *)&signal->theData[0];
3477 rep->nodeState = newState;
3478 rep->nodeState.masterNodeId = cmasterNodeId;
3479 rep->nodeState.setNodeGroup(c_nodeGroup);
3480 EXECUTE_DIRECT(QMGR, GSN_NODE_STATE_REP, signal,
3481 NodeStateRep::SignalLength);
3482
3483 if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){
3484 jam();
3485 StartOrd * startOrd = (StartOrd *)&signal->theData[0];
3486 startOrd->restartInfo = c_stopRec.stopReq.requestInfo;
3487 sendSignalWithDelay(CMVMI_REF, GSN_START_ORD, signal, 500,
3488 StartOrd::SignalLength);
3489 } else {
3490 jam();
3491 sendSignalWithDelay(CMVMI_REF, GSN_STOP_ORD, signal, 500, 1);
3492 }
3493 return;
3494 }
3495
3496 unblock:
3497 WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
3498 req->senderRef = reference();
3499 req->senderData = StopRecord::SR_UNBLOCK_GCP_START_GCP;
3500 req->requestType = WaitGCPReq::UnblockStartGcp;
3501 sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
3502 WaitGCPReq::SignalLength, JBB);
3503 }
3504
3505 void
execSTOP_CONF(Signal * signal)3506 Ndbcntr::execSTOP_CONF(Signal* signal)
3507 {
3508 jamEntry();
3509 StopConf *conf = (StopConf*)signal->getDataPtr();
3510 ndbrequire(c_stopRec.m_state == StopRecord::SR_QMGR_STOP_REQ);
3511 c_stopRec.m_stop_req_counter.clearWaitingFor(conf->nodeId);
3512 if (c_stopRec.m_stop_req_counter.done())
3513 {
3514 char buf[100];
3515 NdbNodeBitmask mask;
3516 mask.assign(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
3517 infoEvent("Stopping of %s", mask.getText(buf));
3518 ndbout_c("Stopping of %s", mask.getText(buf));
3519
3520 /**
3521 * Kill any node...
3522 */
3523 FailRep * const failRep = (FailRep *)&signal->theData[0];
3524 failRep->failCause = FailRep::ZMULTI_NODE_SHUTDOWN;
3525 failRep->failSourceNodeId = getOwnNodeId();
3526 NodeReceiverGroup rg(QMGR, c_clusterNodes);
3527 Uint32 nodeId = 0;
3528 while ((nodeId = NdbNodeBitmask::find(c_stopRec.stopReq.nodes, nodeId+1))
3529 != NdbNodeBitmask::NotFound)
3530 {
3531 failRep->failNodeId = nodeId;
3532 sendSignal(rg, GSN_FAIL_REP, signal, FailRep::SignalLength, JBA);
3533 }
3534 c_stopRec.m_state = StopRecord::SR_WAIT_NODE_FAILURES;
3535 return;
3536 }
3537 }
3538
execSTTORRY(Signal * signal)3539 void Ndbcntr::execSTTORRY(Signal* signal){
3540 jamEntry();
3541 c_missra.execSTTORRY(signal);
3542 }
3543
execREAD_CONFIG_CONF(Signal * signal)3544 void Ndbcntr::execREAD_CONFIG_CONF(Signal* signal){
3545 jamEntry();
3546 c_missra.execREAD_CONFIG_CONF(signal);
3547 }
3548
execSTART_ORD(Signal * signal)3549 void Ndbcntr::execSTART_ORD(Signal* signal){
3550 jamEntry();
3551 c_missra.execSTART_ORD(signal);
3552 }
3553
3554 #define CLEAR_DX 13
3555 #define CLEAR_LCP 3
3556 #define CLEAR_DD 2
3557 // FileSystemPathDataFiles FileSystemPathUndoFiles
3558
3559 void
clearFilesystem(Signal * signal)3560 Ndbcntr::clearFilesystem(Signal* signal)
3561 {
3562 jam();
3563 FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend();
3564 req->userReference = reference();
3565 req->userPointer = 0;
3566 req->directory = 1;
3567 req->ownDirectory = 1;
3568
3569 const Uint32 DX = CLEAR_DX;
3570 const Uint32 LCP = CLEAR_DX + CLEAR_LCP;
3571 const Uint32 DD = CLEAR_DX + CLEAR_LCP + CLEAR_DD;
3572
3573 if (c_fsRemoveCount < DX)
3574 {
3575 FsOpenReq::setVersion(req->fileNumber, 3);
3576 FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL); // Can by any...
3577 FsOpenReq::v1_setDisk(req->fileNumber, c_fsRemoveCount);
3578 }
3579 else if (c_fsRemoveCount < LCP)
3580 {
3581 FsOpenReq::setVersion(req->fileNumber, 5);
3582 FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
3583 FsOpenReq::v5_setLcpNo(req->fileNumber, c_fsRemoveCount - CLEAR_DX);
3584 FsOpenReq::v5_setTableId(req->fileNumber, 0);
3585 FsOpenReq::v5_setFragmentId(req->fileNumber, 0);
3586 }
3587 else if (c_fsRemoveCount < DD)
3588 {
3589 req->ownDirectory = 0;
3590 FsOpenReq::setVersion(req->fileNumber, 6);
3591 FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
3592 FsOpenReq::v5_setLcpNo(req->fileNumber,
3593 FsOpenReq::BP_DD_DF + c_fsRemoveCount - LCP);
3594 }
3595 else
3596 {
3597 ndbrequire(false);
3598 }
3599
3600 sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
3601 FsRemoveReq::SignalLength, JBA);
3602 c_fsRemoveCount++;
3603 }
3604
3605 void
execFSREMOVECONF(Signal * signal)3606 Ndbcntr::execFSREMOVECONF(Signal* signal){
3607 jamEntry();
3608 if(c_fsRemoveCount == CLEAR_DX + CLEAR_LCP + CLEAR_DD){
3609 jam();
3610 sendSttorry(signal);
3611 } else {
3612 jam();
3613 ndbrequire(c_fsRemoveCount < CLEAR_DX + CLEAR_LCP + CLEAR_DD);
3614 clearFilesystem(signal);
3615 }//if
3616 }
3617
execSTART_ORD(Signal * signal)3618 void Ndbcntr::Missra::execSTART_ORD(Signal* signal){
3619 signal->theData[0] = NDB_LE_NDBStartStarted;
3620 signal->theData[1] = NDB_VERSION;
3621 signal->theData[2] = NDB_MYSQL_VERSION_D;
3622 cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
3623
3624 currentBlockIndex = 0;
3625 sendNextREAD_CONFIG_REQ(signal);
3626 }
3627
sendNextREAD_CONFIG_REQ(Signal * signal)3628 void Ndbcntr::Missra::sendNextREAD_CONFIG_REQ(Signal* signal){
3629
3630 if(currentBlockIndex < ALL_BLOCKS_SZ){
3631 jam();
3632
3633 ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtrSend();
3634 req->senderData = 0;
3635 req->senderRef = cntr.reference();
3636 req->noOfParameters = 0;
3637
3638 const BlockReference ref = readConfigOrder[currentBlockIndex];
3639
3640 #if 0
3641 ndbout_c("sending READ_CONFIG_REQ to %s(ref=%x index=%d)",
3642 getBlockName( refToBlock(ref)),
3643 ref,
3644 currentBlockIndex);
3645 #endif
3646
3647 /**
3648 * send delayed so that alloc gets "time-sliced"
3649 */
3650 cntr.sendSignalWithDelay(ref, GSN_READ_CONFIG_REQ, signal,
3651 1, ReadConfigReq::SignalLength);
3652 return;
3653 }
3654
3655 /**
3656 * Finished...
3657 */
3658 currentStartPhase = 0;
3659 for(Uint32 i = 0; i<ALL_BLOCKS_SZ; i++){
3660 if(ALL_BLOCKS[i].NextSP < currentStartPhase)
3661 currentStartPhase = ALL_BLOCKS[i].NextSP;
3662 }
3663
3664 currentBlockIndex = 0;
3665 sendNextSTTOR(signal);
3666 }
3667
execREAD_CONFIG_CONF(Signal * signal)3668 void Ndbcntr::Missra::execREAD_CONFIG_CONF(Signal* signal){
3669 const ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtr();
3670
3671 const Uint32 ref = conf->senderRef;
3672 ndbrequire(refToBlock(readConfigOrder[currentBlockIndex])
3673 == refToBlock(ref));
3674
3675 currentBlockIndex++;
3676 sendNextREAD_CONFIG_REQ(signal);
3677 }
3678
execSTTORRY(Signal * signal)3679 void Ndbcntr::Missra::execSTTORRY(Signal* signal){
3680 const BlockReference ref = signal->senderBlockRef();
3681 ndbrequire(refToBlock(ref) == refToBlock(ALL_BLOCKS[currentBlockIndex].Ref));
3682
3683 /**
3684 * Update next start phase
3685 */
3686 for (Uint32 i = 3; i < 25; i++){
3687 jam();
3688 if (signal->theData[i] > currentStartPhase){
3689 jam();
3690 ALL_BLOCKS[currentBlockIndex].NextSP = signal->theData[i];
3691 break;
3692 }
3693 }
3694
3695 currentBlockIndex++;
3696 sendNextSTTOR(signal);
3697 }
3698
sendNextSTTOR(Signal * signal)3699 void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){
3700
3701 for(; currentStartPhase < 255 ;
3702 currentStartPhase++, g_currentStartPhase = currentStartPhase){
3703 jam();
3704
3705 #ifdef ERROR_INSERT
3706 if (cntr.cerrorInsert == 1002 &&
3707 cntr.c_error_insert_extra == currentStartPhase)
3708 {
3709 signal->theData[0] = ZBLOCK_STTOR;
3710 cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
3711 return;
3712 }
3713 #endif
3714
3715 const Uint32 start = currentBlockIndex;
3716 for(; currentBlockIndex < ALL_BLOCKS_SZ; currentBlockIndex++){
3717 jam();
3718 if(ALL_BLOCKS[currentBlockIndex].NextSP == currentStartPhase){
3719 jam();
3720 signal->theData[0] = 0;
3721 signal->theData[1] = currentStartPhase;
3722 signal->theData[2] = 0;
3723 signal->theData[3] = 0;
3724 signal->theData[4] = 0;
3725 signal->theData[5] = 0;
3726 signal->theData[6] = 0;
3727 signal->theData[7] = cntr.ctypeOfStart;
3728
3729 const BlockReference ref = ALL_BLOCKS[currentBlockIndex].Ref;
3730
3731 #ifdef MAX_STARTPHASE
3732 ndbrequire(currentStartPhase <= MAX_STARTPHASE);
3733 #endif
3734
3735 #ifdef TRACE_STTOR
3736 ndbout_c("sending STTOR(%d) to %s(ref=%x index=%d)",
3737 currentStartPhase,
3738 getBlockName( refToBlock(ref)),
3739 ref,
3740 currentBlockIndex);
3741 #endif
3742 if (refToBlock(ref) == DBDIH)
3743 signal->theData[7] = cntr.cdihStartType;
3744
3745 cntr.sendSignal(ref, GSN_STTOR, signal, 8, JBB);
3746
3747 return;
3748 }
3749 }
3750
3751 currentBlockIndex = 0;
3752
3753 NodeState newState(NodeState::SL_STARTING, currentStartPhase,
3754 (NodeState::StartType)cntr.ctypeOfStart);
3755 cntr.updateNodeState(signal, newState);
3756
3757 if(start != 0)
3758 {
3759 /**
3760 * At least one wanted this start phase, record & report it
3761 */
3762 jam();
3763 g_eventLogger->info("Start phase %u completed", currentStartPhase);
3764
3765 signal->theData[0] = NDB_LE_StartPhaseCompleted;
3766 signal->theData[1] = currentStartPhase;
3767 signal->theData[2] = cntr.ctypeOfStart;
3768 cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
3769
3770 /**
3771 * Check if we should wait before proceeding with
3772 * next startphase
3773 *
3774 * New code guarantees that before starting X
3775 * that all other nodes (in system restart/initial start)
3776 * want to start a startphase >= X
3777 */
3778 if (cntr.wait_sp(signal, currentStartPhase + 1))
3779 {
3780 jam();
3781 currentStartPhase++;
3782 g_currentStartPhase = currentStartPhase;
3783 return;
3784 }
3785 }
3786 }
3787
3788 g_eventLogger->info("Node started");
3789
3790 signal->theData[0] = NDB_LE_NDBStartCompleted;
3791 signal->theData[1] = NDB_VERSION;
3792 signal->theData[2] = NDB_MYSQL_VERSION_D;
3793 cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
3794
3795 NodeState newState(NodeState::SL_STARTED);
3796 cntr.updateNodeState(signal, newState);
3797
3798 NodeReceiverGroup rg(NDBCNTR, cntr.c_clusterNodes);
3799 signal->theData[0] = cntr.getOwnNodeId();
3800 cntr.sendSignal(rg, GSN_CNTR_START_REP, signal, 1, JBB);
3801 }
3802
3803 void
execCREATE_NODEGROUP_IMPL_REQ(Signal * signal)3804 Ndbcntr::execCREATE_NODEGROUP_IMPL_REQ(Signal* signal)
3805 {
3806 jamEntry();
3807
3808 CreateNodegroupImplReq reqCopy = *(CreateNodegroupImplReq*)signal->getDataPtr();
3809 CreateNodegroupImplReq *req = &reqCopy;
3810
3811 if (req->requestType == CreateNodegroupImplReq::RT_COMMIT)
3812 {
3813 jam();
3814 Uint32 save = c_nodeGroup;
3815 getNodeGroup(signal);
3816 if (save != c_nodeGroup)
3817 {
3818 jam();
3819 updateNodeState(signal, getNodeState());
3820 }
3821 }
3822
3823 {
3824 CreateNodegroupImplConf* conf = (CreateNodegroupImplConf*)signal->getDataPtrSend();
3825 conf->senderRef = reference();
3826 conf->senderData = req->senderData;
3827 sendSignal(req->senderRef, GSN_CREATE_NODEGROUP_IMPL_CONF, signal,
3828 CreateNodegroupImplConf::SignalLength, JBB);
3829 }
3830 }
3831
3832 void
execDROP_NODEGROUP_IMPL_REQ(Signal * signal)3833 Ndbcntr::execDROP_NODEGROUP_IMPL_REQ(Signal* signal)
3834 {
3835 jamEntry();
3836
3837 DropNodegroupImplReq reqCopy = *(DropNodegroupImplReq*)signal->getDataPtr();
3838 DropNodegroupImplReq *req = &reqCopy;
3839
3840 if (req->requestType == DropNodegroupImplReq::RT_COMPLETE)
3841 {
3842 jam();
3843 Uint32 save = c_nodeGroup;
3844 getNodeGroup(signal);
3845
3846 if (save != c_nodeGroup)
3847 {
3848 jam();
3849 updateNodeState(signal, getNodeState());
3850 }
3851 }
3852
3853 {
3854 DropNodegroupImplConf* conf = (DropNodegroupImplConf*)signal->getDataPtrSend();
3855 conf->senderRef = reference();
3856 conf->senderData = req->senderData;
3857 sendSignal(req->senderRef, GSN_DROP_NODEGROUP_IMPL_CONF, signal,
3858 DropNodegroupImplConf::SignalLength, JBB);
3859 }
3860 }
3861
3862 template class Vector<ddentry>;
3863