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