1 /* Copyright (c) 2003-2007 MySQL AB
2    Use is subject to license terms
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 as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
16 
17 #define DBDIH_C
18 #include <ndb_limits.h>
19 #include <ndb_version.h>
20 #include <NdbOut.hpp>
21 
22 #include "Dbdih.hpp"
23 #include "Configuration.hpp"
24 
25 #include <signaldata/BlockCommitOrd.hpp>
26 #include <signaldata/CheckNodeGroups.hpp>
27 #include <signaldata/CreateFrag.hpp>
28 #include <signaldata/CopyActive.hpp>
29 #include <signaldata/CopyFrag.hpp>
30 #include <signaldata/CopyGCIReq.hpp>
31 #include <signaldata/DiAddTab.hpp>
32 #include <signaldata/DictStart.hpp>
33 #include <signaldata/DiGetNodes.hpp>
34 #include <signaldata/DihContinueB.hpp>
35 #include <signaldata/DihSwitchReplica.hpp>
36 #include <signaldata/DumpStateOrd.hpp>
37 #include <signaldata/EmptyLcp.hpp>
38 #include <signaldata/EndTo.hpp>
39 #include <signaldata/EventReport.hpp>
40 #include <signaldata/GCPSave.hpp>
41 #include <signaldata/HotSpareRep.hpp>
42 #include <signaldata/MasterGCP.hpp>
43 #include <signaldata/MasterLCP.hpp>
44 #include <signaldata/NFCompleteRep.hpp>
45 #include <signaldata/NodeFailRep.hpp>
46 #include <signaldata/ReadNodesConf.hpp>
47 #include <signaldata/StartFragReq.hpp>
48 #include <signaldata/StartInfo.hpp>
49 #include <signaldata/StartMe.hpp>
50 #include <signaldata/StartPerm.hpp>
51 #include <signaldata/StartRec.hpp>
52 #include <signaldata/StartTo.hpp>
53 #include <signaldata/StopPerm.hpp>
54 #include <signaldata/StopMe.hpp>
55 #include <signaldata/TestOrd.hpp>
56 #include <signaldata/UpdateTo.hpp>
57 #include <signaldata/WaitGCP.hpp>
58 #include <signaldata/DihStartTab.hpp>
59 #include <signaldata/LCP.hpp>
60 #include <signaldata/SystemError.hpp>
61 
62 #include <signaldata/DropTab.hpp>
63 #include <signaldata/AlterTab.hpp>
64 #include <signaldata/PrepDropTab.hpp>
65 #include <signaldata/SumaImpl.hpp>
66 #include <signaldata/DictTabInfo.hpp>
67 #include <signaldata/CreateFragmentation.hpp>
68 #include <signaldata/LqhFrag.hpp>
69 #include <signaldata/FsOpenReq.hpp>
70 #include <signaldata/DihFragCount.hpp>
71 #include <signaldata/DictLock.hpp>
72 #include <DebuggerNames.hpp>
73 
74 #include <EventLogger.hpp>
75 extern EventLogger g_eventLogger;
76 
77 #define SYSFILE ((Sysfile *)&sysfileData[0])
78 
79 #define RETURN_IF_NODE_NOT_ALIVE(node) \
80   if (!checkNodeAlive((node))) { \
81     jam(); \
82     return; \
83   } \
84 
85 #define RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverIndex, regTOPtr) \
86   regTOPtr.i = takeOverIndex; \
87   ptrCheckGuard(regTOPtr, MAX_NDB_NODES, takeOverRecord); \
88   if (checkToInterrupted(regTOPtr)) { \
89     jam(); \
90     return; \
91   } \
92 
93 #define receiveLoopMacro(sigName, receiveNodeId)\
94 {                                                \
95   c_##sigName##_Counter.clearWaitingFor(receiveNodeId); \
96   if(c_##sigName##_Counter.done() == false){     \
97      jam();                                      \
98      return;                                     \
99   }                                              \
100 }
101 
102 #define sendLoopMacro(sigName, signalRoutine)  \
103 {                                                                       \
104   c_##sigName##_Counter.clearWaitingFor();                              \
105   NodeRecordPtr specNodePtr;                                            \
106   specNodePtr.i = cfirstAliveNode;                                      \
107   do {                                                                  \
108     jam();                                                              \
109     ptrCheckGuard(specNodePtr, MAX_NDB_NODES, nodeRecord);              \
110     c_##sigName##_Counter.setWaitingFor(specNodePtr.i);                 \
111     signalRoutine(signal, specNodePtr.i);                               \
112     specNodePtr.i = specNodePtr.p->nextNode;                            \
113   } while (specNodePtr.i != RNIL);                                      \
114 }
115 
116 static
117 Uint32
prevLcpNo(Uint32 lcpNo)118 prevLcpNo(Uint32 lcpNo){
119   if(lcpNo == 0)
120     return MAX_LCP_STORED - 1;
121   return lcpNo - 1;
122 }
123 
124 static
125 Uint32
nextLcpNo(Uint32 lcpNo)126 nextLcpNo(Uint32 lcpNo){
127   lcpNo++;
128   if(lcpNo == MAX_LCP_STORED)
129     return 0;
130   return lcpNo;
131 }
132 
133 #define gth(x, y) ndbrequire(((int)x)>((int)y))
134 
nullRoutine(Signal * signal,Uint32 nodeId)135 void Dbdih::nullRoutine(Signal* signal, Uint32 nodeId)
136 {
137 }//Dbdih::nullRoutine()
138 
sendCOPY_GCIREQ(Signal * signal,Uint32 nodeId)139 void Dbdih::sendCOPY_GCIREQ(Signal* signal, Uint32 nodeId)
140 {
141   ndbrequire(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE);
142 
143   const BlockReference ref = calcDihBlockRef(nodeId);
144   const Uint32 wordPerSignal = CopyGCIReq::DATA_SIZE;
145   const Uint32 noOfSignals = ((Sysfile::SYSFILE_SIZE32 + (wordPerSignal - 1)) /
146 			      wordPerSignal);
147 
148   CopyGCIReq * const copyGCI = (CopyGCIReq *)&signal->theData[0];
149   copyGCI->anyData = nodeId;
150   copyGCI->copyReason = c_copyGCIMaster.m_copyReason;
151   copyGCI->startWord = 0;
152 
153   for(Uint32 i = 0; i < noOfSignals; i++) {
154     jam();
155     { // Do copy
156       const int startWord = copyGCI->startWord;
157       for(Uint32 j = 0; j < wordPerSignal; j++) {
158         copyGCI->data[j] = sysfileData[j+startWord];
159       }//for
160     }
161     sendSignal(ref, GSN_COPY_GCIREQ, signal, 25, JBB);
162     copyGCI->startWord += wordPerSignal;
163   }//for
164 }//Dbdih::sendCOPY_GCIREQ()
165 
166 
sendDIH_SWITCH_REPLICA_REQ(Signal * signal,Uint32 nodeId)167 void Dbdih::sendDIH_SWITCH_REPLICA_REQ(Signal* signal, Uint32 nodeId)
168 {
169   const BlockReference ref    = calcDihBlockRef(nodeId);
170   sendSignal(ref, GSN_DIH_SWITCH_REPLICA_REQ, signal,
171              DihSwitchReplicaReq::SignalLength, JBB);
172 }//Dbdih::sendDIH_SWITCH_REPLICA_REQ()
173 
sendEMPTY_LCP_REQ(Signal * signal,Uint32 nodeId)174 void Dbdih::sendEMPTY_LCP_REQ(Signal* signal, Uint32 nodeId)
175 {
176   BlockReference ref = calcLqhBlockRef(nodeId);
177   sendSignal(ref, GSN_EMPTY_LCP_REQ, signal, EmptyLcpReq::SignalLength, JBB);
178 }//Dbdih::sendEMPTY_LCPREQ()
179 
sendEND_TOREQ(Signal * signal,Uint32 nodeId)180 void Dbdih::sendEND_TOREQ(Signal* signal, Uint32 nodeId)
181 {
182   BlockReference ref = calcDihBlockRef(nodeId);
183   sendSignal(ref, GSN_END_TOREQ, signal, EndToReq::SignalLength, JBB);
184 }//Dbdih::sendEND_TOREQ()
185 
sendGCP_COMMIT(Signal * signal,Uint32 nodeId)186 void Dbdih::sendGCP_COMMIT(Signal* signal, Uint32 nodeId)
187 {
188   BlockReference ref = calcDihBlockRef(nodeId);
189   signal->theData[0] = cownNodeId;
190   signal->theData[1] = cnewgcp;
191   sendSignal(ref, GSN_GCP_COMMIT, signal, 2, JBA);
192 }//Dbdih::sendGCP_COMMIT()
193 
sendGCP_PREPARE(Signal * signal,Uint32 nodeId)194 void Dbdih::sendGCP_PREPARE(Signal* signal, Uint32 nodeId)
195 {
196   BlockReference ref = calcDihBlockRef(nodeId);
197   signal->theData[0] = cownNodeId;
198   signal->theData[1] = cnewgcp;
199   sendSignal(ref, GSN_GCP_PREPARE, signal, 2, JBA);
200 }//Dbdih::sendGCP_PREPARE()
201 
sendGCP_SAVEREQ(Signal * signal,Uint32 nodeId)202 void Dbdih::sendGCP_SAVEREQ(Signal* signal, Uint32 nodeId)
203 {
204   GCPSaveReq * const saveReq = (GCPSaveReq*)&signal->theData[0];
205   BlockReference ref = calcLqhBlockRef(nodeId);
206   saveReq->dihBlockRef = reference();
207   saveReq->dihPtr = nodeId;
208   saveReq->gci = coldgcp;
209   sendSignal(ref, GSN_GCP_SAVEREQ, signal, GCPSaveReq::SignalLength, JBB);
210 }//Dbdih::sendGCP_SAVEREQ()
211 
sendINCL_NODEREQ(Signal * signal,Uint32 nodeId)212 void Dbdih::sendINCL_NODEREQ(Signal* signal, Uint32 nodeId)
213 {
214   BlockReference nodeDihRef = calcDihBlockRef(nodeId);
215   signal->theData[0] = reference();
216   signal->theData[1] = c_nodeStartMaster.startNode;
217   signal->theData[2] = c_nodeStartMaster.failNr;
218   signal->theData[3] = 0;
219   signal->theData[4] = currentgcp;
220   sendSignal(nodeDihRef, GSN_INCL_NODEREQ, signal, 5, JBA);
221 }//Dbdih::sendINCL_NODEREQ()
222 
sendMASTER_GCPREQ(Signal * signal,Uint32 nodeId)223 void Dbdih::sendMASTER_GCPREQ(Signal* signal, Uint32 nodeId)
224 {
225   BlockReference ref = calcDihBlockRef(nodeId);
226   sendSignal(ref, GSN_MASTER_GCPREQ, signal, MasterGCPReq::SignalLength, JBB);
227 }//Dbdih::sendMASTER_GCPREQ()
228 
sendMASTER_LCPREQ(Signal * signal,Uint32 nodeId)229 void Dbdih::sendMASTER_LCPREQ(Signal* signal, Uint32 nodeId)
230 {
231   BlockReference ref = calcDihBlockRef(nodeId);
232   sendSignal(ref, GSN_MASTER_LCPREQ, signal, MasterLCPReq::SignalLength, JBB);
233 }//Dbdih::sendMASTER_LCPREQ()
234 
sendSTART_INFOREQ(Signal * signal,Uint32 nodeId)235 void Dbdih::sendSTART_INFOREQ(Signal* signal, Uint32 nodeId)
236 {
237   const BlockReference ref = calcDihBlockRef(nodeId);
238   sendSignal(ref, GSN_START_INFOREQ, signal, StartInfoReq::SignalLength, JBB);
239 }//sendSTART_INFOREQ()
240 
sendSTART_RECREQ(Signal * signal,Uint32 nodeId)241 void Dbdih::sendSTART_RECREQ(Signal* signal, Uint32 nodeId)
242 {
243   StartRecReq * const req = (StartRecReq*)&signal->theData[0];
244   BlockReference ref = calcLqhBlockRef(nodeId);
245   req->receivingNodeId = nodeId;
246   req->senderRef = reference();
247   req->keepGci = SYSFILE->keepGCI;
248   req->lastCompletedGci = SYSFILE->lastCompletedGCI[nodeId];
249   req->newestGci = SYSFILE->newestRestorableGCI;
250   sendSignal(ref, GSN_START_RECREQ, signal, StartRecReq::SignalLength, JBB);
251 
252   signal->theData[0] = NDB_LE_StartREDOLog;
253   signal->theData[1] = nodeId;
254   signal->theData[2] = SYSFILE->keepGCI;
255   signal->theData[3] = SYSFILE->lastCompletedGCI[nodeId];
256   signal->theData[4] = SYSFILE->newestRestorableGCI;
257   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 5, JBB);
258 }//Dbdih::sendSTART_RECREQ()
259 
sendSTART_TOREQ(Signal * signal,Uint32 nodeId)260 void Dbdih::sendSTART_TOREQ(Signal* signal, Uint32 nodeId)
261 {
262   BlockReference ref = calcDihBlockRef(nodeId);
263   sendSignal(ref, GSN_START_TOREQ, signal, StartToReq::SignalLength, JBB);
264 }//Dbdih::sendSTART_TOREQ()
265 
sendSTOP_ME_REQ(Signal * signal,Uint32 nodeId)266 void Dbdih::sendSTOP_ME_REQ(Signal* signal, Uint32 nodeId)
267 {
268   if (nodeId != getOwnNodeId()) {
269     jam();
270     const BlockReference ref = calcDihBlockRef(nodeId);
271     sendSignal(ref, GSN_STOP_ME_REQ, signal, StopMeReq::SignalLength, JBB);
272   }//if
273 }//Dbdih::sendSTOP_ME_REQ()
274 
sendTC_CLOPSIZEREQ(Signal * signal,Uint32 nodeId)275 void Dbdih::sendTC_CLOPSIZEREQ(Signal* signal, Uint32 nodeId)
276 {
277   BlockReference ref = calcTcBlockRef(nodeId);
278   signal->theData[0] = nodeId;
279   signal->theData[1] = reference();
280   sendSignal(ref, GSN_TC_CLOPSIZEREQ, signal, 2, JBB);
281 }//Dbdih::sendTC_CLOPSIZEREQ()
282 
sendTCGETOPSIZEREQ(Signal * signal,Uint32 nodeId)283 void Dbdih::sendTCGETOPSIZEREQ(Signal* signal, Uint32 nodeId)
284 {
285   BlockReference ref = calcTcBlockRef(nodeId);
286   signal->theData[0] = nodeId;
287   signal->theData[1] = reference();
288   sendSignal(ref, GSN_TCGETOPSIZEREQ, signal, 2, JBB);
289 }//Dbdih::sendTCGETOPSIZEREQ()
290 
sendUPDATE_TOREQ(Signal * signal,Uint32 nodeId)291 void Dbdih::sendUPDATE_TOREQ(Signal* signal, Uint32 nodeId)
292 {
293   const BlockReference ref = calcDihBlockRef(nodeId);
294   sendSignal(ref, GSN_UPDATE_TOREQ, signal, UpdateToReq::SignalLength, JBB);
295 }//sendUPDATE_TOREQ()
296 
execCONTINUEB(Signal * signal)297 void Dbdih::execCONTINUEB(Signal* signal)
298 {
299   jamEntry();
300   switch ((DihContinueB::Type)signal->theData[0]) {
301   case DihContinueB::ZPACK_TABLE_INTO_PAGES:
302     {
303       jam();
304       Uint32 tableId = signal->theData[1];
305       packTableIntoPagesLab(signal, tableId);
306       return;
307       break;
308     }
309   case DihContinueB::ZPACK_FRAG_INTO_PAGES:
310     {
311       RWFragment wf;
312       jam();
313       wf.rwfTabPtr.i = signal->theData[1];
314       ptrCheckGuard(wf.rwfTabPtr, ctabFileSize, tabRecord);
315       wf.fragId = signal->theData[2];
316       wf.pageIndex = signal->theData[3];
317       wf.wordIndex = signal->theData[4];
318       packFragIntoPagesLab(signal, &wf);
319       return;
320       break;
321     }
322   case DihContinueB::ZREAD_PAGES_INTO_TABLE:
323     {
324       jam();
325       Uint32 tableId = signal->theData[1];
326       readPagesIntoTableLab(signal, tableId);
327       return;
328       break;
329     }
330   case DihContinueB::ZREAD_PAGES_INTO_FRAG:
331     {
332       RWFragment rf;
333       jam();
334       rf.rwfTabPtr.i = signal->theData[1];
335       ptrCheckGuard(rf.rwfTabPtr, ctabFileSize, tabRecord);
336       rf.fragId = signal->theData[2];
337       rf.pageIndex = signal->theData[3];
338       rf.wordIndex = signal->theData[4];
339       readPagesIntoFragLab(signal, &rf);
340       return;
341       break;
342     }
343   case DihContinueB::ZCOPY_TABLE:
344     {
345       jam();
346       Uint32 tableId = signal->theData[1];
347       copyTableLab(signal, tableId);
348       return;
349     }
350   case DihContinueB::ZCOPY_TABLE_NODE:
351     {
352       NodeRecordPtr nodePtr;
353       CopyTableNode ctn;
354       jam();
355       ctn.ctnTabPtr.i = signal->theData[1];
356       ptrCheckGuard(ctn.ctnTabPtr, ctabFileSize, tabRecord);
357       nodePtr.i = signal->theData[2];
358       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
359       ctn.pageIndex = signal->theData[3];
360       ctn.wordIndex = signal->theData[4];
361       ctn.noOfWords = signal->theData[5];
362       copyTableNode(signal, &ctn, nodePtr);
363       return;
364     }
365   case DihContinueB::ZSTART_FRAGMENT:
366     {
367       jam();
368       Uint32 tableId = signal->theData[1];
369       Uint32 fragId = signal->theData[2];
370       startFragment(signal, tableId, fragId);
371       return;
372     }
373   case DihContinueB::ZCOMPLETE_RESTART:
374     jam();
375     completeRestartLab(signal);
376     return;
377   case DihContinueB::ZREAD_TABLE_FROM_PAGES:
378     {
379       TabRecordPtr tabPtr;
380       jam();
381       tabPtr.i = signal->theData[1];
382       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
383       readTableFromPagesLab(signal, tabPtr);
384       return;
385     }
386   case DihContinueB::ZSR_PHASE2_READ_TABLE:
387     {
388       TabRecordPtr tabPtr;
389       jam();
390       tabPtr.i = signal->theData[1];
391       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
392       srPhase2ReadTableLab(signal, tabPtr);
393       return;
394     }
395   case DihContinueB::ZCHECK_TC_COUNTER:
396     jam();
397 #ifndef NO_LCP
398     checkTcCounterLab(signal);
399 #endif
400     return;
401   case DihContinueB::ZCALCULATE_KEEP_GCI:
402     {
403       jam();
404       Uint32 tableId = signal->theData[1];
405       Uint32 fragId = signal->theData[2];
406       calculateKeepGciLab(signal, tableId, fragId);
407       return;
408     }
409   case DihContinueB::ZSTORE_NEW_LCP_ID:
410     jam();
411     storeNewLcpIdLab(signal);
412     return;
413   case DihContinueB::ZTABLE_UPDATE:
414     {
415       TabRecordPtr tabPtr;
416       jam();
417       tabPtr.i = signal->theData[1];
418       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
419       tableUpdateLab(signal, tabPtr);
420       return;
421     }
422   case DihContinueB::ZCHECK_LCP_COMPLETED:
423     {
424       jam();
425       checkLcpCompletedLab(signal);
426       return;
427     }
428   case DihContinueB::ZINIT_LCP:
429     {
430       jam();
431       Uint32 senderRef = signal->theData[1];
432       Uint32 tableId = signal->theData[2];
433       initLcpLab(signal, senderRef, tableId);
434       return;
435     }
436   case DihContinueB::ZADD_TABLE_MASTER_PAGES:
437     {
438       TabRecordPtr tabPtr;
439       jam();
440       tabPtr.i = signal->theData[1];
441       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
442       tabPtr.p->tabUpdateState = TabRecord::US_ADD_TABLE_MASTER;
443       tableUpdateLab(signal, tabPtr);
444       return;
445       break;
446     }
447   case DihContinueB::ZDIH_ADD_TABLE_MASTER:
448     {
449       jam();
450       addTable_closeConf(signal, signal->theData[1]);
451       return;
452     }
453   case DihContinueB::ZADD_TABLE_SLAVE_PAGES:
454     {
455       TabRecordPtr tabPtr;
456       jam();
457       tabPtr.i = signal->theData[1];
458       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
459       tabPtr.p->tabUpdateState = TabRecord::US_ADD_TABLE_SLAVE;
460       tableUpdateLab(signal, tabPtr);
461       return;
462     }
463   case DihContinueB::ZDIH_ADD_TABLE_SLAVE:
464     {
465       ndbrequire(false);
466       return;
467     }
468   case DihContinueB::ZSTART_GCP:
469     jam();
470 #ifndef NO_GCP
471     startGcpLab(signal, signal->theData[1]);
472 #endif
473     return;
474     break;
475   case DihContinueB::ZCOPY_GCI:{
476     jam();
477     CopyGCIReq::CopyReason reason = (CopyGCIReq::CopyReason)signal->theData[1];
478     ndbrequire(c_copyGCIMaster.m_copyReason == reason);
479     sendLoopMacro(COPY_GCIREQ, sendCOPY_GCIREQ);
480     return;
481   }
482     break;
483   case DihContinueB::ZEMPTY_VERIFY_QUEUE:
484     jam();
485     emptyverificbuffer(signal, true);
486     return;
487     break;
488   case DihContinueB::ZCHECK_GCP_STOP:
489     jam();
490 #ifndef NO_GCP
491     checkGcpStopLab(signal);
492 #endif
493     return;
494     break;
495   case DihContinueB::ZREMOVE_NODE_FROM_TABLE:
496     {
497       jam();
498       Uint32 nodeId = signal->theData[1];
499       Uint32 tableId = signal->theData[2];
500       removeNodeFromTables(signal, nodeId, tableId);
501       return;
502     }
503   case DihContinueB::ZCOPY_NODE:
504     {
505       jam();
506       Uint32 tableId = signal->theData[1];
507       copyNodeLab(signal, tableId);
508       return;
509     }
510   case DihContinueB::ZSTART_TAKE_OVER:
511     {
512       jam();
513       Uint32 takeOverPtrI = signal->theData[1];
514       Uint32 startNode = signal->theData[2];
515       Uint32 toNode = signal->theData[3];
516       startTakeOver(signal, takeOverPtrI, startNode, toNode);
517       return;
518       break;
519     }
520   case DihContinueB::ZCHECK_START_TAKE_OVER:
521     jam();
522     checkStartTakeOver(signal);
523     break;
524   case DihContinueB::ZTO_START_COPY_FRAG:
525     {
526       jam();
527       Uint32 takeOverPtrI = signal->theData[1];
528       startNextCopyFragment(signal, takeOverPtrI);
529       return;
530     }
531   case DihContinueB::ZINVALIDATE_NODE_LCP:
532     {
533       jam();
534       const Uint32 nodeId = signal->theData[1];
535       const Uint32 tableId = signal->theData[2];
536       invalidateNodeLCP(signal, nodeId, tableId);
537       return;
538     }
539   case DihContinueB::ZINITIALISE_RECORDS:
540     jam();
541     initialiseRecordsLab(signal,
542 			 signal->theData[1],
543 			 signal->theData[2],
544 			 signal->theData[3]);
545     return;
546     break;
547   case DihContinueB::ZSTART_PERMREQ_AGAIN:
548     jam();
549     nodeRestartPh2Lab2(signal);
550     return;
551     break;
552   case DihContinueB::SwitchReplica:
553     {
554       jam();
555       const Uint32 nodeId = signal->theData[1];
556       const Uint32 tableId = signal->theData[2];
557       const Uint32 fragNo = signal->theData[3];
558       switchReplica(signal, nodeId, tableId, fragNo);
559       return;
560     }
561   case DihContinueB::ZSEND_START_TO:
562     {
563       jam();
564       Uint32 takeOverPtrI = signal->theData[1];
565       sendStartTo(signal, takeOverPtrI);
566       return;
567     }
568   case DihContinueB::ZSEND_ADD_FRAG:
569     {
570       jam();
571       Uint32 takeOverPtrI = signal->theData[1];
572       toCopyFragLab(signal, takeOverPtrI);
573       return;
574     }
575   case DihContinueB::ZSEND_UPDATE_TO:
576     {
577       jam();
578       Uint32 takeOverPtrI = signal->theData[1];
579       Uint32 updateState = signal->theData[4];
580       sendUpdateTo(signal, takeOverPtrI, updateState);
581       return;
582     }
583   case DihContinueB::ZSEND_END_TO:
584     {
585       jam();
586       Uint32 takeOverPtrI = signal->theData[1];
587       sendEndTo(signal, takeOverPtrI);
588       return;
589     }
590   case DihContinueB::ZSEND_CREATE_FRAG:
591     {
592       jam();
593       Uint32 takeOverPtrI = signal->theData[1];
594       Uint32 storedType = signal->theData[2];
595       Uint32 startGci = signal->theData[3];
596       sendCreateFragReq(signal, startGci, storedType, takeOverPtrI);
597       return;
598     }
599   case DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE:{
600     jam();
601     TabRecordPtr tabPtr;
602     tabPtr.i = signal->theData[1];
603     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
604     waitDropTabWritingToFile(signal, tabPtr);
605     return;
606   }
607   case DihContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH:{
608     jam();
609     Uint32 nodeId = signal->theData[1];
610     Uint32 tableId = signal->theData[2];
611     checkWaitDropTabFailedLqh(signal, nodeId, tableId);
612     return;
613   }
614   case DihContinueB::ZTO_START_FRAGMENTS:
615   {
616     TakeOverRecordPtr takeOverPtr;
617     takeOverPtr.i = signal->theData[1];
618     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
619     nr_start_fragments(signal, takeOverPtr);
620     return;
621   }
622   }//switch
623 
624   ndbrequire(false);
625   return;
626 }//Dbdih::execCONTINUEB()
627 
execCOPY_GCIREQ(Signal * signal)628 void Dbdih::execCOPY_GCIREQ(Signal* signal)
629 {
630   CopyGCIReq * const copyGCI = (CopyGCIReq *)&signal->theData[0];
631   jamEntry();
632   CopyGCIReq::CopyReason reason = (CopyGCIReq::CopyReason)copyGCI->copyReason;
633   const Uint32 tstart = copyGCI->startWord;
634 
635   ndbrequire(cmasterdihref == signal->senderBlockRef()) ;
636   ndbrequire(c_copyGCISlave.m_copyReason  == CopyGCIReq::IDLE);
637   ndbrequire(c_copyGCISlave.m_expectedNextWord == tstart);
638   ndbrequire(reason != CopyGCIReq::IDLE);
639   bool isdone = (tstart + CopyGCIReq::DATA_SIZE) >= Sysfile::SYSFILE_SIZE32;
640 
641   if (ERROR_INSERTED(7177))
642   {
643     jam();
644 
645     if (signal->getLength() == 3)
646     {
647       jam();
648       goto done;
649     }
650   }
651 
652   arrGuard(tstart + CopyGCIReq::DATA_SIZE, sizeof(sysfileData)/4);
653   for(Uint32 i = 0; i<CopyGCIReq::DATA_SIZE; i++)
654     cdata[tstart+i] = copyGCI->data[i];
655 
656   if (ERROR_INSERTED(7177) && isMaster() && isdone)
657   {
658     sendSignalWithDelay(reference(), GSN_COPY_GCIREQ, signal, 1000, 3);
659     return;
660   }
661 
662 done:
663   if (isdone)
664   {
665     jam();
666     c_copyGCISlave.m_expectedNextWord = 0;
667   }
668   else
669   {
670     jam();
671     c_copyGCISlave.m_expectedNextWord += CopyGCIReq::DATA_SIZE;
672     return;
673   }
674 
675   if (cmasterdihref != reference())
676   {
677     jam();
678     Uint32 tmp= SYSFILE->m_restart_seq;
679     memcpy(sysfileData, cdata, sizeof(sysfileData));
680     SYSFILE->m_restart_seq = tmp;
681 
682     if (c_set_initial_start_flag)
683     {
684       jam();
685       Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
686     }
687   }
688 
689   c_copyGCISlave.m_copyReason = reason;
690   c_copyGCISlave.m_senderRef  = signal->senderBlockRef();
691   c_copyGCISlave.m_senderData = copyGCI->anyData;
692 
693   CRASH_INSERTION2(7020, reason==CopyGCIReq::LOCAL_CHECKPOINT);
694   CRASH_INSERTION2(7008, reason==CopyGCIReq::GLOBAL_CHECKPOINT);
695 
696   /* -------------------------------------------------------------------------*/
697   /*     WE SET THE REQUESTER OF THE COPY GCI TO THE CURRENT MASTER. IF THE   */
698   /*     CURRENT MASTER WE DO NOT WANT THE NEW MASTER TO RECEIVE CONFIRM OF   */
699   /*     SOMETHING HE HAS NOT SENT. THE TAKE OVER MUST BE CAREFUL.            */
700   /* -------------------------------------------------------------------------*/
701   bool ok = false;
702   switch(reason){
703   case CopyGCIReq::IDLE:
704     ok = true;
705     jam();
706     ndbrequire(false);
707     break;
708   case CopyGCIReq::LOCAL_CHECKPOINT: {
709     ok = true;
710     jam();
711     c_lcpState.setLcpStatus(LCP_COPY_GCI, __LINE__);
712     c_lcpState.m_masterLcpDihRef = cmasterdihref;
713     setNodeInfo(signal);
714     break;
715   }
716   case CopyGCIReq::RESTART: {
717     ok = true;
718     jam();
719     coldgcp = SYSFILE->newestRestorableGCI;
720     crestartGci = SYSFILE->newestRestorableGCI;
721     c_newest_restorable_gci = SYSFILE->newestRestorableGCI;
722     Sysfile::setRestartOngoing(SYSFILE->systemRestartBits);
723     currentgcp = coldgcp + 1;
724     cnewgcp = coldgcp + 1;
725     setNodeInfo(signal);
726     if ((Sysfile::getLCPOngoing(SYSFILE->systemRestartBits))) {
727       jam();
728       /* -------------------------------------------------------------------- */
729       //  IF THERE WAS A LOCAL CHECKPOINT ONGOING AT THE CRASH MOMENT WE WILL
730       //    INVALIDATE THAT LOCAL CHECKPOINT.
731       /* -------------------------------------------------------------------- */
732       invalidateLcpInfoAfterSr();
733     }//if
734     break;
735   }
736   case CopyGCIReq::GLOBAL_CHECKPOINT: {
737     ok = true;
738     jam();
739     cgcpParticipantState = GCP_PARTICIPANT_COPY_GCI_RECEIVED;
740     c_newest_restorable_gci = SYSFILE->newestRestorableGCI;
741     setNodeInfo(signal);
742     break;
743   }//if
744   case CopyGCIReq::INITIAL_START_COMPLETED:
745     ok = true;
746     jam();
747     break;
748   }
749   ndbrequire(ok);
750 
751   CRASH_INSERTION(7183);
752 
753   if (ERROR_INSERTED(7185) && reason==CopyGCIReq::GLOBAL_CHECKPOINT)
754   {
755     jam();
756     return;
757   }
758 
759   /* ----------------------------------------------------------------------- */
760   /*     WE START BY TRYING TO OPEN THE FIRST RESTORABLE GCI FILE.           */
761   /* ----------------------------------------------------------------------- */
762   FileRecordPtr filePtr;
763   filePtr.i = crestartInfoFile[0];
764   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
765   if (filePtr.p->fileStatus == FileRecord::OPEN) {
766     jam();
767     openingCopyGciSkipInitLab(signal, filePtr);
768     return;
769   }//if
770   openFileRw(signal, filePtr);
771   filePtr.p->reqStatus = FileRecord::OPENING_COPY_GCI;
772   return;
773 }//Dbdih::execCOPY_GCIREQ()
774 
execDICTSTARTCONF(Signal * signal)775 void Dbdih::execDICTSTARTCONF(Signal* signal)
776 {
777   jamEntry();
778   Uint32 nodeId = refToNode(signal->getSendersBlockRef());
779   if (nodeId != getOwnNodeId()) {
780     jam();
781     nodeDictStartConfLab(signal);
782   } else {
783     jam();
784     dictStartConfLab(signal);
785   }//if
786 }//Dbdih::execDICTSTARTCONF()
787 
execFSCLOSECONF(Signal * signal)788 void Dbdih::execFSCLOSECONF(Signal* signal)
789 {
790   FileRecordPtr filePtr;
791   jamEntry();
792   filePtr.i = signal->theData[0];
793   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
794   filePtr.p->fileStatus = FileRecord::CLOSED;
795   FileRecord::ReqStatus status = filePtr.p->reqStatus;
796   filePtr.p->reqStatus = FileRecord::IDLE;
797   switch (status) {
798   case FileRecord::CLOSING_GCP:
799     jam();
800     closingGcpLab(signal, filePtr);
801     break;
802   case FileRecord::CLOSING_GCP_CRASH:
803     jam();
804     closingGcpCrashLab(signal, filePtr);
805     break;
806   case FileRecord::CLOSING_TABLE_CRASH:
807     jam();
808     closingTableCrashLab(signal, filePtr);
809     break;
810   case FileRecord::CLOSING_TABLE_SR:
811     jam();
812     closingTableSrLab(signal, filePtr);
813     break;
814   case FileRecord::TABLE_CLOSE:
815     jam();
816     tableCloseLab(signal, filePtr);
817     break;
818   case FileRecord::TABLE_CLOSE_DELETE:
819     jam();
820     tableDeleteLab(signal, filePtr);
821     break;
822   default:
823     ndbrequire(false);
824     break;
825   }//switch
826   return;
827 }//Dbdih::execFSCLOSECONF()
828 
execFSCLOSEREF(Signal * signal)829 void Dbdih::execFSCLOSEREF(Signal* signal)
830 {
831   FileRecordPtr filePtr;
832   jamEntry();
833   filePtr.i = signal->theData[0];
834   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
835   FileRecord::ReqStatus status = filePtr.p->reqStatus;
836   filePtr.p->reqStatus = FileRecord::IDLE;
837   switch (status) {
838   case FileRecord::CLOSING_GCP:
839     jam();
840     break;
841   case FileRecord::CLOSING_GCP_CRASH:
842     jam();
843     closingGcpCrashLab(signal, filePtr);
844     return;
845   case FileRecord::CLOSING_TABLE_CRASH:
846     jam();
847     closingTableCrashLab(signal, filePtr);
848     return;
849   case FileRecord::CLOSING_TABLE_SR:
850     jam();
851     break;
852   case FileRecord::TABLE_CLOSE:
853     jam();
854     break;
855   case FileRecord::TABLE_CLOSE_DELETE:
856     jam();
857     break;
858   default:
859     jam();
860     break;
861 
862   }//switch
863   {
864     char msg[100];
865     sprintf(msg, "File system close failed during FileRecord status %d", (Uint32)status);
866     fsRefError(signal,__LINE__,msg);
867   }
868 
869   return;
870 }//Dbdih::execFSCLOSEREF()
871 
execFSOPENCONF(Signal * signal)872 void Dbdih::execFSOPENCONF(Signal* signal)
873 {
874   FileRecordPtr filePtr;
875   jamEntry();
876   filePtr.i = signal->theData[0];
877   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
878   filePtr.p->fileRef = signal->theData[1];
879   filePtr.p->fileStatus = FileRecord::OPEN;
880   FileRecord::ReqStatus status = filePtr.p->reqStatus;
881   filePtr.p->reqStatus = FileRecord::IDLE;
882   switch (status) {
883   case FileRecord::CREATING_GCP:
884     jam();
885     creatingGcpLab(signal, filePtr);
886     break;
887   case FileRecord::OPENING_COPY_GCI:
888     jam();
889     openingCopyGciSkipInitLab(signal, filePtr);
890     break;
891   case FileRecord::CREATING_COPY_GCI:
892     jam();
893     openingCopyGciSkipInitLab(signal, filePtr);
894     break;
895   case FileRecord::OPENING_GCP:
896     jam();
897     openingGcpLab(signal, filePtr);
898     break;
899   case FileRecord::OPENING_TABLE:
900     jam();
901     openingTableLab(signal, filePtr);
902     break;
903   case FileRecord::TABLE_CREATE:
904     jam();
905     tableCreateLab(signal, filePtr);
906     break;
907   case FileRecord::TABLE_OPEN_FOR_DELETE:
908     jam();
909     tableOpenLab(signal, filePtr);
910     break;
911   default:
912     ndbrequire(false);
913     break;
914   }//switch
915   return;
916 }//Dbdih::execFSOPENCONF()
917 
execFSOPENREF(Signal * signal)918 void Dbdih::execFSOPENREF(Signal* signal)
919 {
920   FileRecordPtr filePtr;
921   jamEntry();
922   filePtr.i = signal->theData[0];
923   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
924   FileRecord::ReqStatus status = filePtr.p->reqStatus;
925   filePtr.p->reqStatus = FileRecord::IDLE;
926   switch (status) {
927   case FileRecord::CREATING_GCP:
928     /* --------------------------------------------------------------------- */
929     /*   WE DID NOT MANAGE TO CREATE A GLOBAL CHECKPOINT FILE. SERIOUS ERROR */
930     /*   WHICH CAUSES A SYSTEM RESTART.                                      */
931     /* --------------------------------------------------------------------- */
932     jam();
933     break;
934   case FileRecord::OPENING_COPY_GCI:
935     jam();
936     openingCopyGciErrorLab(signal, filePtr);
937     return;
938   case FileRecord::CREATING_COPY_GCI:
939     jam();
940     break;
941   case FileRecord::OPENING_GCP:
942     jam();
943     openingGcpErrorLab(signal, filePtr);
944     return;
945   case FileRecord::OPENING_TABLE:
946     jam();
947     openingTableErrorLab(signal, filePtr);
948     return;
949   case FileRecord::TABLE_CREATE:
950     jam();
951     break;
952   case FileRecord::TABLE_OPEN_FOR_DELETE:
953     jam();
954     tableDeleteLab(signal, filePtr);
955     return;
956   default:
957     jam();
958     break;
959   }//switch
960   {
961     char msg[100];
962     sprintf(msg, "File system open failed during FileRecord status %d", (Uint32)status);
963     fsRefError(signal,__LINE__,msg);
964   }
965   return;
966 }//Dbdih::execFSOPENREF()
967 
execFSREADCONF(Signal * signal)968 void Dbdih::execFSREADCONF(Signal* signal)
969 {
970   FileRecordPtr filePtr;
971   jamEntry();
972   filePtr.i = signal->theData[0];
973   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
974   FileRecord::ReqStatus status = filePtr.p->reqStatus;
975   filePtr.p->reqStatus = FileRecord::IDLE;
976   switch (status) {
977   case FileRecord::READING_GCP:
978     jam();
979     readingGcpLab(signal, filePtr);
980     break;
981   case FileRecord::READING_TABLE:
982     jam();
983     readingTableLab(signal, filePtr);
984     break;
985   default:
986     ndbrequire(false);
987     break;
988   }//switch
989   return;
990 }//Dbdih::execFSREADCONF()
991 
execFSREADREF(Signal * signal)992 void Dbdih::execFSREADREF(Signal* signal)
993 {
994   FileRecordPtr filePtr;
995   jamEntry();
996   filePtr.i = signal->theData[0];
997   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
998   FileRecord::ReqStatus status = filePtr.p->reqStatus;
999   filePtr.p->reqStatus = FileRecord::IDLE;
1000   switch (status) {
1001   case FileRecord::READING_GCP:
1002     jam();
1003     readingGcpErrorLab(signal, filePtr);
1004     return;
1005   case FileRecord::READING_TABLE:
1006     jam();
1007     readingTableErrorLab(signal, filePtr);
1008     return;
1009   default:
1010     break;
1011   }//switch
1012   {
1013     char msg[100];
1014     sprintf(msg, "File system read failed during FileRecord status %d", (Uint32)status);
1015     fsRefError(signal,__LINE__,msg);
1016   }
1017 }//Dbdih::execFSREADREF()
1018 
execFSWRITECONF(Signal * signal)1019 void Dbdih::execFSWRITECONF(Signal* signal)
1020 {
1021   FileRecordPtr filePtr;
1022   jamEntry();
1023   filePtr.i = signal->theData[0];
1024   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
1025   FileRecord::ReqStatus status = filePtr.p->reqStatus;
1026   filePtr.p->reqStatus = FileRecord::IDLE;
1027   switch (status) {
1028   case FileRecord::WRITING_COPY_GCI:
1029     jam();
1030     writingCopyGciLab(signal, filePtr);
1031     break;
1032   case FileRecord::WRITE_INIT_GCP:
1033     jam();
1034     writeInitGcpLab(signal, filePtr);
1035     break;
1036   case FileRecord::TABLE_WRITE:
1037     jam();
1038     tableWriteLab(signal, filePtr);
1039     break;
1040   default:
1041     ndbrequire(false);
1042     break;
1043   }//switch
1044   return;
1045 }//Dbdih::execFSWRITECONF()
1046 
execFSWRITEREF(Signal * signal)1047 void Dbdih::execFSWRITEREF(Signal* signal)
1048 {
1049   FileRecordPtr filePtr;
1050   jamEntry();
1051   filePtr.i = signal->theData[0];
1052   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
1053   FileRecord::ReqStatus status = filePtr.p->reqStatus;
1054   filePtr.p->reqStatus = FileRecord::IDLE;
1055   switch (status) {
1056   case FileRecord::WRITING_COPY_GCI:
1057     /* --------------------------------------------------------------------- */
1058     /*  EVEN CREATING THE FILE DID NOT WORK. WE WILL THEN CRASH.             */
1059     /*  ERROR IN WRITING FILE. WE WILL NOT CONTINUE FROM HERE.               */
1060     /* --------------------------------------------------------------------- */
1061     jam();
1062     break;
1063   case FileRecord::WRITE_INIT_GCP:
1064     /* --------------------------------------------------------------------- */
1065     /*   AN ERROR OCCURRED IN WRITING A GCI FILE WHICH IS A SERIOUS ERROR    */
1066     /*   THAT CAUSE A SYSTEM RESTART.                                        */
1067     /* --------------------------------------------------------------------- */
1068     jam();
1069     break;
1070   case FileRecord::TABLE_WRITE:
1071     jam();
1072     break;
1073   default:
1074     jam();
1075     break;
1076   }//switch
1077   {
1078     char msg[100];
1079     sprintf(msg, "File system write failed during FileRecord status %d", (Uint32)status);
1080     fsRefError(signal,__LINE__,msg);
1081   }
1082   return;
1083 }//Dbdih::execFSWRITEREF()
1084 
execGETGCIREQ(Signal * signal)1085 void Dbdih::execGETGCIREQ(Signal* signal)
1086 {
1087 
1088   jamEntry();
1089   Uint32 userPtr = signal->theData[0];
1090   BlockReference userRef = signal->theData[1];
1091 
1092   signal->theData[0] = userPtr;
1093   signal->theData[1] = SYSFILE->newestRestorableGCI;
1094   sendSignal(userRef, GSN_GETGCICONF, signal, 2, JBB);
1095 }//Dbdih::execGETGCIREQ()
1096 
execREAD_CONFIG_REQ(Signal * signal)1097 void Dbdih::execREAD_CONFIG_REQ(Signal* signal)
1098 {
1099   const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
1100   Uint32 ref = req->senderRef;
1101   Uint32 senderData = req->senderData;
1102   ndbrequire(req->noOfParameters == 0);
1103 
1104   jamEntry();
1105 
1106   const ndb_mgm_configuration_iterator * p =
1107     m_ctx.m_config.getOwnConfigIterator();
1108   ndbrequireErr(p != 0, NDBD_EXIT_INVALID_CONFIG);
1109 
1110   initData();
1111 
1112   ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_API_CONNECT,
1113 					   &capiConnectFileSize),
1114 		NDBD_EXIT_INVALID_CONFIG);
1115   ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_CONNECT,
1116 					   &cconnectFileSize),
1117 		NDBD_EXIT_INVALID_CONFIG);
1118   ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT,
1119 					   &cfragstoreFileSize),
1120 		NDBD_EXIT_INVALID_CONFIG);
1121   ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_REPLICAS,
1122 					   &creplicaFileSize),
1123 		NDBD_EXIT_INVALID_CONFIG);
1124   ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_TABLE, &ctabFileSize),
1125 		NDBD_EXIT_INVALID_CONFIG);
1126   cfileFileSize = (2 * ctabFileSize) + 2;
1127   initRecords();
1128   initialiseRecordsLab(signal, 0, ref, senderData);
1129   return;
1130 }//Dbdih::execSIZEALT_REP()
1131 
execSTART_COPYREF(Signal * signal)1132 void Dbdih::execSTART_COPYREF(Signal* signal)
1133 {
1134   jamEntry();
1135   ndbrequire(false);
1136 }//Dbdih::execSTART_COPYREF()
1137 
execSTART_FRAGCONF(Signal * signal)1138 void Dbdih::execSTART_FRAGCONF(Signal* signal)
1139 {
1140   (void)signal;  // Don't want compiler warning
1141   /* ********************************************************************* */
1142   /*  If anyone wants to add functionality in this method, be aware that   */
1143   /*  for temporary tables no START_FRAGREQ is sent and therefore no       */
1144   /*  START_FRAGCONF signal will be received for those tables!!            */
1145   /* ********************************************************************* */
1146   jamEntry();
1147   return;
1148 }//Dbdih::execSTART_FRAGCONF()
1149 
execSTART_FRAGREF(Signal * signal)1150 void Dbdih::execSTART_FRAGREF(Signal* signal)
1151 {
1152   jamEntry();
1153 
1154   /**
1155    * Kill starting node
1156    */
1157   Uint32 errCode = signal->theData[1];
1158   Uint32 nodeId = signal->theData[2];
1159 
1160   SystemError * const sysErr = (SystemError*)&signal->theData[0];
1161   sysErr->errorCode = SystemError::StartFragRefError;
1162   sysErr->errorRef = reference();
1163   sysErr->data1 = errCode;
1164   sysErr->data2 = 0;
1165   sendSignal(calcNdbCntrBlockRef(nodeId), GSN_SYSTEM_ERROR, signal,
1166 	     SystemError::SignalLength, JBB);
1167   return;
1168 }//Dbdih::execSTART_FRAGCONF()
1169 
execSTART_MEREF(Signal * signal)1170 void Dbdih::execSTART_MEREF(Signal* signal)
1171 {
1172   jamEntry();
1173   ndbrequire(false);
1174 }//Dbdih::execSTART_MEREF()
1175 
execTAB_COMMITREQ(Signal * signal)1176 void Dbdih::execTAB_COMMITREQ(Signal* signal)
1177 {
1178   TabRecordPtr tabPtr;
1179   jamEntry();
1180   Uint32 tdictPtr = signal->theData[0];
1181   BlockReference tdictBlockref = signal->theData[1];
1182   tabPtr.i = signal->theData[2];
1183   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
1184 
1185   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_CREATING);
1186   tabPtr.p->tabStatus = TabRecord::TS_ACTIVE;
1187   signal->theData[0] = tdictPtr;
1188   signal->theData[1] = cownNodeId;
1189   signal->theData[2] = tabPtr.i;
1190   sendSignal(tdictBlockref, GSN_TAB_COMMITCONF, signal, 3, JBB);
1191   return;
1192 }//Dbdih::execTAB_COMMITREQ()
1193 
1194 /*
1195   3.2   S T A N D A R D   S U B P R O G R A M S   I N   P L E X
1196   *************************************************************
1197   */
1198 /*
1199   3.2.1   S T A R T /  R E S T A R T
1200   **********************************
1201   */
1202 /*****************************************************************************/
1203 /* **********     START / RESTART MODULE                         *************/
1204 /*****************************************************************************/
1205 /*
1206   3.2.1.1    LOADING   O W N   B L O C K  R E F E R E N C E (ABSOLUTE PHASE 1)
1207   *****************************************************************************
1208   */
execDIH_RESTARTREQ(Signal * signal)1209 void Dbdih::execDIH_RESTARTREQ(Signal* signal)
1210 {
1211   jamEntry();
1212   if (signal->theData[0])
1213   {
1214     jam();
1215     cntrlblockref = signal->theData[0];
1216     if(m_ctx.m_config.getInitialStart()){
1217       sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
1218     } else {
1219       readGciFileLab(signal);
1220     }
1221   }
1222   else
1223   {
1224     /**
1225      * Precondition, (not checked)
1226      *   atleast 1 node in each node group
1227      */
1228     Uint32 i;
1229     NdbNodeBitmask mask;
1230     mask.assign(NdbNodeBitmask::Size, signal->theData + 1);
1231     Uint32 *node_gcis = signal->theData+1+NdbNodeBitmask::Size;
1232     Uint32 node_group_gcis[MAX_NDB_NODES+1];
1233     bzero(node_group_gcis, sizeof(node_group_gcis));
1234     for (i = 0; i<MAX_NDB_NODES; i++)
1235     {
1236       if (mask.get(i))
1237       {
1238 	jam();
1239 	Uint32 ng = Sysfile::getNodeGroup(i, SYSFILE->nodeGroups);
1240 	ndbrequire(ng < MAX_NDB_NODES);
1241 	Uint32 gci = node_gcis[i];
1242         if (gci < SYSFILE->lastCompletedGCI[i])
1243         {
1244           jam();
1245           /**
1246            * Handle case, where *I* know that node complete GCI
1247            *   but node does not...bug#29167
1248            *   i.e node died before it wrote own sysfile
1249            */
1250           gci = SYSFILE->lastCompletedGCI[i];
1251         }
1252 
1253 	if (gci > node_group_gcis[ng])
1254 	{
1255 	  jam();
1256 	  node_group_gcis[ng] = gci;
1257 	}
1258       }
1259     }
1260     for (i = 0; i<MAX_NDB_NODES && node_group_gcis[i] == 0; i++);
1261 
1262     Uint32 gci = node_group_gcis[i];
1263     for (i++ ; i<MAX_NDB_NODES; i++)
1264     {
1265       jam();
1266       if (node_group_gcis[i] && node_group_gcis[i] != gci)
1267       {
1268 	jam();
1269 	signal->theData[0] = i;
1270 	return;
1271       }
1272     }
1273     signal->theData[0] = MAX_NDB_NODES;
1274     return;
1275   }
1276   return;
1277 }//Dbdih::execDIH_RESTARTREQ()
1278 
execSTTOR(Signal * signal)1279 void Dbdih::execSTTOR(Signal* signal)
1280 {
1281   jamEntry();
1282 
1283   signal->theData[0] = 0;
1284   signal->theData[1] = 0;
1285   signal->theData[2] = 0;
1286   signal->theData[3] = 1;   // Next start phase
1287   signal->theData[4] = 255; // Next start phase
1288   sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
1289   return;
1290 }//Dbdih::execSTTOR()
1291 
initialStartCompletedLab(Signal * signal)1292 void Dbdih::initialStartCompletedLab(Signal* signal)
1293 {
1294   /*-------------------------------------------------------------------------*/
1295   /* NOW THAT (RE)START IS COMPLETED WE CAN START THE LCP.*/
1296   /*-------------------------------------------------------------------------*/
1297   return;
1298 }//Dbdih::initialStartCompletedLab()
1299 
1300 /*
1301  * ***************************************************************************
1302  * S E N D I N G   R E P L Y  T O  S T A R T /  R E S T A R T   R E Q U E S T S
1303  * ****************************************************************************
1304  */
ndbsttorry10Lab(Signal * signal,Uint32 _line)1305 void Dbdih::ndbsttorry10Lab(Signal* signal, Uint32 _line)
1306 {
1307   /*-------------------------------------------------------------------------*/
1308   // AN NDB START PHASE HAS BEEN COMPLETED. WHEN START PHASE 6 IS COMPLETED WE
1309   // RECORD THAT THE SYSTEM IS RUNNING.
1310   /*-------------------------------------------------------------------------*/
1311   signal->theData[0] = reference();
1312   sendSignal(cntrlblockref, GSN_NDB_STTORRY, signal, 1, JBB);
1313   return;
1314 }//Dbdih::ndbsttorry10Lab()
1315 
1316 /*
1317 ****************************************
1318 I N T E R N A L  P H A S E S
1319 ****************************************
1320 */
1321 /*---------------------------------------------------------------------------*/
1322 /*NDB_STTOR                              START SIGNAL AT START/RESTART       */
1323 /*---------------------------------------------------------------------------*/
execNDB_STTOR(Signal * signal)1324 void Dbdih::execNDB_STTOR(Signal* signal)
1325 {
1326   jamEntry();
1327   BlockReference cntrRef = signal->theData[0];    /* SENDERS BLOCK REFERENCE */
1328   Uint32 ownNodeId = signal->theData[1];          /* OWN PROCESSOR ID*/
1329   Uint32 phase = signal->theData[2];              /* INTERNAL START PHASE*/
1330   Uint32 typestart = signal->theData[3];
1331 
1332   cstarttype = typestart;
1333   cstartPhase = phase;
1334 
1335   switch (phase){
1336   case ZNDB_SPH1:
1337     jam();
1338     /*----------------------------------------------------------------------*/
1339     /* Set the delay between local checkpoints in ndb startphase 1.         */
1340     /*----------------------------------------------------------------------*/
1341     cownNodeId = ownNodeId;
1342     /*-----------------------------------------------------------------------*/
1343     // Compute all static block references in this node as part of
1344     // ndb start phase 1.
1345     /*-----------------------------------------------------------------------*/
1346     cntrlblockref = cntrRef;
1347     clocaltcblockref = calcTcBlockRef(ownNodeId);
1348     clocallqhblockref = calcLqhBlockRef(ownNodeId);
1349     cdictblockref = calcDictBlockRef(ownNodeId);
1350     ndbsttorry10Lab(signal, __LINE__);
1351     break;
1352 
1353   case ZNDB_SPH2:
1354     jam();
1355     /*-----------------------------------------------------------------------*/
1356     // Set the number of replicas,  maximum is 4 replicas.
1357     // Read the ndb nodes from the configuration.
1358     /*-----------------------------------------------------------------------*/
1359 
1360     /*-----------------------------------------------------------------------*/
1361     // For node restarts we will also add a request for permission
1362     // to continue the system restart.
1363     // The permission is given by the master node in the alive set.
1364     /*-----------------------------------------------------------------------*/
1365     createMutexes(signal, 0);
1366     if (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)
1367     {
1368       jam();
1369       c_set_initial_start_flag = TRUE; // In sysfile...
1370     }
1371     break;
1372 
1373   case ZNDB_SPH3:
1374     jam();
1375     /*-----------------------------------------------------------------------*/
1376     // Non-master nodes performing an initial start will execute
1377     // the start request here since the
1378     // initial start do not synchronise so much from the master.
1379     // In the master nodes the start
1380     // request will be sent directly to dih (in ndb_startreq) when all
1381     // nodes have completed phase 3 of the start.
1382     /*-----------------------------------------------------------------------*/
1383     cmasterState = MASTER_IDLE;
1384     if(cstarttype == NodeState::ST_INITIAL_START ||
1385        cstarttype == NodeState::ST_SYSTEM_RESTART){
1386       jam();
1387       cmasterState = isMaster() ? MASTER_ACTIVE : MASTER_IDLE;
1388     }
1389     if (!isMaster() && cstarttype == NodeState::ST_INITIAL_START) {
1390       jam();
1391       ndbStartReqLab(signal, cntrRef);
1392       return;
1393     }//if
1394     ndbsttorry10Lab(signal, __LINE__);
1395     break;
1396 
1397   case ZNDB_SPH4:
1398     jam();
1399     c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
1400     cmasterTakeOverNode = ZNIL;
1401     switch(typestart){
1402     case NodeState::ST_INITIAL_START:
1403       jam();
1404       ndbsttorry10Lab(signal, __LINE__);
1405       return;
1406     case NodeState::ST_SYSTEM_RESTART:
1407       jam();
1408       if (isMaster()) {
1409 	jam();
1410 	systemRestartTakeOverLab(signal);
1411 	if (anyActiveTakeOver())
1412 	{
1413 	  jam();
1414 	  return;
1415 	}
1416       }
1417       ndbsttorry10Lab(signal, __LINE__);
1418       return;
1419     case NodeState::ST_INITIAL_NODE_RESTART:
1420     case NodeState::ST_NODE_RESTART:
1421       jam();
1422 
1423       /***********************************************************************
1424        * When starting nodes while system is operational we must be controlled
1425        * by the master since only one node restart is allowed at a time.
1426        * When this signal is confirmed the master has also copied the
1427        * dictionary and the distribution information.
1428        */
1429       StartMeReq * req = (StartMeReq*)&signal->theData[0];
1430       req->startingRef = reference();
1431       req->startingVersion = 0; // Obsolete
1432       sendSignal(cmasterdihref, GSN_START_MEREQ, signal,
1433                  StartMeReq::SignalLength, JBB);
1434       return;
1435     }
1436     ndbrequire(false);
1437     break;
1438   case ZNDB_SPH5:
1439     jam();
1440     switch(typestart){
1441     case NodeState::ST_INITIAL_START:
1442     case NodeState::ST_SYSTEM_RESTART:
1443       jam();
1444       jam();
1445       /*---------------------------------------------------------------------*/
1446       // WE EXECUTE A LOCAL CHECKPOINT AS A PART OF A SYSTEM RESTART.
1447       // THE IDEA IS THAT WE NEED TO
1448       // ENSURE THAT WE CAN RECOVER FROM PROBLEMS CAUSED BY MANY NODE
1449       // CRASHES THAT CAUSES THE LOG
1450       // TO GROW AND THE NUMBER OF LOG ROUNDS TO EXECUTE TO GROW.
1451       // THIS CAN OTHERWISE GET US INTO
1452       // A SITUATION WHICH IS UNREPAIRABLE. THUS WE EXECUTE A CHECKPOINT
1453       // BEFORE ALLOWING ANY TRANSACTIONS TO START.
1454       /*---------------------------------------------------------------------*/
1455       if (!isMaster()) {
1456 	jam();
1457 	ndbsttorry10Lab(signal, __LINE__);
1458 	return;
1459       }//if
1460 
1461       c_lcpState.immediateLcpStart = true;
1462       cwaitLcpSr = true;
1463       checkLcpStart(signal, __LINE__);
1464       return;
1465     case NodeState::ST_NODE_RESTART:
1466     case NodeState::ST_INITIAL_NODE_RESTART:
1467       jam();
1468       signal->theData[0] = cownNodeId;
1469       signal->theData[1] = reference();
1470       sendSignal(cmasterdihref, GSN_START_COPYREQ, signal, 2, JBB);
1471       return;
1472     }
1473     ndbrequire(false);
1474   case ZNDB_SPH6:
1475     jam();
1476     switch(typestart){
1477     case NodeState::ST_INITIAL_START:
1478     case NodeState::ST_SYSTEM_RESTART:
1479       jam();
1480       if(isMaster()){
1481 	jam();
1482 	startGcp(signal);
1483       }
1484       ndbsttorry10Lab(signal, __LINE__);
1485       return;
1486     case NodeState::ST_NODE_RESTART:
1487     case NodeState::ST_INITIAL_NODE_RESTART:
1488       ndbsttorry10Lab(signal, __LINE__);
1489       return;
1490     }
1491     ndbrequire(false);
1492     break;
1493   default:
1494     jam();
1495     ndbsttorry10Lab(signal, __LINE__);
1496     break;
1497   }//switch
1498 }//Dbdih::execNDB_STTOR()
1499 
1500 void
execNODE_START_REP(Signal * signal)1501 Dbdih::execNODE_START_REP(Signal* signal)
1502 {
1503   /*
1504    * Send DICT_UNLOCK_ORD when this node is SL_STARTED.
1505    *
1506    * Sending it before (sp 7) conflicts with code which assumes
1507    * SL_STARTING means we are in copy phase of NR.
1508    *
1509    * NodeState::starting.restartType is not supposed to be used
1510    * when SL_STARTED.  Also it seems NODE_START_REP can arrive twice.
1511    *
1512    * For these reasons there are no consistency checks and
1513    * we rely on c_dictLockSlavePtrI_nodeRestart alone.
1514    */
1515   if (c_dictLockSlavePtrI_nodeRestart != RNIL) {
1516     sendDictUnlockOrd(signal, c_dictLockSlavePtrI_nodeRestart);
1517     c_dictLockSlavePtrI_nodeRestart = RNIL;
1518   }
1519 }
1520 
1521 void
createMutexes(Signal * signal,Uint32 count)1522 Dbdih::createMutexes(Signal * signal, Uint32 count){
1523   Callback c = { safe_cast(&Dbdih::createMutex_done), count };
1524 
1525   switch(count){
1526   case 0:{
1527     Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
1528     mutex.create(c);
1529     return;
1530   }
1531   case 1:{
1532     Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
1533     mutex.create(c);
1534     return;
1535   }
1536   }
1537 
1538   signal->theData[0] = reference();
1539   sendSignal(cntrlblockref, GSN_READ_NODESREQ, signal, 1, JBB);
1540 }
1541 
1542 void
createMutex_done(Signal * signal,Uint32 senderData,Uint32 retVal)1543 Dbdih::createMutex_done(Signal* signal, Uint32 senderData, Uint32 retVal){
1544   jamEntry();
1545   ndbrequire(retVal == 0);
1546 
1547   switch(senderData){
1548   case 0:{
1549     Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
1550     mutex.release();
1551   }
1552   case 1:{
1553     Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
1554     mutex.release();
1555   }
1556   }
1557 
1558   createMutexes(signal, senderData + 1);
1559 }
1560 
1561 /*****************************************************************************/
1562 /* ------------------------------------------------------------------------- */
1563 /*       WE HAVE BEEN REQUESTED BY NDBCNTR TO PERFORM A RESTART OF THE       */
1564 /*       DATABASE TABLES.                                                    */
1565 /*       THIS SIGNAL IS SENT AFTER COMPLETING PHASE 3 IN ALL BLOCKS IN A     */
1566 /*       SYSTEM RESTART. WE WILL ALSO JUMP TO THIS LABEL FROM PHASE 3 IN AN  */
1567 /*       INITIAL START.                                                      */
1568 /* ------------------------------------------------------------------------- */
1569 /*****************************************************************************/
execNDB_STARTREQ(Signal * signal)1570 void Dbdih::execNDB_STARTREQ(Signal* signal)
1571 {
1572   jamEntry();
1573   BlockReference ref = signal->theData[0];
1574   cstarttype = signal->theData[1];
1575   ndbStartReqLab(signal, ref);
1576 }//Dbdih::execNDB_STARTREQ()
1577 
ndbStartReqLab(Signal * signal,BlockReference ref)1578 void Dbdih::ndbStartReqLab(Signal* signal, BlockReference ref)
1579 {
1580   cndbStartReqBlockref = ref;
1581   if (cstarttype == NodeState::ST_INITIAL_START) {
1582     jam();
1583     initRestartInfo();
1584     initGciFilesLab(signal);
1585     return;
1586   }
1587 
1588   NodeRecordPtr nodePtr;
1589   Uint32 gci = SYSFILE->lastCompletedGCI[getOwnNodeId()];
1590   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++)
1591   {
1592     jam();
1593     ptrAss(nodePtr, nodeRecord);
1594     if (SYSFILE->lastCompletedGCI[nodePtr.i] > gci)
1595     {
1596       jam();
1597       /**
1598        * Since we're starting(is master) and there
1599        *   there are other nodes with higher GCI...
1600        *   there gci's must be invalidated...
1601        *   and they _must_ do an initial start
1602        *   indicate this by setting lastCompletedGCI = 0
1603        */
1604       SYSFILE->lastCompletedGCI[nodePtr.i] = 0;
1605       ndbrequire(nodePtr.p->nodeStatus != NodeRecord::ALIVE);
1606       warningEvent("Making filesystem for node %d unusable (need --initial)",
1607 		   nodePtr.i);
1608     }
1609     else if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
1610 	     SYSFILE->lastCompletedGCI[nodePtr.i] == 0)
1611     {
1612       jam();
1613       CRASH_INSERTION(7170);
1614       char buf[255];
1615       BaseString::snprintf(buf, sizeof(buf),
1616 			   "Cluster requires this node to be started "
1617 			   " with --initial as partial start has been performed"
1618 			   " and this filesystem is unusable");
1619       progError(__LINE__,
1620 		NDBD_EXIT_SR_RESTARTCONFLICT,
1621 		buf);
1622       ndbrequire(false);
1623     }
1624   }
1625 
1626   /**
1627    * This set which GCI we will try to restart to
1628    */
1629   SYSFILE->newestRestorableGCI = gci;
1630 
1631   ndbrequire(isMaster());
1632   copyGciLab(signal, CopyGCIReq::RESTART); // We have already read the file!
1633 }//Dbdih::ndbStartReqLab()
1634 
execREAD_NODESCONF(Signal * signal)1635 void Dbdih::execREAD_NODESCONF(Signal* signal)
1636 {
1637   unsigned i;
1638   ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
1639   jamEntry();
1640   Uint32 nodeArray[MAX_NDB_NODES];
1641 
1642   csystemnodes  = readNodes->noOfNodes;
1643   cmasterNodeId = readNodes->masterNodeId;
1644   int index = 0;
1645   NdbNodeBitmask tmp; tmp.assign(2, readNodes->allNodes);
1646   for (i = 1; i < MAX_NDB_NODES; i++){
1647     jam();
1648     if(tmp.get(i)){
1649       jam();
1650       nodeArray[index] = i;
1651       if(NodeBitmask::get(readNodes->inactiveNodes, i) == false){
1652         jam();
1653         con_lineNodes++;
1654       }//if
1655       index++;
1656     }//if
1657   }//for
1658 
1659   if(cstarttype == NodeState::ST_SYSTEM_RESTART ||
1660      cstarttype == NodeState::ST_NODE_RESTART){
1661 
1662     for(i = 1; i<MAX_NDB_NODES; i++){
1663       const Uint32 stat = Sysfile::getNodeStatus(i, SYSFILE->nodeStatus);
1664       if(stat == Sysfile::NS_NotDefined && !tmp.get(i)){
1665 	jam();
1666 	continue;
1667       }
1668 
1669       if(tmp.get(i) && stat != Sysfile::NS_NotDefined){
1670 	jam();
1671 	continue;
1672       }
1673       char buf[255];
1674       BaseString::snprintf(buf, sizeof(buf),
1675 	       "Illegal configuration change."
1676 	       " Initial start needs to be performed "
1677 	       " when changing no of storage nodes (node %d)", i);
1678       progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
1679     }
1680   }
1681 
1682   ndbrequire(csystemnodes >= 1 && csystemnodes < MAX_NDB_NODES);
1683   if (cstarttype == NodeState::ST_INITIAL_START) {
1684     jam();
1685     ndbrequire(cnoReplicas <= csystemnodes);
1686     calculateHotSpare();
1687     ndbrequire(cnoReplicas <= (csystemnodes - cnoHotSpare));
1688   }//if
1689 
1690   cmasterdihref = calcDihBlockRef(cmasterNodeId);
1691   /*-------------------------------------------------------------------------*/
1692   /* MAKE THE LIST OF PRN-RECORD WHICH IS ONE OF THE NODES-LIST IN THIS BLOCK*/
1693   /*-------------------------------------------------------------------------*/
1694   makePrnList(readNodes, nodeArray);
1695   if (cstarttype == NodeState::ST_INITIAL_START) {
1696     jam();
1697     /**----------------------------------------------------------------------
1698      * WHEN WE INITIALLY START A DATABASE WE WILL CREATE NODE GROUPS.
1699      * ALL NODES ARE PUT INTO NODE GROUPS ALTHOUGH HOT SPARE NODES ARE PUT
1700      * INTO A SPECIAL NODE GROUP. IN EACH NODE GROUP WE HAVE THE SAME AMOUNT
1701      * OF NODES AS THERE ARE NUMBER OF REPLICAS.
1702      * ONE POSSIBLE USAGE OF NODE GROUPS ARE TO MAKE A NODE GROUP A COMPLETE
1703      * FRAGMENT OF THE DATABASE. THIS MEANS THAT ALL REPLICAS WILL BE STORED
1704      * IN THE NODE GROUP.
1705      *-----------------------------------------------------------------------*/
1706     makeNodeGroups(nodeArray);
1707   }//if
1708   ndbrequire(checkNodeAlive(cmasterNodeId));
1709   if (cstarttype == NodeState::ST_INITIAL_START) {
1710     jam();
1711     /**-----------------------------------------------------------------------
1712      * INITIALISE THE SECOND NODE-LIST AND SET NODE BITS AND SOME NODE STATUS.
1713      * VERY CONNECTED WITH MAKE_NODE_GROUPS. CHANGING ONE WILL AFFECT THE
1714      * OTHER AS WELL.
1715      *-----------------------------------------------------------------------*/
1716     setInitialActiveStatus();
1717   } else if (cstarttype == NodeState::ST_SYSTEM_RESTART) {
1718     jam();
1719     /*empty*/;
1720   } else if ((cstarttype == NodeState::ST_NODE_RESTART) ||
1721              (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)) {
1722     jam();
1723     nodeRestartPh2Lab(signal);
1724     return;
1725   } else {
1726     ndbrequire(false);
1727   }//if
1728   /**------------------------------------------------------------------------
1729    * ESTABLISH CONNECTIONS WITH THE OTHER DIH BLOCKS AND INITIALISE THIS
1730    * NODE-LIST THAT HANDLES CONNECTION WITH OTHER DIH BLOCKS.
1731    *-------------------------------------------------------------------------*/
1732   ndbsttorry10Lab(signal, __LINE__);
1733 }//Dbdih::execREAD_NODESCONF()
1734 
1735 /*---------------------------------------------------------------------------*/
1736 /*                    START NODE LOGIC FOR NODE RESTART                      */
1737 /*---------------------------------------------------------------------------*/
nodeRestartPh2Lab(Signal * signal)1738 void Dbdih::nodeRestartPh2Lab(Signal* signal)
1739 {
1740   /*
1741    * Lock master DICT to avoid metadata operations during INR/NR.
1742    * Done just before START_PERMREQ.
1743    *
1744    * It would be more elegant to do this just before START_MEREQ.
1745    * The problem is, on INR we end up in massive invalidateNodeLCP
1746    * which is not fully protected against metadata ops.
1747    */
1748   ndbrequire(c_dictLockSlavePtrI_nodeRestart == RNIL);
1749 
1750   // check that we are not yet taking part in schema ops
1751   CRASH_INSERTION(7174);
1752 
1753   Uint32 lockType = DictLockReq::NodeRestartLock;
1754   Callback c = { safe_cast(&Dbdih::recvDictLockConf_nodeRestart), 0 };
1755   sendDictLockReq(signal, lockType, c);
1756 }
1757 
recvDictLockConf_nodeRestart(Signal * signal,Uint32 data,Uint32 ret)1758 void Dbdih::recvDictLockConf_nodeRestart(Signal* signal, Uint32 data, Uint32 ret)
1759 {
1760   ndbrequire(c_dictLockSlavePtrI_nodeRestart == RNIL);
1761   ndbrequire(data != RNIL);
1762   c_dictLockSlavePtrI_nodeRestart = data;
1763 
1764   nodeRestartPh2Lab2(signal);
1765 }
1766 
nodeRestartPh2Lab2(Signal * signal)1767 void Dbdih::nodeRestartPh2Lab2(Signal* signal)
1768 {
1769   /*------------------------------------------------------------------------*/
1770   // REQUEST FOR PERMISSION FROM MASTER TO START A NODE IN AN ALREADY
1771   // RUNNING SYSTEM.
1772   /*------------------------------------------------------------------------*/
1773   StartPermReq * const req = (StartPermReq *)&signal->theData[0];
1774 
1775   req->blockRef  = reference();
1776   req->nodeId    = cownNodeId;
1777   req->startType = cstarttype;
1778   sendSignal(cmasterdihref, GSN_START_PERMREQ, signal, 3, JBB);
1779 }
1780 
execSTART_PERMCONF(Signal * signal)1781 void Dbdih::execSTART_PERMCONF(Signal* signal)
1782 {
1783   jamEntry();
1784   CRASH_INSERTION(7121);
1785   Uint32 nodeId = signal->theData[0];
1786   cfailurenr = signal->theData[1];
1787   ndbrequire(nodeId == cownNodeId);
1788   ndbsttorry10Lab(signal, __LINE__);
1789 }//Dbdih::execSTART_PERMCONF()
1790 
execSTART_PERMREF(Signal * signal)1791 void Dbdih::execSTART_PERMREF(Signal* signal)
1792 {
1793   jamEntry();
1794   Uint32 errorCode = signal->theData[1];
1795   if (errorCode == StartPermRef::ZNODE_ALREADY_STARTING_ERROR ||
1796       errorCode == StartPermRef::ZNODE_START_DISALLOWED_ERROR) {
1797     jam();
1798     /*-----------------------------------------------------------------------*/
1799     // The master was busy adding another node. We will wait for a second and
1800     // try again.
1801     /*-----------------------------------------------------------------------*/
1802     signal->theData[0] = DihContinueB::ZSTART_PERMREQ_AGAIN;
1803     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 3000, 1);
1804     return;
1805   }//if
1806 
1807   if (errorCode == StartPermRef::InitialStartRequired)
1808   {
1809     CRASH_INSERTION(7170);
1810     char buf[255];
1811     BaseString::snprintf(buf, sizeof(buf),
1812 			 "Cluster requires this node to be started "
1813 			 " with --initial as partial start has been performed"
1814 			 " and this filesystem is unusable");
1815     progError(__LINE__,
1816 	      NDBD_EXIT_SR_RESTARTCONFLICT,
1817 	      buf);
1818     ndbrequire(false);
1819   }
1820   /*------------------------------------------------------------------------*/
1821   // Some node process in another node involving our node was still active. We
1822   // will recover from this by crashing here.
1823   // This is controlled restart using the
1824   // already existing features of node crashes. It is not a bug getting here.
1825   /*-------------------------------------------------------------------------*/
1826   ndbrequire(false);
1827   return;
1828 }//Dbdih::execSTART_PERMREF()
1829 
1830 /*---------------------------------------------------------------------------*/
1831 /*       THIS SIGNAL IS RECEIVED IN THE STARTING NODE WHEN THE START_MEREQ   */
1832 /*       HAS BEEN EXECUTED IN THE MASTER NODE.                               */
1833 /*---------------------------------------------------------------------------*/
execSTART_MECONF(Signal * signal)1834 void Dbdih::execSTART_MECONF(Signal* signal)
1835 {
1836   jamEntry();
1837   StartMeConf * const startMe = (StartMeConf *)&signal->theData[0];
1838   Uint32 nodeId = startMe->startingNodeId;
1839   const Uint32 startWord = startMe->startWord;
1840   Uint32 i;
1841 
1842   CRASH_INSERTION(7130);
1843   ndbrequire(nodeId == cownNodeId);
1844   arrGuard(startWord + StartMeConf::DATA_SIZE, sizeof(cdata)/4);
1845   for(i = 0; i < StartMeConf::DATA_SIZE; i++)
1846     cdata[startWord+i] = startMe->data[i];
1847 
1848   if(startWord + StartMeConf::DATA_SIZE < Sysfile::SYSFILE_SIZE32){
1849     jam();
1850     /**
1851      * We are still waiting for data
1852      */
1853     return;
1854   }
1855   jam();
1856 
1857   /**
1858    * Copy into sysfile
1859    *
1860    * But dont copy lastCompletedGCI:s
1861    */
1862   Uint32 key = SYSFILE->m_restart_seq;
1863   Uint32 tempGCP[MAX_NDB_NODES];
1864   for(i = 0; i < MAX_NDB_NODES; i++)
1865     tempGCP[i] = SYSFILE->lastCompletedGCI[i];
1866 
1867   for(i = 0; i < Sysfile::SYSFILE_SIZE32; i++)
1868     sysfileData[i] = cdata[i];
1869 
1870   SYSFILE->m_restart_seq = key;
1871   for(i = 0; i < MAX_NDB_NODES; i++)
1872     SYSFILE->lastCompletedGCI[i] = tempGCP[i];
1873 
1874   setNodeActiveStatus();
1875   setNodeGroups();
1876   ndbsttorry10Lab(signal, __LINE__);
1877 }//Dbdih::execSTART_MECONF()
1878 
execSTART_COPYCONF(Signal * signal)1879 void Dbdih::execSTART_COPYCONF(Signal* signal)
1880 {
1881   jamEntry();
1882   Uint32 nodeId = signal->theData[0];
1883   ndbrequire(nodeId == cownNodeId);
1884   CRASH_INSERTION(7132);
1885   ndbsttorry10Lab(signal, __LINE__);
1886   return;
1887 }//Dbdih::execSTART_COPYCONF()
1888 
1889 /*---------------------------------------------------------------------------*/
1890 /*                    MASTER LOGIC FOR NODE RESTART                          */
1891 /*---------------------------------------------------------------------------*/
1892 /*                    NODE RESTART PERMISSION REQUEST                        */
1893 /*---------------------------------------------------------------------------*/
1894 // A REQUEST FROM A STARTING NODE TO PERFORM A NODE RESTART. IF NO OTHER NODE
1895 // IS ACTIVE IN PERFORMING A NODE RESTART AND THERE ARE NO ACTIVE PROCESSES IN
1896 // THIS NODE INVOLVING THE STARTING NODE  THIS REQUEST WILL BE GRANTED.
1897 /*---------------------------------------------------------------------------*/
execSTART_PERMREQ(Signal * signal)1898 void Dbdih::execSTART_PERMREQ(Signal* signal)
1899 {
1900   StartPermReq * const req = (StartPermReq*)&signal->theData[0];
1901   jamEntry();
1902   const BlockReference retRef = req->blockRef;
1903   const Uint32 nodeId   = req->nodeId;
1904   const Uint32 typeStart = req->startType;
1905   CRASH_INSERTION(7122);
1906   ndbrequire(isMaster());
1907   ndbrequire(refToNode(retRef) == nodeId);
1908   if ((c_nodeStartMaster.activeState) ||
1909       (c_nodeStartMaster.wait != ZFALSE) ||
1910       ERROR_INSERTED_CLEAR(7175)) {
1911     jam();
1912     signal->theData[0] = nodeId;
1913     signal->theData[1] = StartPermRef::ZNODE_ALREADY_STARTING_ERROR;
1914     sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
1915     return;
1916   }//if
1917   if (getNodeStatus(nodeId) != NodeRecord::DEAD){
1918     g_eventLogger.error("nodeStatus in START_PERMREQ = %u",
1919                         (Uint32) getNodeStatus(nodeId));
1920     ndbrequire(false);
1921   }//if
1922 
1923   if (SYSFILE->lastCompletedGCI[nodeId] == 0 &&
1924       typeStart != NodeState::ST_INITIAL_NODE_RESTART)
1925   {
1926     jam();
1927     signal->theData[0] = nodeId;
1928     signal->theData[1] = StartPermRef::InitialStartRequired;
1929     sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
1930     return;
1931   }
1932 
1933   /*----------------------------------------------------------------------
1934    * WE START THE INCLUSION PROCEDURE
1935    * ---------------------------------------------------------------------*/
1936   c_nodeStartMaster.failNr   = cfailurenr;
1937   c_nodeStartMaster.wait     = ZFALSE;
1938   c_nodeStartMaster.startInfoErrorCode = 0;
1939   c_nodeStartMaster.startNode = nodeId;
1940   c_nodeStartMaster.activeState = true;
1941   c_nodeStartMaster.m_outstandingGsn =  GSN_START_INFOREQ;
1942 
1943   setNodeStatus(nodeId, NodeRecord::STARTING);
1944   /**
1945    * But if it's a NodeState::ST_INITIAL_NODE_RESTART
1946    *
1947    * We first have to clear LCP's
1948    * For normal node restart we simply ensure that all nodes
1949    * are informed of the node restart
1950    */
1951   StartInfoReq *const r =(StartInfoReq*)&signal->theData[0];
1952   r->startingNodeId = nodeId;
1953   r->typeStart = typeStart;
1954   r->systemFailureNo = cfailurenr;
1955   sendLoopMacro(START_INFOREQ, sendSTART_INFOREQ);
1956 }//Dbdih::execSTART_PERMREQ()
1957 
execSTART_INFOREF(Signal * signal)1958 void Dbdih::execSTART_INFOREF(Signal* signal)
1959 {
1960   StartInfoRef * ref = (StartInfoRef*)&signal->theData[0];
1961   if (getNodeStatus(ref->startingNodeId) != NodeRecord::STARTING) {
1962     jam();
1963     return;
1964   }//if
1965   ndbrequire(c_nodeStartMaster.startNode == ref->startingNodeId);
1966   c_nodeStartMaster.startInfoErrorCode = ref->errorCode;
1967   startInfoReply(signal, ref->sendingNodeId);
1968 }//Dbdih::execSTART_INFOREF()
1969 
execSTART_INFOCONF(Signal * signal)1970 void Dbdih::execSTART_INFOCONF(Signal* signal)
1971 {
1972   jamEntry();
1973   StartInfoConf * conf = (StartInfoConf*)&signal->theData[0];
1974   if (getNodeStatus(conf->startingNodeId) != NodeRecord::STARTING) {
1975     jam();
1976     return;
1977   }//if
1978   ndbrequire(c_nodeStartMaster.startNode == conf->startingNodeId);
1979   startInfoReply(signal, conf->sendingNodeId);
1980 }//Dbdih::execSTART_INFOCONF()
1981 
startInfoReply(Signal * signal,Uint32 nodeId)1982 void Dbdih::startInfoReply(Signal* signal, Uint32 nodeId)
1983 {
1984   receiveLoopMacro(START_INFOREQ, nodeId);
1985   /**
1986    * We're finished with the START_INFOREQ's
1987    */
1988   if (c_nodeStartMaster.startInfoErrorCode == 0) {
1989     jam();
1990     /**
1991      * Everything has been a success so far
1992      */
1993     StartPermConf * conf = (StartPermConf*)&signal->theData[0];
1994     conf->startingNodeId = c_nodeStartMaster.startNode;
1995     conf->systemFailureNo = cfailurenr;
1996     sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode),
1997 	       GSN_START_PERMCONF, signal, StartPermConf::SignalLength, JBB);
1998     c_nodeStartMaster.m_outstandingGsn = GSN_START_PERMCONF;
1999   } else {
2000     jam();
2001     StartPermRef * ref = (StartPermRef*)&signal->theData[0];
2002     ref->startingNodeId = c_nodeStartMaster.startNode;
2003     ref->errorCode = c_nodeStartMaster.startInfoErrorCode;
2004     sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode),
2005 	       GSN_START_PERMREF, signal, StartPermRef::SignalLength, JBB);
2006     nodeResetStart();
2007   }//if
2008 }//Dbdih::startInfoReply()
2009 
2010 /*---------------------------------------------------------------------------*/
2011 /*                    NODE RESTART CONTINUE REQUEST                          */
2012 /*---------------------------------------------------------------------------*/
2013 // THIS SIGNAL AND THE CODE BELOW IS EXECUTED BY THE MASTER WHEN IT HAS BEEN
2014 // REQUESTED TO START UP A NEW NODE. The master instructs the starting node
2015 // how to set up its log for continued execution.
2016 /*---------------------------------------------------------------------------*/
execSTART_MEREQ(Signal * signal)2017 void Dbdih::execSTART_MEREQ(Signal* signal)
2018 {
2019   StartMeReq * req = (StartMeReq*)&signal->theData[0];
2020   jamEntry();
2021   const BlockReference Tblockref = req->startingRef;
2022   const Uint32 Tnodeid = refToNode(Tblockref);
2023 
2024   ndbrequire(isMaster());
2025   ndbrequire(c_nodeStartMaster.startNode == Tnodeid);
2026   ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING);
2027 
2028   c_nodeStartMaster.blockLcp = true;
2029   if ((c_lcpState.lcpStatus != LCP_STATUS_IDLE) &&
2030       (c_lcpState.lcpStatus != LCP_TCGET)) {
2031     jam();
2032     /*-----------------------------------------------------------------------*/
2033     // WE WILL NOT ALLOW A NODE RESTART TO COME IN WHEN A LOCAL CHECKPOINT IS
2034     // ONGOING. IT WOULD COMPLICATE THE LCP PROTOCOL TOO MUCH. WE WILL ADD THIS
2035     // LATER.
2036     /*-----------------------------------------------------------------------*/
2037     return;
2038   }//if
2039   lcpBlockedLab(signal);
2040 }//Dbdih::nodeRestartStartRecConfLab()
2041 
lcpBlockedLab(Signal * signal)2042 void Dbdih::lcpBlockedLab(Signal* signal)
2043 {
2044   ndbrequire(getNodeStatus(c_nodeStartMaster.startNode)==NodeRecord::STARTING);
2045   /*------------------------------------------------------------------------*/
2046   // NOW WE HAVE COPIED ALL INFORMATION IN DICT WE ARE NOW READY TO COPY ALL
2047   // INFORMATION IN DIH TO THE NEW NODE.
2048   /*------------------------------------------------------------------------*/
2049   c_nodeStartMaster.wait = 10;
2050   signal->theData[0] = DihContinueB::ZCOPY_NODE;
2051   signal->theData[1] = 0;
2052   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2053   c_nodeStartMaster.m_outstandingGsn = GSN_COPY_TABREQ;
2054 }//Dbdih::lcpBlockedLab()
2055 
nodeDictStartConfLab(Signal * signal)2056 void Dbdih::nodeDictStartConfLab(Signal* signal)
2057 {
2058   /*-------------------------------------------------------------------------*/
2059   // NOW WE HAVE COPIED BOTH DIH AND DICT INFORMATION. WE ARE NOW READY TO
2060   // INTEGRATE THE NODE INTO THE LCP AND GCP PROTOCOLS AND TO ALLOW UPDATES OF
2061   // THE DICTIONARY AGAIN.
2062   /*-------------------------------------------------------------------------*/
2063   c_nodeStartMaster.wait = ZFALSE;
2064   c_nodeStartMaster.blockGcp = true;
2065   if (cgcpStatus != GCP_READY) {
2066     /*-----------------------------------------------------------------------*/
2067     // The global checkpoint is executing. Wait until it is completed before we
2068     // continue processing the node recovery.
2069     /*-----------------------------------------------------------------------*/
2070     jam();
2071     return;
2072   }//if
2073   gcpBlockedLab(signal);
2074 
2075   /*-----------------------------------------------------------------*/
2076   // Report that node restart has completed copy of dictionary.
2077   /*-----------------------------------------------------------------*/
2078   signal->theData[0] = NDB_LE_NR_CopyDict;
2079   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
2080 }//Dbdih::nodeDictStartConfLab()
2081 
dihCopyCompletedLab(Signal * signal)2082 void Dbdih::dihCopyCompletedLab(Signal* signal)
2083 {
2084   BlockReference ref = calcDictBlockRef(c_nodeStartMaster.startNode);
2085   DictStartReq * req = (DictStartReq*)&signal->theData[0];
2086   req->restartGci = cnewgcp;
2087   req->senderRef = reference();
2088   sendSignal(ref, GSN_DICTSTARTREQ,
2089              signal, DictStartReq::SignalLength, JBB);
2090   c_nodeStartMaster.m_outstandingGsn = GSN_DICTSTARTREQ;
2091   c_nodeStartMaster.wait = 0;
2092 }//Dbdih::dihCopyCompletedLab()
2093 
gcpBlockedLab(Signal * signal)2094 void Dbdih::gcpBlockedLab(Signal* signal)
2095 {
2096   /*-----------------------------------------------------------------*/
2097   // Report that node restart has completed copy of distribution info.
2098   /*-----------------------------------------------------------------*/
2099   signal->theData[0] = NDB_LE_NR_CopyDistr;
2100   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
2101 
2102   /**
2103    * The node DIH will be part of LCP
2104    */
2105   NodeRecordPtr nodePtr;
2106   nodePtr.i = c_nodeStartMaster.startNode;
2107   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
2108   nodePtr.p->m_inclDihLcp = true;
2109 
2110   /*-------------------------------------------------------------------------*/
2111   // NOW IT IS TIME TO INFORM ALL OTHER NODES IN THE CLUSTER OF THE STARTED
2112   // NODE SUCH THAT THEY ALSO INCLUDE THE NODE IN THE NODE LISTS AND SO FORTH.
2113   /*------------------------------------------------------------------------*/
2114   sendLoopMacro(INCL_NODEREQ, sendINCL_NODEREQ);
2115   /*-------------------------------------------------------------------------*/
2116   // We also need to send to the starting node to ensure he is aware of the
2117   // global checkpoint id and the correct state. We do not wait for any reply
2118   // since the starting node will not send any.
2119   /*-------------------------------------------------------------------------*/
2120   Uint32 startVersion = getNodeInfo(c_nodeStartMaster.startNode).m_version;
2121 
2122   if ((getMajor(startVersion) == 4 &&
2123        startVersion >= NDBD_INCL_NODECONF_VERSION_4) ||
2124       (getMajor(startVersion) == 5 &&
2125        startVersion >= NDBD_INCL_NODECONF_VERSION_5) ||
2126       (getMajor(startVersion) > 5))
2127   {
2128     c_INCL_NODEREQ_Counter.setWaitingFor(c_nodeStartMaster.startNode);
2129   }
2130 
2131   sendINCL_NODEREQ(signal, c_nodeStartMaster.startNode);
2132 }//Dbdih::gcpBlockedLab()
2133 
2134 /*---------------------------------------------------------------------------*/
2135 // THIS SIGNAL IS EXECUTED IN BOTH SLAVES AND IN THE MASTER
2136 /*---------------------------------------------------------------------------*/
execINCL_NODECONF(Signal * signal)2137 void Dbdih::execINCL_NODECONF(Signal* signal)
2138 {
2139   jamEntry();
2140   Uint32 TstartNode = signal->theData[0];
2141   Uint32 TsendNodeId_or_blockref = signal->theData[1];
2142 
2143   Uint32 blocklist[6];
2144   blocklist[0] = clocallqhblockref;
2145   blocklist[1] = clocaltcblockref;
2146   blocklist[2] = cdictblockref;
2147   blocklist[3] = numberToRef(BACKUP, getOwnNodeId());
2148   blocklist[4] = numberToRef(SUMA, getOwnNodeId());
2149   blocklist[5] = 0;
2150 
2151   for (Uint32 i = 0; blocklist[i] != 0; i++)
2152   {
2153     if (TsendNodeId_or_blockref == blocklist[i])
2154     {
2155       jam();
2156 
2157       if (TstartNode != c_nodeStartSlave.nodeId)
2158       {
2159         jam();
2160         warningEvent("Recevied INCL_NODECONF for %u from %s"
2161                      " while %u is starting",
2162                      TstartNode,
2163                      getBlockName(refToBlock(TsendNodeId_or_blockref)),
2164                      c_nodeStartSlave.nodeId);
2165         return;
2166       }
2167 
2168       if (getNodeStatus(c_nodeStartSlave.nodeId) == NodeRecord::ALIVE &&
2169 	  blocklist[i+1] != 0)
2170       {
2171 	/**
2172 	 * Send to next in block list
2173 	 */
2174 	jam();
2175 	signal->theData[0] = reference();
2176 	signal->theData[1] = c_nodeStartSlave.nodeId;
2177 	sendSignal(blocklist[i+1], GSN_INCL_NODEREQ, signal, 2, JBB);
2178 	return;
2179       }
2180       else
2181       {
2182 	/**
2183 	 * All done, reply to master
2184 	 */
2185 	jam();
2186 	signal->theData[0] = c_nodeStartSlave.nodeId;
2187 	signal->theData[1] = cownNodeId;
2188 	sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB);
2189 
2190 	c_nodeStartSlave.nodeId = 0;
2191 	return;
2192       }
2193     }
2194   }
2195 
2196   if (c_nodeStartMaster.startNode != TstartNode)
2197   {
2198     jam();
2199     warningEvent("Recevied INCL_NODECONF for %u from %u"
2200                  " while %u is starting",
2201                  TstartNode,
2202                  TsendNodeId_or_blockref,
2203                  c_nodeStartMaster.startNode);
2204     return;
2205   }
2206 
2207   ndbrequire(cmasterdihref = reference());
2208   receiveLoopMacro(INCL_NODEREQ, TsendNodeId_or_blockref);
2209 
2210   CRASH_INSERTION(7128);
2211   /*-------------------------------------------------------------------------*/
2212   // Now that we have included the starting node in the node lists in the
2213   // various blocks we are ready to start the global checkpoint protocol
2214   /*------------------------------------------------------------------------*/
2215   c_nodeStartMaster.wait = 11;
2216   c_nodeStartMaster.blockGcp = false;
2217 
2218   signal->theData[0] = reference();
2219   sendSignal(reference(), GSN_UNBLO_DICTCONF, signal, 1, JBB);
2220 }//Dbdih::execINCL_NODECONF()
2221 
execUNBLO_DICTCONF(Signal * signal)2222 void Dbdih::execUNBLO_DICTCONF(Signal* signal)
2223 {
2224   jamEntry();
2225   c_nodeStartMaster.wait = ZFALSE;
2226   if (!c_nodeStartMaster.activeState) {
2227     jam();
2228     return;
2229   }//if
2230 
2231   CRASH_INSERTION(7129);
2232   /**-----------------------------------------------------------------------
2233    * WE HAVE NOW PREPARED IT FOR INCLUSION IN THE LCP PROTOCOL.
2234    * WE CAN NOW START THE LCP PROTOCOL AGAIN.
2235    * WE HAVE ALSO MADE THIS FOR THE GCP PROTOCOL.
2236    * WE ARE READY TO START THE PROTOCOLS AND RESPOND TO THE START REQUEST
2237    * FROM THE STARTING NODE.
2238    *------------------------------------------------------------------------*/
2239 
2240   StartMeConf * const startMe = (StartMeConf *)&signal->theData[0];
2241 
2242   const Uint32 wordPerSignal = StartMeConf::DATA_SIZE;
2243   const int noOfSignals = ((Sysfile::SYSFILE_SIZE32 + (wordPerSignal - 1)) /
2244                            wordPerSignal);
2245 
2246   startMe->startingNodeId = c_nodeStartMaster.startNode;
2247   startMe->startWord = 0;
2248 
2249   const Uint32 ref = calcDihBlockRef(c_nodeStartMaster.startNode);
2250   for(int i = 0; i < noOfSignals; i++){
2251     jam();
2252     { // Do copy
2253       const int startWord = startMe->startWord;
2254       for(Uint32 j = 0; j < wordPerSignal; j++){
2255         startMe->data[j] = sysfileData[j+startWord];
2256       }
2257     }
2258     sendSignal(ref, GSN_START_MECONF, signal, StartMeConf::SignalLength, JBB);
2259     startMe->startWord += wordPerSignal;
2260   }//for
2261   c_nodeStartMaster.m_outstandingGsn = GSN_START_MECONF;
2262 }//Dbdih::execUNBLO_DICTCONF()
2263 
2264 /*---------------------------------------------------------------------------*/
2265 /*                    NODE RESTART COPY REQUEST                              */
2266 /*---------------------------------------------------------------------------*/
2267 // A NODE RESTART HAS REACHED ITS FINAL PHASE WHEN THE DATA IS TO BE COPIED
2268 // TO THE NODE. START_COPYREQ IS EXECUTED BY THE MASTER NODE.
2269 /*---------------------------------------------------------------------------*/
execSTART_COPYREQ(Signal * signal)2270 void Dbdih::execSTART_COPYREQ(Signal* signal)
2271 {
2272   jamEntry();
2273   Uint32 startNodeId = signal->theData[0];
2274   //BlockReference startingRef = signal->theData[1];
2275   ndbrequire(c_nodeStartMaster.startNode == startNodeId);
2276   /*-------------------------------------------------------------------------*/
2277   // REPORT Copy process of node restart is now about to start up.
2278   /*-------------------------------------------------------------------------*/
2279   signal->theData[0] = NDB_LE_NR_CopyFragsStarted;
2280   signal->theData[1] = startNodeId;
2281   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
2282 
2283   CRASH_INSERTION(7131);
2284   nodeRestartTakeOver(signal, startNodeId);
2285   //  BlockReference ref = calcQmgrBlockRef(startNodeId);
2286   //  signal->theData[0] = cownNodeId;
2287   // Remove comments as soon as I open up the Qmgr block
2288   // TODO_RONM
2289   //  sendSignal(ref, GSN_ALLOW_NODE_CRASHORD, signal, 1, JBB);
2290 }//Dbdih::execSTART_COPYREQ()
2291 
2292 /*---------------------------------------------------------------------------*/
2293 /*                    SLAVE LOGIC FOR NODE RESTART                           */
2294 /*---------------------------------------------------------------------------*/
execSTART_INFOREQ(Signal * signal)2295 void Dbdih::execSTART_INFOREQ(Signal* signal)
2296 {
2297   jamEntry();
2298   StartInfoReq *const req =(StartInfoReq*)&signal->theData[0];
2299   Uint32 startNode = req->startingNodeId;
2300   if (cfailurenr != req->systemFailureNo) {
2301     jam();
2302     //---------------------------------------------------------------
2303     // A failure occurred since master sent this request. We will ignore
2304     // this request since the node is already dead that is starting.
2305     //---------------------------------------------------------------
2306     return;
2307   }//if
2308   CRASH_INSERTION(7123);
2309   if (isMaster()) {
2310     jam();
2311     ndbrequire(getNodeStatus(startNode) == NodeRecord::STARTING);
2312   } else {
2313     jam();
2314     ndbrequire(getNodeStatus(startNode) == NodeRecord::DEAD);
2315   }//if
2316   if ((!getAllowNodeStart(startNode)) ||
2317       (c_nodeStartSlave.nodeId != 0) ||
2318       (ERROR_INSERTED(7124))) {
2319     jam();
2320     StartInfoRef *const ref =(StartInfoRef*)&signal->theData[0];
2321     ref->startingNodeId = startNode;
2322     ref->sendingNodeId = cownNodeId;
2323     ref->errorCode = StartPermRef::ZNODE_START_DISALLOWED_ERROR;
2324     sendSignal(cmasterdihref, GSN_START_INFOREF, signal,
2325 	       StartInfoRef::SignalLength, JBB);
2326     return;
2327   }//if
2328   setNodeStatus(startNode, NodeRecord::STARTING);
2329   if (req->typeStart == NodeState::ST_INITIAL_NODE_RESTART) {
2330     jam();
2331     setAllowNodeStart(startNode, false);
2332     invalidateNodeLCP(signal, startNode, 0);
2333   } else {
2334     jam();
2335     StartInfoConf * c = (StartInfoConf*)&signal->theData[0];
2336     c->sendingNodeId = cownNodeId;
2337     c->startingNodeId = startNode;
2338     sendSignal(cmasterdihref, GSN_START_INFOCONF, signal,
2339 	       StartInfoConf::SignalLength, JBB);
2340     return;
2341   }//if
2342 }//Dbdih::execSTART_INFOREQ()
2343 
execINCL_NODEREQ(Signal * signal)2344 void Dbdih::execINCL_NODEREQ(Signal* signal)
2345 {
2346   jamEntry();
2347   Uint32 retRef = signal->theData[0];
2348   Uint32 nodeId = signal->theData[1];
2349   if (nodeId == getOwnNodeId() && ERROR_INSERTED(7165))
2350   {
2351     CLEAR_ERROR_INSERT_VALUE;
2352     sendSignalWithDelay(reference(), GSN_INCL_NODEREQ, signal, 5000, signal->getLength());
2353     return;
2354   }
2355 
2356   Uint32 tnodeStartFailNr = signal->theData[2];
2357   currentgcp = signal->theData[4];
2358   CRASH_INSERTION(7127);
2359   cnewgcp = currentgcp;
2360   coldgcp = currentgcp -  1;
2361   if (!isMaster()) {
2362     jam();
2363     /*-----------------------------------------------------------------------*/
2364     // We don't want to change the state of the master since he can be in the
2365     // state LCP_TCGET at this time.
2366     /*-----------------------------------------------------------------------*/
2367     c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
2368   }//if
2369 
2370   /*-------------------------------------------------------------------------*/
2371   // When a node is restarted we must ensure that a lcp will be run
2372   // as soon as possible and the reset the delay according to the original
2373   // configuration.
2374   // Without an initial local checkpoint the new node will not be available.
2375   /*-------------------------------------------------------------------------*/
2376   if (getOwnNodeId() == nodeId) {
2377     jam();
2378     /*-----------------------------------------------------------------------*/
2379     // We are the starting node. We came here only to set the global checkpoint
2380     // id's and the lcp status.
2381     /*-----------------------------------------------------------------------*/
2382     CRASH_INSERTION(7171);
2383     Uint32 masterVersion = getNodeInfo(refToNode(cmasterdihref)).m_version;
2384 
2385     if ((NDB_VERSION_MAJOR == 4 &&
2386 	 masterVersion >= NDBD_INCL_NODECONF_VERSION_4) ||
2387 	(NDB_VERSION_MAJOR == 5 &&
2388 	 masterVersion >= NDBD_INCL_NODECONF_VERSION_5) ||
2389 	(NDB_VERSION_MAJOR > 5))
2390     {
2391       signal->theData[0] = getOwnNodeId();
2392       signal->theData[1] = getOwnNodeId();
2393       sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB);
2394     }
2395     return;
2396   }//if
2397   if (getNodeStatus(nodeId) != NodeRecord::STARTING) {
2398     jam();
2399     return;
2400   }//if
2401   ndbrequire(cfailurenr == tnodeStartFailNr);
2402   ndbrequire (c_nodeStartSlave.nodeId == 0);
2403   c_nodeStartSlave.nodeId = nodeId;
2404 
2405   ndbrequire (retRef == cmasterdihref);
2406 
2407   NodeRecordPtr nodePtr;
2408   nodePtr.i = nodeId;
2409   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
2410 
2411   Sysfile::ActiveStatus TsaveState = nodePtr.p->activeStatus;
2412   Uint32 TnodeGroup = nodePtr.p->nodeGroup;
2413 
2414   new (nodePtr.p) NodeRecord();
2415   nodePtr.p->nodeGroup = TnodeGroup;
2416   nodePtr.p->activeStatus = TsaveState;
2417   nodePtr.p->nodeStatus = NodeRecord::ALIVE;
2418   nodePtr.p->useInTransactions = true;
2419   nodePtr.p->m_inclDihLcp = true;
2420 
2421   removeDeadNode(nodePtr);
2422   insertAlive(nodePtr);
2423   con_lineNodes++;
2424 
2425   /*-------------------------------------------------------------------------*/
2426   //      WE WILL ALSO SEND THE INCLUDE NODE REQUEST TO THE LOCAL LQH BLOCK.
2427   /*-------------------------------------------------------------------------*/
2428   signal->theData[0] = reference();
2429   signal->theData[1] = nodeId;
2430   signal->theData[2] = currentgcp;
2431   sendSignal(clocallqhblockref, GSN_INCL_NODEREQ, signal, 3, JBB);
2432 }//Dbdih::execINCL_NODEREQ()
2433 
2434 /* ------------------------------------------------------------------------- */
2435 // execINCL_NODECONF() is found in the master logic part since it is used by
2436 // both the master and the slaves.
2437 /* ------------------------------------------------------------------------- */
2438 
2439 /*****************************************************************************/
2440 /***********     TAKE OVER DECISION  MODULE                      *************/
2441 /*****************************************************************************/
2442 // This module contains the subroutines that take the decision whether to take
2443 // over a node now or not.
2444 /* ------------------------------------------------------------------------- */
2445 /*                       MASTER LOGIC FOR SYSTEM RESTART                     */
2446 /* ------------------------------------------------------------------------- */
2447 // WE ONLY COME HERE IF WE ARE THE MASTER AND WE ARE PERFORMING A SYSTEM
2448 // RESTART. WE ALSO COME HERE DURING THIS SYSTEM RESTART ONE TIME PER NODE
2449 // THAT NEEDS TAKE OVER.
2450 /*---------------------------------------------------------------------------*/
2451 // WE CHECK IF ANY NODE NEEDS TO BE TAKEN OVER AND THE TAKE OVER HAS NOT YET
2452 // BEEN STARTED OR COMPLETED.
2453 /*---------------------------------------------------------------------------*/
2454 void
systemRestartTakeOverLab(Signal * signal)2455 Dbdih::systemRestartTakeOverLab(Signal* signal)
2456 {
2457   NodeRecordPtr nodePtr;
2458   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
2459     jam();
2460     ptrAss(nodePtr, nodeRecord);
2461     switch (nodePtr.p->activeStatus) {
2462     case Sysfile::NS_Active:
2463     case Sysfile::NS_ActiveMissed_1:
2464       jam();
2465       break;
2466       /*---------------------------------------------------------------------*/
2467       // WE HAVE NOT REACHED A STATE YET WHERE THIS NODE NEEDS TO BE TAKEN OVER
2468       /*---------------------------------------------------------------------*/
2469     case Sysfile::NS_ActiveMissed_2:
2470     case Sysfile::NS_NotActive_NotTakenOver:
2471       jam();
2472       /*---------------------------------------------------------------------*/
2473       // THIS NODE IS IN TROUBLE.
2474       // WE MUST SUCCEED WITH A LOCAL CHECKPOINT WITH THIS NODE TO REMOVE THE
2475       // DANGER. IF THE NODE IS NOT ALIVE THEN THIS WILL NOT BE
2476       // POSSIBLE AND WE CAN START THE TAKE OVER IMMEDIATELY IF WE HAVE ANY
2477       // NODES THAT CAN PERFORM A TAKE OVER.
2478       /*---------------------------------------------------------------------*/
2479       if (nodePtr.p->nodeStatus != NodeRecord::ALIVE) {
2480         jam();
2481         Uint32 ThotSpareNode = findHotSpare();
2482         if (ThotSpareNode != RNIL) {
2483           jam();
2484           startTakeOver(signal, RNIL, ThotSpareNode, nodePtr.i);
2485         }//if
2486       } else if(nodePtr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver){
2487         jam();
2488 	/*-------------------------------------------------------------------*/
2489 	// NOT ACTIVE NODES THAT HAVE NOT YET BEEN TAKEN OVER NEEDS TAKE OVER
2490 	// IMMEDIATELY. IF WE ARE ALIVE WE TAKE OVER OUR OWN NODE.
2491 	/*-------------------------------------------------------------------*/
2492 	infoEvent("Take over of node %d started",
2493 		  nodePtr.i);
2494 	startTakeOver(signal, RNIL, nodePtr.i, nodePtr.i);
2495       }//if
2496       break;
2497     case Sysfile::NS_TakeOver:
2498       /**-------------------------------------------------------------------
2499        * WE MUST HAVE FAILED IN THE MIDDLE OF THE TAKE OVER PROCESS.
2500        * WE WILL CONCLUDE THE TAKE OVER PROCESS NOW.
2501        *-------------------------------------------------------------------*/
2502       if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
2503         jam();
2504         Uint32 takeOverNode = Sysfile::getTakeOverNode(nodePtr.i,
2505 						       SYSFILE->takeOver);
2506 	if(takeOverNode == 0){
2507 	  jam();
2508 	  warningEvent("Bug in take-over code restarting");
2509 	  takeOverNode = nodePtr.i;
2510 	}
2511         startTakeOver(signal, RNIL, nodePtr.i, takeOverNode);
2512       } else {
2513         jam();
2514 	/**-------------------------------------------------------------------
2515 	 * We are not currently taking over, change our active status.
2516 	 *-------------------------------------------------------------------*/
2517         nodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
2518         setNodeRestartInfoBits();
2519       }//if
2520       break;
2521     case Sysfile::NS_HotSpare:
2522       jam();
2523       break;
2524       /*---------------------------------------------------------------------*/
2525       // WE NEED NOT TAKE OVER NODES THAT ARE HOT SPARE.
2526       /*---------------------------------------------------------------------*/
2527     case Sysfile::NS_NotDefined:
2528       jam();
2529       break;
2530       /*---------------------------------------------------------------------*/
2531       // WE NEED NOT TAKE OVER NODES THAT DO NOT EVEN EXIST IN THE CLUSTER.
2532       /*---------------------------------------------------------------------*/
2533     default:
2534       ndbrequire(false);
2535       break;
2536     }//switch
2537   }//for
2538   /*-------------------------------------------------------------------------*/
2539   /* NO TAKE OVER HAS BEEN INITIATED.                                        */
2540   /*-------------------------------------------------------------------------*/
2541 }//Dbdih::systemRestartTakeOverLab()
2542 
2543 /*---------------------------------------------------------------------------*/
2544 // This subroutine is called as part of node restart in the master node.
2545 /*---------------------------------------------------------------------------*/
nodeRestartTakeOver(Signal * signal,Uint32 startNodeId)2546 void Dbdih::nodeRestartTakeOver(Signal* signal, Uint32 startNodeId)
2547 {
2548   switch (getNodeActiveStatus(startNodeId)) {
2549   case Sysfile::NS_Active:
2550   case Sysfile::NS_ActiveMissed_1:
2551   case Sysfile::NS_ActiveMissed_2:
2552     jam();
2553     /*-----------------------------------------------------------------------*/
2554     // AN ACTIVE NODE HAS BEEN STARTED. THE ACTIVE NODE MUST THEN GET ALL DATA
2555     // IT HAD BEFORE ITS CRASH. WE START THE TAKE OVER IMMEDIATELY.
2556     // SINCE WE ARE AN ACTIVE NODE WE WILL TAKE OVER OUR OWN NODE THAT
2557     // PREVIOUSLY CRASHED.
2558     /*-----------------------------------------------------------------------*/
2559     startTakeOver(signal, RNIL, startNodeId, startNodeId);
2560     break;
2561   case Sysfile::NS_HotSpare:{
2562     jam();
2563     /*-----------------------------------------------------------------------*/
2564     // WHEN STARTING UP A HOT SPARE WE WILL CHECK IF ANY NODE NEEDS TO TAKEN
2565     // OVER. IF SO THEN WE WILL START THE TAKE OVER.
2566     /*-----------------------------------------------------------------------*/
2567       bool takeOverStarted = false;
2568       NodeRecordPtr nodePtr;
2569       for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
2570 	jam();
2571 	ptrAss(nodePtr, nodeRecord);
2572 	if (nodePtr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver) {
2573 	  jam();
2574 	  takeOverStarted = true;
2575 	  startTakeOver(signal, RNIL, startNodeId, nodePtr.i);
2576 	}//if
2577       }//for
2578       if (!takeOverStarted) {
2579 	jam();
2580 	/*-------------------------------------------------------------------*/
2581 	// NO TAKE OVER WAS NEEDED AT THE MOMENT WE START-UP AND WAIT UNTIL A
2582 	// TAKE OVER IS NEEDED.
2583 	/*-------------------------------------------------------------------*/
2584 	BlockReference ref = calcDihBlockRef(startNodeId);
2585 	signal->theData[0] = startNodeId;
2586 	sendSignal(ref, GSN_START_COPYCONF, signal, 1, JBB);
2587       }//if
2588       break;
2589   }
2590   case Sysfile::NS_NotActive_NotTakenOver:
2591     jam();
2592     /*-----------------------------------------------------------------------*/
2593     // ALL DATA IN THE NODE IS LOST BUT WE HAVE NOT TAKEN OVER YET. WE WILL
2594     // TAKE OVER OUR OWN NODE
2595     /*-----------------------------------------------------------------------*/
2596     startTakeOver(signal, RNIL, startNodeId, startNodeId);
2597     break;
2598   case Sysfile::NS_TakeOver:{
2599     jam();
2600     /*--------------------------------------------------------------------
2601      * We were in the process of taking over but it was not completed.
2602      * We will complete it now instead.
2603      *--------------------------------------------------------------------*/
2604     Uint32 takeOverNode = Sysfile::getTakeOverNode(startNodeId,
2605 						   SYSFILE->takeOver);
2606     if(takeOverNode == 0){
2607       jam();
2608       warningEvent("Bug in take-over code restarting");
2609       takeOverNode = startNodeId;
2610     }
2611 
2612     startTakeOver(signal, RNIL, startNodeId, takeOverNode);
2613     break;
2614   }
2615   default:
2616     ndbrequire(false);
2617     break;
2618   }//switch
2619   nodeResetStart();
2620 }//Dbdih::nodeRestartTakeOver()
2621 
2622 /*************************************************************************/
2623 // Ths routine is called when starting a local checkpoint.
2624 /*************************************************************************/
checkStartTakeOver(Signal * signal)2625 void Dbdih::checkStartTakeOver(Signal* signal)
2626 {
2627   NodeRecordPtr csoNodeptr;
2628   Uint32 tcsoHotSpareNode;
2629   Uint32 tcsoTakeOverNode;
2630   if (isMaster()) {
2631     /*-----------------------------------------------------------------*/
2632     /*       WE WILL ONLY START TAKE OVER IF WE ARE MASTER.            */
2633     /*-----------------------------------------------------------------*/
2634     /*       WE WILL ONLY START THE  TAKE OVER IF THERE WERE A NEED OF */
2635     /*       A TAKE OVER.                                              */
2636     /*-----------------------------------------------------------------*/
2637     /*       WE CAN ONLY PERFORM THE TAKE OVER IF WE HAVE A HOT SPARE  */
2638     /*       AVAILABLE.                                                */
2639     /*-----------------------------------------------------------------*/
2640     tcsoTakeOverNode = 0;
2641     tcsoHotSpareNode = 0;
2642     for (csoNodeptr.i = 1; csoNodeptr.i < MAX_NDB_NODES; csoNodeptr.i++) {
2643       ptrAss(csoNodeptr, nodeRecord);
2644       if (csoNodeptr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver) {
2645         jam();
2646         tcsoTakeOverNode = csoNodeptr.i;
2647       } else {
2648         jam();
2649         if (csoNodeptr.p->activeStatus == Sysfile::NS_HotSpare) {
2650           jam();
2651           tcsoHotSpareNode = csoNodeptr.i;
2652         }//if
2653       }//if
2654     }//for
2655     if ((tcsoTakeOverNode != 0) &&
2656         (tcsoHotSpareNode != 0)) {
2657       jam();
2658       startTakeOver(signal, RNIL, tcsoHotSpareNode, tcsoTakeOverNode);
2659     }//if
2660   }//if
2661 }//Dbdih::checkStartTakeOver()
2662 
2663 /*****************************************************************************/
2664 /***********     NODE ADDING  MODULE                             *************/
2665 /***********     CODE TO HANDLE TAKE OVER                        *************/
2666 /*****************************************************************************/
2667 // A take over can be initiated by a number of things:
2668 // 1) A node restart, usually the node takes over itself but can also take
2669 //    over somebody else if its own data was already taken over
2670 // 2) At system restart it is necessary to use the take over code to recover
2671 //    nodes which had too old checkpoints to be restorable by the usual
2672 //    restoration from disk.
2673 // 3) When a node has missed too many local checkpoints and is decided by the
2674 //    master to be taken over by a hot spare node that sits around waiting
2675 //    for this to happen.
2676 //
2677 // To support multiple node failures efficiently the code is written such that
2678 // only one take over can handle transitions in state but during a copy
2679 // fragment other take over's can perform state transitions.
2680 /*****************************************************************************/
startTakeOver(Signal * signal,Uint32 takeOverPtrI,Uint32 startNode,Uint32 nodeTakenOver)2681 void Dbdih::startTakeOver(Signal* signal,
2682                           Uint32 takeOverPtrI,
2683                           Uint32 startNode,
2684                           Uint32 nodeTakenOver)
2685 {
2686   NodeRecordPtr toNodePtr;
2687   NodeGroupRecordPtr NGPtr;
2688   toNodePtr.i = nodeTakenOver;
2689   ptrCheckGuard(toNodePtr, MAX_NDB_NODES, nodeRecord);
2690   NGPtr.i = toNodePtr.p->nodeGroup;
2691   ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
2692   TakeOverRecordPtr takeOverPtr;
2693   if (takeOverPtrI == RNIL) {
2694     jam();
2695     setAllowNodeStart(startNode, false);
2696     seizeTakeOver(takeOverPtr);
2697     if (startNode == c_nodeStartMaster.startNode) {
2698       jam();
2699       takeOverPtr.p->toNodeRestart = true;
2700     }//if
2701     takeOverPtr.p->toStartingNode = startNode;
2702     takeOverPtr.p->toFailedNode = nodeTakenOver;
2703   } else {
2704     jam();
2705     RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
2706     ndbrequire(takeOverPtr.p->toStartingNode == startNode);
2707     ndbrequire(takeOverPtr.p->toFailedNode == nodeTakenOver);
2708     ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_WAIT_START_TAKE_OVER);
2709   }//if
2710   if ((NGPtr.p->activeTakeOver) || (ERROR_INSERTED(7157))) {
2711     jam();
2712     /**------------------------------------------------------------------------
2713      * A take over is already active in this node group. We only allow one
2714      * take over per node group. Otherwise we will overload the node group and
2715      * also we will require much more checks when starting up copying of
2716      * fragments. The parallelism for take over is mainly to ensure that we
2717      * can handle take over efficiently in large systems with 4 nodes and above
2718      * A typical case is a 8 node system executing on two 8-cpu boxes.
2719      * A box crash in one of the boxes will mean 4 nodes crashes.
2720      * We want to be able to restart those four nodes to some
2721      * extent in parallel.
2722      *
2723      * We will wait for a few seconds and then try again.
2724      */
2725     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_START_TAKE_OVER;
2726     signal->theData[0] = DihContinueB::ZSTART_TAKE_OVER;
2727     signal->theData[1] = takeOverPtr.i;
2728     signal->theData[2] = startNode;
2729     signal->theData[3] = nodeTakenOver;
2730     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 5000, 4);
2731     return;
2732   }//if
2733   NGPtr.p->activeTakeOver = true;
2734   if (startNode == nodeTakenOver) {
2735     jam();
2736     switch (getNodeActiveStatus(nodeTakenOver)) {
2737     case Sysfile::NS_Active:
2738     case Sysfile::NS_ActiveMissed_1:
2739     case Sysfile::NS_ActiveMissed_2:
2740       jam();
2741       break;
2742     case Sysfile::NS_NotActive_NotTakenOver:
2743     case Sysfile::NS_TakeOver:
2744       jam();
2745       setNodeActiveStatus(nodeTakenOver, Sysfile::NS_TakeOver);
2746       break;
2747     default:
2748       ndbrequire(false);
2749     }//switch
2750   } else {
2751     jam();
2752     setNodeActiveStatus(nodeTakenOver, Sysfile::NS_HotSpare);
2753     setNodeActiveStatus(startNode, Sysfile::NS_TakeOver);
2754     changeNodeGroups(startNode, nodeTakenOver);
2755   }//if
2756   setNodeRestartInfoBits();
2757   /* ---------------------------------------------------------------------- */
2758   /*  WE SET THE RESTART INFORMATION TO INDICATE THAT WE ARE ABOUT TO TAKE  */
2759   /*  OVER THE FAILED NODE. WE SET THIS INFORMATION AND WAIT UNTIL THE      */
2760   /*  GLOBAL CHECKPOINT HAS WRITTEN THE RESTART INFORMATION.                */
2761   /* ---------------------------------------------------------------------- */
2762   Sysfile::setTakeOverNode(takeOverPtr.p->toFailedNode, SYSFILE->takeOver,
2763 			   startNode);
2764   takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_START_COPY;
2765 
2766   if (getNodeState().getSystemRestartInProgress())
2767   {
2768     jam();
2769     checkToCopy();
2770     checkToCopyCompleted(signal);
2771     return;
2772   }
2773   cstartGcpNow = true;
2774 }//Dbdih::startTakeOver()
2775 
changeNodeGroups(Uint32 startNode,Uint32 nodeTakenOver)2776 void Dbdih::changeNodeGroups(Uint32 startNode, Uint32 nodeTakenOver)
2777 {
2778   NodeRecordPtr startNodePtr;
2779   NodeRecordPtr toNodePtr;
2780   startNodePtr.i = startNode;
2781   ptrCheckGuard(startNodePtr, MAX_NDB_NODES, nodeRecord);
2782   toNodePtr.i = nodeTakenOver;
2783   ptrCheckGuard(toNodePtr, MAX_NDB_NODES, nodeRecord);
2784   ndbrequire(startNodePtr.p->nodeGroup == ZNIL);
2785   NodeGroupRecordPtr NGPtr;
2786 
2787   NGPtr.i = toNodePtr.p->nodeGroup;
2788   ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
2789   bool nodeFound = false;
2790   for (Uint32 i = 0; i < NGPtr.p->nodeCount; i++) {
2791     jam();
2792     if (NGPtr.p->nodesInGroup[i] == nodeTakenOver) {
2793       jam();
2794       NGPtr.p->nodesInGroup[i] = startNode;
2795       nodeFound = true;
2796     }//if
2797   }//for
2798   ndbrequire(nodeFound);
2799   Sysfile::setNodeGroup(startNodePtr.i, SYSFILE->nodeGroups, toNodePtr.p->nodeGroup);
2800   startNodePtr.p->nodeGroup = toNodePtr.p->nodeGroup;
2801   Sysfile::setNodeGroup(toNodePtr.i, SYSFILE->nodeGroups, NO_NODE_GROUP_ID);
2802   toNodePtr.p->nodeGroup = ZNIL;
2803 }//Dbdih::changeNodeGroups()
2804 
checkToCopy()2805 void Dbdih::checkToCopy()
2806 {
2807   TakeOverRecordPtr takeOverPtr;
2808   for (takeOverPtr.i = 0;takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
2809     ptrAss(takeOverPtr, takeOverRecord);
2810     /*----------------------------------------------------------------------*/
2811     // TAKE OVER HANDLING WRITES RESTART INFORMATION THROUGH
2812     // THE GLOBAL CHECKPOINT
2813     // PROTOCOL. WE CHECK HERE BEFORE STARTING A WRITE OF THE RESTART
2814     // INFORMATION.
2815     /*-----------------------------------------------------------------------*/
2816     if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_START_COPY) {
2817       jam();
2818       takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_START_COPY_ONGOING;
2819     } else if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_END_COPY) {
2820       jam();
2821       takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_END_COPY_ONGOING;
2822     }//if
2823   }//for
2824 }//Dbdih::checkToCopy()
2825 
checkToCopyCompleted(Signal * signal)2826 void Dbdih::checkToCopyCompleted(Signal* signal)
2827 {
2828   /* ------------------------------------------------------------------------*/
2829   /*     WE CHECK HERE IF THE WRITING OF TAKE OVER INFORMATION ALSO HAS BEEN */
2830   /*     COMPLETED.                                                          */
2831   /* ------------------------------------------------------------------------*/
2832   TakeOverRecordPtr toPtr;
2833   for (toPtr.i = 0; toPtr.i < MAX_NDB_NODES; toPtr.i++) {
2834     ptrAss(toPtr, takeOverRecord);
2835     if (toPtr.p->toMasterStatus == TakeOverRecord::TO_START_COPY_ONGOING){
2836       jam();
2837       sendStartTo(signal, toPtr.i);
2838     } else if (toPtr.p->toMasterStatus == TakeOverRecord::TO_END_COPY_ONGOING){
2839       jam();
2840       sendEndTo(signal, toPtr.i);
2841     } else {
2842       jam();
2843     }//if
2844   }//for
2845 }//Dbdih::checkToCopyCompleted()
2846 
checkToInterrupted(TakeOverRecordPtr & takeOverPtr)2847 bool Dbdih::checkToInterrupted(TakeOverRecordPtr& takeOverPtr)
2848 {
2849   if (checkNodeAlive(takeOverPtr.p->toStartingNode)) {
2850     jam();
2851     return false;
2852   } else {
2853     jam();
2854     endTakeOver(takeOverPtr.i);
2855     return true;
2856   }//if
2857 }//Dbdih::checkToInterrupted()
2858 
sendStartTo(Signal * signal,Uint32 takeOverPtrI)2859 void Dbdih::sendStartTo(Signal* signal, Uint32 takeOverPtrI)
2860 {
2861   TakeOverRecordPtr takeOverPtr;
2862   CRASH_INSERTION(7155);
2863   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
2864   if ((c_startToLock != RNIL) || (ERROR_INSERTED(7158))) {
2865     jam();
2866     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_START;
2867     signal->theData[0] = DihContinueB::ZSEND_START_TO;
2868     signal->theData[1] = takeOverPtrI;
2869     signal->theData[2] = takeOverPtr.p->toStartingNode;
2870     signal->theData[3] = takeOverPtr.p->toFailedNode;
2871     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 4);
2872     return;
2873   }//if
2874   c_startToLock = takeOverPtrI;
2875 
2876   takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING;
2877   StartToReq * const req = (StartToReq *)&signal->theData[0];
2878   req->userPtr = takeOverPtr.i;
2879   req->userRef = reference();
2880   req->startingNodeId = takeOverPtr.p->toStartingNode;
2881   req->nodeTakenOver = takeOverPtr.p->toFailedNode;
2882   req->nodeRestart = takeOverPtr.p->toNodeRestart;
2883   sendLoopMacro(START_TOREQ, sendSTART_TOREQ);
2884 }//Dbdih::sendStartTo()
2885 
execSTART_TOREQ(Signal * signal)2886 void Dbdih::execSTART_TOREQ(Signal* signal)
2887 {
2888   TakeOverRecordPtr takeOverPtr;
2889   jamEntry();
2890   const StartToReq * const req = (StartToReq *)&signal->theData[0];
2891   takeOverPtr.i = req->userPtr;
2892   BlockReference ref = req->userRef;
2893   Uint32 startingNode = req->startingNodeId;
2894 
2895   CRASH_INSERTION(7133);
2896   RETURN_IF_NODE_NOT_ALIVE(req->startingNodeId);
2897   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
2898   allocateTakeOver(takeOverPtr);
2899   initStartTakeOver(req, takeOverPtr);
2900 
2901   StartToConf * const conf = (StartToConf *)&signal->theData[0];
2902   conf->userPtr = takeOverPtr.i;
2903   conf->sendingNodeId = cownNodeId;
2904   conf->startingNodeId = startingNode;
2905   sendSignal(ref, GSN_START_TOCONF, signal, StartToConf::SignalLength, JBB);
2906 }//Dbdih::execSTART_TOREQ()
2907 
execSTART_TOCONF(Signal * signal)2908 void Dbdih::execSTART_TOCONF(Signal* signal)
2909 {
2910   TakeOverRecordPtr takeOverPtr;
2911   jamEntry();
2912   const StartToConf * const conf = (StartToConf *)&signal->theData[0];
2913 
2914   CRASH_INSERTION(7147);
2915 
2916   RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
2917 
2918   takeOverPtr.i = conf->userPtr;
2919   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
2920   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::STARTING);
2921   ndbrequire(takeOverPtr.p->toStartingNode == conf->startingNodeId);
2922   receiveLoopMacro(START_TOREQ, conf->sendingNodeId);
2923   CRASH_INSERTION(7134);
2924   c_startToLock = RNIL;
2925 
2926   if (takeOverPtr.p->toNodeRestart)
2927   {
2928     jam();
2929     takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING_LOCAL_FRAGMENTS;
2930     nr_start_fragments(signal, takeOverPtr);
2931     return;
2932   }
2933 
2934   startNextCopyFragment(signal, takeOverPtr.i);
2935 }//Dbdih::execSTART_TOCONF()
2936 
2937 void
nr_start_fragments(Signal * signal,TakeOverRecordPtr takeOverPtr)2938 Dbdih::nr_start_fragments(Signal* signal,
2939 			  TakeOverRecordPtr takeOverPtr)
2940 {
2941   Uint32 loopCount = 0 ;
2942   TabRecordPtr tabPtr;
2943   while (loopCount++ < 100) {
2944     tabPtr.i = takeOverPtr.p->toCurrentTabref;
2945     if (tabPtr.i >= ctabFileSize) {
2946       jam();
2947       nr_run_redo(signal, takeOverPtr);
2948       return;
2949     }//if
2950     ptrAss(tabPtr, tabRecord);
2951     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE ||
2952 	tabPtr.p->tabStorage != TabRecord::ST_NORMAL)
2953     {
2954       jam();
2955       takeOverPtr.p->toCurrentFragid = 0;
2956       takeOverPtr.p->toCurrentTabref++;
2957       continue;
2958     }//if
2959     Uint32 fragId = takeOverPtr.p->toCurrentFragid;
2960     if (fragId >= tabPtr.p->totalfragments) {
2961       jam();
2962       takeOverPtr.p->toCurrentFragid = 0;
2963       takeOverPtr.p->toCurrentTabref++;
2964       continue;
2965     }//if
2966     FragmentstorePtr fragPtr;
2967     getFragstore(tabPtr.p, fragId, fragPtr);
2968     ReplicaRecordPtr loopReplicaPtr;
2969     loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
2970     while (loopReplicaPtr.i != RNIL) {
2971       ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
2972       if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
2973         jam();
2974 	nr_start_fragment(signal, takeOverPtr, loopReplicaPtr);
2975 	break;
2976       } else {
2977         jam();
2978         loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
2979       }//if
2980     }//while
2981     takeOverPtr.p->toCurrentFragid++;
2982   }//while
2983   signal->theData[0] = DihContinueB::ZTO_START_FRAGMENTS;
2984   signal->theData[1] = takeOverPtr.i;
2985   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2986 }
2987 
2988 void
nr_start_fragment(Signal * signal,TakeOverRecordPtr takeOverPtr,ReplicaRecordPtr replicaPtr)2989 Dbdih::nr_start_fragment(Signal* signal,
2990 			 TakeOverRecordPtr takeOverPtr,
2991 			 ReplicaRecordPtr replicaPtr)
2992 {
2993   Uint32 i, j = 0;
2994   Uint32 maxLcpId = 0;
2995   Uint32 maxLcpIndex = ~0;
2996 
2997   Uint32 restorableGCI = 0;
2998 
2999   ndbout_c("tab: %d frag: %d replicaP->nextLcp: %d",
3000 	   takeOverPtr.p->toCurrentTabref,
3001 	   takeOverPtr.p->toCurrentFragid,
3002 	   replicaPtr.p->nextLcp);
3003 
3004   Uint32 idx = replicaPtr.p->nextLcp;
3005   for(i = 0; i<MAX_LCP_STORED; i++, idx = nextLcpNo(idx))
3006   {
3007     ndbout_c("scanning idx: %d lcpId: %d", idx, replicaPtr.p->lcpId[idx]);
3008     if (replicaPtr.p->lcpStatus[idx] == ZVALID)
3009     {
3010       ndbrequire(replicaPtr.p->lcpId[idx] > maxLcpId);
3011       Uint32 stopGci = replicaPtr.p->maxGciStarted[idx];
3012       for (;j < replicaPtr.p->noCrashedReplicas; j++)
3013       {
3014 	ndbout_c("crashed replica: %d(%d) replicaLastGci: %d",
3015 		 j,
3016 		 replicaPtr.p->noCrashedReplicas,
3017 		 replicaPtr.p->replicaLastGci[j]);
3018 	if (replicaPtr.p->replicaLastGci[j] > stopGci)
3019 	{
3020 	  maxLcpId = replicaPtr.p->lcpId[idx];
3021 	  maxLcpIndex = idx;
3022 	  restorableGCI = replicaPtr.p->replicaLastGci[j];
3023 	  break;
3024 	}
3025       }
3026     }
3027   }
3028 
3029   if (maxLcpIndex == ~ (Uint32) 0)
3030   {
3031     ndbout_c("Didnt find any LCP for node: %d tab: %d frag: %d",
3032 	     takeOverPtr.p->toStartingNode,
3033 	     takeOverPtr.p->toCurrentTabref,
3034 	     takeOverPtr.p->toCurrentFragid);
3035     replicaPtr.p->lcpIdStarted = 0;
3036     BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
3037     StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
3038     req->userPtr = 0;
3039     req->userRef = reference();
3040     req->lcpNo = ZNIL;
3041     req->lcpId = 0;
3042     req->tableId = takeOverPtr.p->toCurrentTabref;
3043     req->fragId = takeOverPtr.p->toCurrentFragid;
3044     req->noOfLogNodes = 0;
3045     sendSignal(ref, GSN_START_FRAGREQ, signal,
3046 	       StartFragReq::SignalLength, JBB);
3047   }
3048   else
3049   {
3050     ndbout_c("Found LCP: %d(%d) maxGciStarted: %d maxGciCompleted: %d restorable: %d(%d) newestRestorableGCI: %d",
3051 	     maxLcpId,
3052 	     maxLcpIndex,
3053 	     replicaPtr.p->maxGciStarted[maxLcpIndex],
3054 	     replicaPtr.p->maxGciCompleted[maxLcpIndex],
3055 	     restorableGCI,
3056 	     SYSFILE->lastCompletedGCI[takeOverPtr.p->toStartingNode],
3057 	     SYSFILE->newestRestorableGCI);
3058 
3059     replicaPtr.p->lcpIdStarted = restorableGCI;
3060     BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
3061     StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
3062     req->userPtr = 0;
3063     req->userRef = reference();
3064     req->lcpNo = maxLcpIndex;
3065     req->lcpId = maxLcpId;
3066     req->tableId = takeOverPtr.p->toCurrentTabref;
3067     req->fragId = takeOverPtr.p->toCurrentFragid;
3068     req->noOfLogNodes = 1;
3069     req->lqhLogNode[0] = takeOverPtr.p->toStartingNode;
3070     req->startGci[0] = replicaPtr.p->maxGciCompleted[maxLcpIndex];
3071     req->lastGci[0] = restorableGCI;
3072     sendSignal(ref, GSN_START_FRAGREQ, signal,
3073 	       StartFragReq::SignalLength, JBB);
3074   }
3075 }
3076 
3077 void
nr_run_redo(Signal * signal,TakeOverRecordPtr takeOverPtr)3078 Dbdih::nr_run_redo(Signal* signal, TakeOverRecordPtr takeOverPtr)
3079 {
3080   takeOverPtr.p->toCurrentTabref = 0;
3081   takeOverPtr.p->toCurrentFragid = 0;
3082   sendSTART_RECREQ(signal, takeOverPtr.p->toStartingNode);
3083 }
3084 
initStartTakeOver(const StartToReq * req,TakeOverRecordPtr takeOverPtr)3085 void Dbdih::initStartTakeOver(const StartToReq * req,
3086 			      TakeOverRecordPtr takeOverPtr)
3087 {
3088   takeOverPtr.p->toCurrentTabref = 0;
3089   takeOverPtr.p->toCurrentFragid = 0;
3090   takeOverPtr.p->toStartingNode = req->startingNodeId;
3091   takeOverPtr.p->toFailedNode = req->nodeTakenOver;
3092   takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_STARTED;
3093   takeOverPtr.p->toCopyNode = RNIL;
3094   takeOverPtr.p->toCurrentReplica = RNIL;
3095   takeOverPtr.p->toNodeRestart = req->nodeRestart;
3096 }//Dbdih::initStartTakeOver()
3097 
startNextCopyFragment(Signal * signal,Uint32 takeOverPtrI)3098 void Dbdih::startNextCopyFragment(Signal* signal, Uint32 takeOverPtrI)
3099 {
3100   TabRecordPtr tabPtr;
3101   TakeOverRecordPtr takeOverPtr;
3102   Uint32 loopCount;
3103   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3104   takeOverPtr.p->toMasterStatus = TakeOverRecord::SELECTING_NEXT;
3105   loopCount = 0;
3106   if (ERROR_INSERTED(7159)) {
3107     loopCount = 100;
3108   }//if
3109   while (loopCount++ < 100) {
3110     tabPtr.i = takeOverPtr.p->toCurrentTabref;
3111     if (tabPtr.i >= ctabFileSize) {
3112       jam();
3113       CRASH_INSERTION(7136);
3114       sendUpdateTo(signal, takeOverPtr.i, UpdateToReq::TO_COPY_COMPLETED);
3115       return;
3116     }//if
3117     ptrAss(tabPtr, tabRecord);
3118     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
3119       jam();
3120       takeOverPtr.p->toCurrentFragid = 0;
3121       takeOverPtr.p->toCurrentTabref++;
3122       continue;
3123     }//if
3124     Uint32 fragId = takeOverPtr.p->toCurrentFragid;
3125     if (fragId >= tabPtr.p->totalfragments) {
3126       jam();
3127       takeOverPtr.p->toCurrentFragid = 0;
3128       takeOverPtr.p->toCurrentTabref++;
3129       if (ERROR_INSERTED(7135)) {
3130         if (takeOverPtr.p->toCurrentTabref == 1) {
3131           ndbrequire(false);
3132         }//if
3133       }//if
3134       continue;
3135     }//if
3136     FragmentstorePtr fragPtr;
3137     getFragstore(tabPtr.p, fragId, fragPtr);
3138     ReplicaRecordPtr loopReplicaPtr;
3139     loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
3140     while (loopReplicaPtr.i != RNIL) {
3141       ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
3142       if (loopReplicaPtr.p->procNode == takeOverPtr.p->toFailedNode) {
3143         jam();
3144 	/* ----------------------------------------------------------------- */
3145 	/* WE HAVE FOUND A REPLICA THAT BELONGED THE FAILED NODE THAT NEEDS  */
3146 	/* TAKE OVER. WE TAKE OVER THIS REPLICA TO THE NEW NODE.             */
3147 	/* ----------------------------------------------------------------- */
3148         takeOverPtr.p->toCurrentReplica = loopReplicaPtr.i;
3149         toCopyFragLab(signal, takeOverPtr.i);
3150         return;
3151       } else if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
3152         jam();
3153 	/* ----------------------------------------------------------------- */
3154 	/* WE HAVE OBVIOUSLY STARTED TAKING OVER THIS WITHOUT COMPLETING IT. */
3155 	/* WE     */
3156 	/* NEED TO COMPLETE THE TAKE OVER OF THIS REPLICA.                   */
3157 	/* ----------------------------------------------------------------- */
3158         takeOverPtr.p->toCurrentReplica = loopReplicaPtr.i;
3159         toCopyFragLab(signal, takeOverPtr.i);
3160         return;
3161       } else {
3162         jam();
3163         loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
3164       }//if
3165     }//while
3166     takeOverPtr.p->toCurrentFragid++;
3167   }//while
3168   signal->theData[0] = DihContinueB::ZTO_START_COPY_FRAG;
3169   signal->theData[1] = takeOverPtr.i;
3170   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
3171 }//Dbdih::startNextCopyFragment()
3172 
toCopyFragLab(Signal * signal,Uint32 takeOverPtrI)3173 void Dbdih::toCopyFragLab(Signal* signal,
3174                           Uint32 takeOverPtrI)
3175 {
3176   TakeOverRecordPtr takeOverPtr;
3177   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3178 
3179   /**
3180    * Inform starting node that TakeOver is about to start
3181    */
3182   Uint32 nodeId = takeOverPtr.p->toStartingNode;
3183 
3184   Uint32 version = getNodeInfo(nodeId).m_version;
3185   if (ndb_check_prep_copy_frag_version(version))
3186   {
3187     jam();
3188     TabRecordPtr tabPtr;
3189     tabPtr.i = takeOverPtr.p->toCurrentTabref;
3190     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3191 
3192     FragmentstorePtr fragPtr;
3193     getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
3194     Uint32 nodes[MAX_REPLICAS];
3195     extractNodeInfo(fragPtr.p, nodes);
3196 
3197     PrepareCopyFragReq* req= (PrepareCopyFragReq*)signal->getDataPtrSend();
3198     req->senderRef = reference();
3199     req->senderData = takeOverPtrI;
3200     req->tableId = takeOverPtr.p->toCurrentTabref;
3201     req->fragId = takeOverPtr.p->toCurrentFragid;
3202     req->copyNodeId = nodes[0]; // Src
3203     req->startingNodeId = takeOverPtr.p->toStartingNode; // Dst
3204     Uint32 ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
3205 
3206     sendSignal(ref, GSN_PREPARE_COPY_FRAG_REQ, signal,
3207 	       PrepareCopyFragReq::SignalLength, JBB);
3208 
3209     takeOverPtr.p->toMasterStatus = TakeOverRecord::PREPARE_COPY;
3210     return;
3211   }
3212 
3213   takeOverPtr.p->maxPage = RNIL;
3214   toStartCopyFrag(signal, takeOverPtr);
3215 }
3216 
3217 void
execPREPARE_COPY_FRAG_REF(Signal * signal)3218 Dbdih::execPREPARE_COPY_FRAG_REF(Signal* signal)
3219 {
3220   jamEntry();
3221   PrepareCopyFragRef ref = *(PrepareCopyFragRef*)signal->getDataPtr();
3222 
3223   TakeOverRecordPtr takeOverPtr;
3224   RETURN_IF_TAKE_OVER_INTERRUPTED(ref.senderData, takeOverPtr);
3225 
3226   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::PREPARE_COPY);
3227 
3228   /**
3229    * Treat this as copy frag ref
3230    */
3231   CopyFragRef * cfref = (CopyFragRef*)signal->getDataPtrSend();
3232   cfref->userPtr = ref.senderData;
3233   cfref->startingNodeId = ref.startingNodeId;
3234   cfref->errorCode = ref.errorCode;
3235   cfref->tableId = ref.tableId;
3236   cfref->fragId = ref.fragId;
3237   cfref->sendingNodeId = ref.copyNodeId;
3238   takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_FRAG;
3239   execCOPY_FRAGREF(signal);
3240 }
3241 
3242 void
execPREPARE_COPY_FRAG_CONF(Signal * signal)3243 Dbdih::execPREPARE_COPY_FRAG_CONF(Signal* signal)
3244 {
3245   PrepareCopyFragConf conf = *(PrepareCopyFragConf*)signal->getDataPtr();
3246 
3247   TakeOverRecordPtr takeOverPtr;
3248   RETURN_IF_TAKE_OVER_INTERRUPTED(conf.senderData, takeOverPtr);
3249 
3250   Uint32 version = getNodeInfo(refToNode(conf.senderRef)).m_version;
3251   if (ndb_check_prep_copy_frag_version(version) >= 2)
3252   {
3253     jam();
3254     takeOverPtr.p->maxPage = conf.maxPageNo;
3255   }
3256   else
3257   {
3258     jam();
3259     takeOverPtr.p->maxPage = RNIL;
3260   }
3261   toStartCopyFrag(signal, takeOverPtr);
3262 }
3263 
3264 void
toStartCopyFrag(Signal * signal,TakeOverRecordPtr takeOverPtr)3265 Dbdih::toStartCopyFrag(Signal* signal, TakeOverRecordPtr takeOverPtr)
3266 {
3267   CreateReplicaRecordPtr createReplicaPtr;
3268   createReplicaPtr.i = 0;
3269   ptrAss(createReplicaPtr, createReplicaRecord);
3270 
3271   ReplicaRecordPtr replicaPtr;
3272   replicaPtr.i = takeOverPtr.p->toCurrentReplica;
3273   ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
3274 
3275   TabRecordPtr tabPtr;
3276   tabPtr.i = takeOverPtr.p->toCurrentTabref;
3277   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3278   /* ----------------------------------------------------------------------- */
3279   /* WE HAVE FOUND A REPLICA THAT NEEDS TAKE OVER. WE WILL START THIS TAKE   */
3280   /* OVER BY ADDING THE FRAGMENT WHEREAFTER WE WILL ORDER THE PRIMARY        */
3281   /* REPLICA TO COPY ITS CONTENT TO THE NEW STARTING REPLICA.                */
3282   /* THIS OPERATION IS A SINGLE USER OPERATION UNTIL WE HAVE SENT            */
3283   /* COPY_FRAGREQ. AFTER SENDING COPY_FRAGREQ WE ARE READY TO START A NEW    */
3284   /* FRAGMENT REPLICA. WE WILL NOT IMPLEMENT THIS IN THE FIRST PHASE.        */
3285   /* ----------------------------------------------------------------------- */
3286   cnoOfCreateReplicas = 1;
3287   createReplicaPtr.p->hotSpareUse = true;
3288   createReplicaPtr.p->dataNodeId = takeOverPtr.p->toStartingNode;
3289 
3290   prepareSendCreateFragReq(signal, takeOverPtr.i);
3291 }//Dbdih::toStartCopy()
3292 
prepareSendCreateFragReq(Signal * signal,Uint32 takeOverPtrI)3293 void Dbdih::prepareSendCreateFragReq(Signal* signal, Uint32 takeOverPtrI)
3294 {
3295   TakeOverRecordPtr takeOverPtr;
3296   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3297 
3298   TabRecordPtr tabPtr;
3299   tabPtr.i = takeOverPtr.p->toCurrentTabref;
3300   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3301   FragmentstorePtr fragPtr;
3302 
3303   getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
3304   Uint32 nodes[MAX_REPLICAS];
3305   extractNodeInfo(fragPtr.p, nodes);
3306   takeOverPtr.p->toCopyNode = nodes[0];
3307   sendCreateFragReq(signal, 0, CreateFragReq::STORED, takeOverPtr.i);
3308 }//Dbdih::prepareSendCreateFragReq()
3309 
sendCreateFragReq(Signal * signal,Uint32 startGci,Uint32 replicaType,Uint32 takeOverPtrI)3310 void Dbdih::sendCreateFragReq(Signal* signal,
3311                               Uint32 startGci,
3312                               Uint32 replicaType,
3313                               Uint32 takeOverPtrI)
3314 {
3315   TakeOverRecordPtr takeOverPtr;
3316   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3317   if ((c_createFragmentLock != RNIL) ||
3318       ((ERROR_INSERTED(7161))&&(replicaType == CreateFragReq::STORED)) ||
3319       ((ERROR_INSERTED(7162))&&(replicaType == CreateFragReq::COMMIT_STORED))){
3320     if (replicaType == CreateFragReq::STORED) {
3321       jam();
3322       takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_PREPARE_CREATE;
3323     } else {
3324       ndbrequire(replicaType == CreateFragReq::COMMIT_STORED);
3325       jam();
3326       takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_COMMIT_CREATE;
3327     }//if
3328     signal->theData[0] = DihContinueB::ZSEND_CREATE_FRAG;
3329     signal->theData[1] = takeOverPtr.i;
3330     signal->theData[2] = replicaType;
3331     signal->theData[3] = startGci;
3332     signal->theData[4] = takeOverPtr.p->toStartingNode;
3333     signal->theData[5] = takeOverPtr.p->toFailedNode;
3334     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 50, 6);
3335     return;
3336   }//if
3337   c_createFragmentLock = takeOverPtr.i;
3338   sendLoopMacro(CREATE_FRAGREQ, nullRoutine);
3339 
3340   CreateFragReq * const req = (CreateFragReq *)&signal->theData[0];
3341   req->userPtr = takeOverPtr.i;
3342   req->userRef = reference();
3343   req->tableId = takeOverPtr.p->toCurrentTabref;
3344   req->fragId = takeOverPtr.p->toCurrentFragid;
3345   req->startingNodeId = takeOverPtr.p->toStartingNode;
3346   req->copyNodeId = takeOverPtr.p->toCopyNode;
3347   req->startGci = startGci;
3348   req->replicaType = replicaType;
3349 
3350   NodeRecordPtr nodePtr;
3351   nodePtr.i = cfirstAliveNode;
3352   do {
3353     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3354     BlockReference ref = calcDihBlockRef(nodePtr.i);
3355     sendSignal(ref, GSN_CREATE_FRAGREQ, signal,
3356 	       CreateFragReq::SignalLength, JBB);
3357     nodePtr.i = nodePtr.p->nextNode;
3358   } while (nodePtr.i != RNIL);
3359 
3360   if (replicaType == CreateFragReq::STORED) {
3361     jam();
3362     takeOverPtr.p->toMasterStatus = TakeOverRecord::PREPARE_CREATE;
3363   } else {
3364     ndbrequire(replicaType == CreateFragReq::COMMIT_STORED);
3365     jam();
3366     takeOverPtr.p->toMasterStatus = TakeOverRecord::COMMIT_CREATE;
3367   }
3368 }//Dbdih::sendCreateFragReq()
3369 
3370 /* --------------------------------------------------------------------------*/
3371 /*       AN ORDER TO START OR COMMIT THE REPLICA CREATION ARRIVED FROM THE   */
3372 /*       MASTER.                                                             */
3373 /* --------------------------------------------------------------------------*/
execCREATE_FRAGREQ(Signal * signal)3374 void Dbdih::execCREATE_FRAGREQ(Signal* signal)
3375 {
3376   jamEntry();
3377   CreateFragReq * const req = (CreateFragReq *)&signal->theData[0];
3378 
3379   TakeOverRecordPtr takeOverPtr;
3380   takeOverPtr.i = req->userPtr;
3381   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3382 
3383   BlockReference retRef = req->userRef;
3384 
3385   TabRecordPtr tabPtr;
3386   tabPtr.i = req->tableId;
3387   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3388 
3389   Uint32 fragId = req->fragId;
3390   Uint32 tdestNodeid = req->startingNodeId;
3391   Uint32 tsourceNodeid = req->copyNodeId;
3392   Uint32 startGci = req->startGci;
3393   Uint32 replicaType = req->replicaType;
3394 
3395   FragmentstorePtr fragPtr;
3396   getFragstore(tabPtr.p, fragId, fragPtr);
3397   RETURN_IF_NODE_NOT_ALIVE(tdestNodeid);
3398   ReplicaRecordPtr frReplicaPtr;
3399   findToReplica(takeOverPtr.p, replicaType, fragPtr, frReplicaPtr);
3400   ndbrequire(frReplicaPtr.i != RNIL);
3401 
3402   switch (replicaType) {
3403   case CreateFragReq::STORED:
3404     jam();
3405     CRASH_INSERTION(7138);
3406     /* ----------------------------------------------------------------------*/
3407     /*  HERE WE ARE INSERTING THE NEW BACKUP NODE IN THE EXECUTION OF ALL    */
3408     /*  OPERATIONS. FROM HERE ON ALL OPERATIONS ON THIS FRAGMENT WILL INCLUDE*/
3409     /*  USE OF THE NEW REPLICA.                                              */
3410     /* --------------------------------------------------------------------- */
3411     insertBackup(fragPtr, tdestNodeid);
3412     takeOverPtr.p->toCopyNode = tsourceNodeid;
3413     takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_CREATE_PREPARE;
3414 
3415     fragPtr.p->distributionKey++;
3416     fragPtr.p->distributionKey &= 255;
3417     break;
3418   case CreateFragReq::COMMIT_STORED:
3419     jam();
3420     CRASH_INSERTION(7139);
3421     /* ----------------------------------------------------------------------*/
3422     /*  HERE WE ARE MOVING THE REPLICA TO THE STORED SECTION SINCE IT IS NOW */
3423     /*  FULLY LOADED WITH ALL DATA NEEDED.                                   */
3424     // We also update the order of the replicas here so that if the new
3425     // replica is the desired primary we insert it as primary.
3426     /* ----------------------------------------------------------------------*/
3427     takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_CREATE_COMMIT;
3428     removeOldStoredReplica(fragPtr, frReplicaPtr);
3429     linkStoredReplica(fragPtr, frReplicaPtr);
3430     updateNodeInfo(fragPtr);
3431     break;
3432   default:
3433     ndbrequire(false);
3434     break;
3435   }//switch
3436 
3437   /* ------------------------------------------------------------------------*/
3438   /*       THE NEW NODE OF THIS REPLICA IS THE STARTING NODE.                */
3439   /* ------------------------------------------------------------------------*/
3440   if (frReplicaPtr.p->procNode != takeOverPtr.p->toStartingNode) {
3441     jam();
3442     /* ---------------------------------------------------------------------*/
3443     /*  IF WE ARE STARTING A TAKE OVER NODE WE MUST INVALIDATE ALL LCP'S.   */
3444     /*  OTHERWISE WE WILL TRY TO START LCP'S THAT DO NOT EXIST.             */
3445     /* ---------------------------------------------------------------------*/
3446     frReplicaPtr.p->procNode = takeOverPtr.p->toStartingNode;
3447     frReplicaPtr.p->noCrashedReplicas = 0;
3448     frReplicaPtr.p->createGci[0] = startGci;
3449     ndbrequire(startGci != 0xF1F1F1F1);
3450     frReplicaPtr.p->replicaLastGci[0] = (Uint32)-1;
3451     for (Uint32 i = 0; i < MAX_LCP_STORED; i++) {
3452       frReplicaPtr.p->lcpStatus[i] = ZINVALID;
3453     }//for
3454   } else {
3455     jam();
3456     const Uint32 noCrashed = frReplicaPtr.p->noCrashedReplicas;
3457     arrGuard(noCrashed, 8);
3458     frReplicaPtr.p->createGci[noCrashed] = startGci;
3459     ndbrequire(startGci != 0xF1F1F1F1);
3460     frReplicaPtr.p->replicaLastGci[noCrashed] = (Uint32)-1;
3461   }//if
3462   takeOverPtr.p->toCurrentTabref = tabPtr.i;
3463   takeOverPtr.p->toCurrentFragid = fragId;
3464   CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
3465   conf->userPtr = takeOverPtr.i;
3466   conf->tableId = tabPtr.i;
3467   conf->fragId = fragId;
3468   conf->sendingNodeId = cownNodeId;
3469   conf->startingNodeId = tdestNodeid;
3470   sendSignal(retRef, GSN_CREATE_FRAGCONF, signal,
3471              CreateFragConf::SignalLength, JBB);
3472 }//Dbdih::execCREATE_FRAGREQ()
3473 
execCREATE_FRAGCONF(Signal * signal)3474 void Dbdih::execCREATE_FRAGCONF(Signal* signal)
3475 {
3476   jamEntry();
3477   CRASH_INSERTION(7148);
3478   const CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
3479   Uint32 fragId = conf->fragId;
3480 
3481   RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
3482 
3483   TabRecordPtr tabPtr;
3484   tabPtr.i = conf->tableId;
3485   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3486 
3487   TakeOverRecordPtr takeOverPtr;
3488   takeOverPtr.i = conf->userPtr;
3489   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3490 
3491   ndbrequire(tabPtr.i == takeOverPtr.p->toCurrentTabref);
3492   ndbrequire(fragId == takeOverPtr.p->toCurrentFragid);
3493   receiveLoopMacro(CREATE_FRAGREQ, conf->sendingNodeId);
3494   c_createFragmentLock = RNIL;
3495 
3496   if (takeOverPtr.p->toMasterStatus == TakeOverRecord::PREPARE_CREATE) {
3497     jam();
3498     CRASH_INSERTION(7140);
3499     /* --------------------------------------------------------------------- */
3500     /*   ALL NODES HAVE PREPARED THE INTRODUCTION OF THIS NEW NODE AND IT IS */
3501     /*   ALREADY IN USE. WE CAN NOW START COPYING THE FRAGMENT.              */
3502     /*---------------------------------------------------------------------- */
3503     FragmentstorePtr fragPtr;
3504     getFragstore(tabPtr.p, fragId, fragPtr);
3505     Uint32 gci = 0;
3506     if (takeOverPtr.p->toNodeRestart)
3507     {
3508       ReplicaRecordPtr replicaPtr;
3509       findReplica(replicaPtr, fragPtr.p, takeOverPtr.p->toStartingNode, true);
3510       gci = replicaPtr.p->lcpIdStarted;
3511       replicaPtr.p->lcpIdStarted = 0;
3512     }
3513     takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_FRAG;
3514     BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toCopyNode);
3515     CopyFragReq * const copyFragReq = (CopyFragReq *)&signal->theData[0];
3516     copyFragReq->userPtr = takeOverPtr.i;
3517     copyFragReq->userRef = reference();
3518     copyFragReq->tableId = tabPtr.i;
3519     copyFragReq->fragId = fragId;
3520     copyFragReq->nodeId = takeOverPtr.p->toStartingNode;
3521     copyFragReq->schemaVersion = tabPtr.p->schemaVersion;
3522     copyFragReq->distributionKey = fragPtr.p->distributionKey;
3523     copyFragReq->gci = gci;
3524     Uint32 len = copyFragReq->nodeCount =
3525       extractNodeInfo(fragPtr.p,
3526                       copyFragReq->nodeList);
3527     copyFragReq->nodeList[len] = takeOverPtr.p->maxPage;
3528     sendSignal(ref, GSN_COPY_FRAGREQ, signal,
3529                CopyFragReq::SignalLength + len, JBB);
3530   } else {
3531     ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COMMIT_CREATE);
3532     jam();
3533     CRASH_INSERTION(7141);
3534     /* --------------------------------------------------------------------- */
3535     // REPORT that copy of fragment has been completed.
3536     /* --------------------------------------------------------------------- */
3537     signal->theData[0] = NDB_LE_NR_CopyFragDone;
3538     signal->theData[1] = takeOverPtr.p->toStartingNode;
3539     signal->theData[2] = tabPtr.i;
3540     signal->theData[3] = takeOverPtr.p->toCurrentFragid;
3541     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
3542     /* --------------------------------------------------------------------- */
3543     /*   WE HAVE NOW CREATED THIS NEW REPLICA AND WE ARE READY TO TAKE THE   */
3544     /*   THE NEXT REPLICA.                                                   */
3545     /* --------------------------------------------------------------------- */
3546 
3547     Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
3548     mutex.unlock(); // ignore result
3549 
3550     takeOverPtr.p->toCurrentFragid++;
3551     startNextCopyFragment(signal, takeOverPtr.i);
3552   }//if
3553 }//Dbdih::execCREATE_FRAGCONF()
3554 
execCOPY_FRAGREF(Signal * signal)3555 void Dbdih::execCOPY_FRAGREF(Signal* signal)
3556 {
3557   const CopyFragRef * const ref = (CopyFragRef *)&signal->theData[0];
3558   jamEntry();
3559   Uint32 takeOverPtrI = ref->userPtr;
3560   Uint32 startingNodeId = ref->startingNodeId;
3561   Uint32 errorCode = ref->errorCode;
3562 
3563   TakeOverRecordPtr takeOverPtr;
3564   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3565   ndbrequire(errorCode != ZNODE_FAILURE_ERROR);
3566   ndbrequire(ref->tableId == takeOverPtr.p->toCurrentTabref);
3567   ndbrequire(ref->fragId == takeOverPtr.p->toCurrentFragid);
3568   ndbrequire(ref->startingNodeId == takeOverPtr.p->toStartingNode);
3569   ndbrequire(ref->sendingNodeId == takeOverPtr.p->toCopyNode);
3570   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG);
3571   endTakeOver(takeOverPtrI);
3572   //--------------------------------------------------------------------------
3573   // For some reason we did not succeed in copying a fragment. We treat this
3574   // as a serious failure and crash the starting node.
3575   //--------------------------------------------------------------------------
3576   BlockReference cntrRef = calcNdbCntrBlockRef(startingNodeId);
3577   SystemError * const sysErr = (SystemError*)&signal->theData[0];
3578   sysErr->errorCode = SystemError::CopyFragRefError;
3579   sysErr->errorRef = reference();
3580   sysErr->data1 = errorCode;
3581   sysErr->data2 = 0;
3582   sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
3583 	     SystemError::SignalLength, JBB);
3584   return;
3585 }//Dbdih::execCOPY_FRAGREF()
3586 
execCOPY_FRAGCONF(Signal * signal)3587 void Dbdih::execCOPY_FRAGCONF(Signal* signal)
3588 {
3589   const CopyFragConf * const conf = (CopyFragConf *)&signal->theData[0];
3590   jamEntry();
3591   CRASH_INSERTION(7142);
3592 
3593   TakeOverRecordPtr takeOverPtr;
3594   Uint32 takeOverPtrI = conf->userPtr;
3595   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3596 
3597   ndbrequire(conf->tableId == takeOverPtr.p->toCurrentTabref);
3598   ndbrequire(conf->fragId == takeOverPtr.p->toCurrentFragid);
3599   ndbrequire(conf->startingNodeId == takeOverPtr.p->toStartingNode);
3600   ndbrequire(conf->sendingNodeId == takeOverPtr.p->toCopyNode);
3601   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG);
3602   sendUpdateTo(signal, takeOverPtr.i,
3603 	       (Uint32)UpdateToReq::TO_COPY_FRAG_COMPLETED);
3604 }//Dbdih::execCOPY_FRAGCONF()
3605 
sendUpdateTo(Signal * signal,Uint32 takeOverPtrI,Uint32 updateState)3606 void Dbdih::sendUpdateTo(Signal* signal,
3607 			 Uint32 takeOverPtrI, Uint32 updateState)
3608 {
3609   TakeOverRecordPtr takeOverPtr;
3610   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3611   if ((c_updateToLock != RNIL) ||
3612       ((ERROR_INSERTED(7163)) &&
3613        (updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED)) ||
3614       ((ERROR_INSERTED(7169)) &&
3615        (updateState == UpdateToReq::TO_COPY_COMPLETED))) {
3616     jam();
3617     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_UPDATE_TO;
3618     signal->theData[0] = DihContinueB::ZSEND_UPDATE_TO;
3619     signal->theData[1] = takeOverPtrI;
3620     signal->theData[2] = takeOverPtr.p->toStartingNode;
3621     signal->theData[3] = takeOverPtr.p->toFailedNode;
3622     signal->theData[4] = updateState;
3623     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 5);
3624     return;
3625   }//if
3626   c_updateToLock = takeOverPtrI;
3627   if (updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED) {
3628     jam();
3629     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_UPDATE_TO;
3630   } else {
3631     jam();
3632     ndbrequire(updateState == UpdateToReq::TO_COPY_COMPLETED);
3633     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_COPY_COMPLETED;
3634   }//if
3635 
3636   UpdateToReq * const req = (UpdateToReq *)&signal->theData[0];
3637   req->userPtr = takeOverPtr.i;
3638   req->userRef = reference();
3639   req->updateState = (UpdateToReq::UpdateState)updateState;
3640   req->startingNodeId = takeOverPtr.p->toStartingNode;
3641   req->tableId = takeOverPtr.p->toCurrentTabref;
3642   req->fragmentNo = takeOverPtr.p->toCurrentFragid;
3643   sendLoopMacro(UPDATE_TOREQ, sendUPDATE_TOREQ);
3644 }//Dbdih::sendUpdateTo()
3645 
execUPDATE_TOREQ(Signal * signal)3646 void Dbdih::execUPDATE_TOREQ(Signal* signal)
3647 {
3648   jamEntry();
3649   const UpdateToReq * const req = (UpdateToReq *)&signal->theData[0];
3650   BlockReference ref = req->userRef;
3651   ndbrequire(cmasterdihref == ref);
3652 
3653   CRASH_INSERTION(7154);
3654   RETURN_IF_NODE_NOT_ALIVE(req->startingNodeId);
3655 
3656   TakeOverRecordPtr takeOverPtr;
3657   takeOverPtr.i = req->userPtr;
3658   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3659 
3660   ndbrequire(req->startingNodeId == takeOverPtr.p->toStartingNode);
3661   if (req->updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED) {
3662     jam();
3663     ndbrequire(takeOverPtr.p->toSlaveStatus == TakeOverRecord::TO_SLAVE_CREATE_PREPARE);
3664     takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED;
3665     takeOverPtr.p->toCurrentTabref = req->tableId;
3666     takeOverPtr.p->toCurrentFragid = req->fragmentNo;
3667   } else {
3668     jam();
3669     ndbrequire(req->updateState == UpdateToReq::TO_COPY_COMPLETED);
3670     takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_COPY_COMPLETED;
3671     setNodeCopyCompleted(takeOverPtr.p->toStartingNode, true);
3672   }//if
3673 
3674 
3675   UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
3676   conf->userPtr = takeOverPtr.i;
3677   conf->sendingNodeId = cownNodeId;
3678   conf->startingNodeId = takeOverPtr.p->toStartingNode;
3679   sendSignal(ref, GSN_UPDATE_TOCONF, signal, UpdateToConf::SignalLength, JBB);
3680 }//Dbdih::execUPDATE_TOREQ()
3681 
execUPDATE_TOCONF(Signal * signal)3682 void Dbdih::execUPDATE_TOCONF(Signal* signal)
3683 {
3684   const UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
3685   CRASH_INSERTION(7152);
3686 
3687   RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
3688 
3689   TakeOverRecordPtr takeOverPtr;
3690   takeOverPtr.i = conf->userPtr;
3691   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3692 
3693   receiveLoopMacro(UPDATE_TOREQ, conf->sendingNodeId);
3694   CRASH_INSERTION(7153);
3695   c_updateToLock = RNIL;
3696 
3697   if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_COPY_COMPLETED) {
3698     jam();
3699     toCopyCompletedLab(signal, takeOverPtr);
3700     return;
3701   } else {
3702     ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_UPDATE_TO);
3703   }//if
3704   TabRecordPtr tabPtr;
3705   tabPtr.i = takeOverPtr.p->toCurrentTabref;
3706   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3707 
3708   FragmentstorePtr fragPtr;
3709   getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
3710   takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_ACTIVE;
3711   BlockReference lqhRef = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
3712   CopyActiveReq * const req = (CopyActiveReq *)&signal->theData[0];
3713   req->userPtr = takeOverPtr.i;
3714   req->userRef = reference();
3715   req->tableId = takeOverPtr.p->toCurrentTabref;
3716   req->fragId = takeOverPtr.p->toCurrentFragid;
3717   req->distributionKey = fragPtr.p->distributionKey;
3718 
3719   sendSignal(lqhRef, GSN_COPY_ACTIVEREQ, signal,
3720              CopyActiveReq::SignalLength, JBB);
3721 }//Dbdih::execUPDATE_TOCONF()
3722 
execCOPY_ACTIVECONF(Signal * signal)3723 void Dbdih::execCOPY_ACTIVECONF(Signal* signal)
3724 {
3725   const CopyActiveConf * const conf = (CopyActiveConf *)&signal->theData[0];
3726   jamEntry();
3727   CRASH_INSERTION(7143);
3728 
3729   TakeOverRecordPtr takeOverPtr;
3730   takeOverPtr.i = conf->userPtr;
3731   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3732 
3733   ndbrequire(conf->tableId == takeOverPtr.p->toCurrentTabref);
3734   ndbrequire(conf->fragId == takeOverPtr.p->toCurrentFragid);
3735   ndbrequire(checkNodeAlive(conf->startingNodeId));
3736   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_ACTIVE);
3737 
3738   takeOverPtr.p->startGci = conf->startGci;
3739   takeOverPtr.p->toMasterStatus = TakeOverRecord::LOCK_MUTEX;
3740 
3741   Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
3742   Callback c = { safe_cast(&Dbdih::switchPrimaryMutex_locked), takeOverPtr.i };
3743   ndbrequire(mutex.lock(c));
3744 }//Dbdih::execCOPY_ACTIVECONF()
3745 
3746 void
switchPrimaryMutex_locked(Signal * signal,Uint32 toPtrI,Uint32 retVal)3747 Dbdih::switchPrimaryMutex_locked(Signal* signal, Uint32 toPtrI, Uint32 retVal){
3748   jamEntry();
3749   ndbrequire(retVal == 0);
3750 
3751   TakeOverRecordPtr takeOverPtr;
3752   takeOverPtr.i = toPtrI;
3753   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3754 
3755   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::LOCK_MUTEX);
3756 
3757   if (!checkNodeAlive((takeOverPtr.p->toStartingNode))) {
3758     // We have mutex
3759     Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
3760     mutex.unlock(); // Ignore result
3761 
3762     c_createFragmentLock = RNIL;
3763     c_CREATE_FRAGREQ_Counter.clearWaitingFor();
3764     endTakeOver(takeOverPtr.i);
3765     return;
3766   }
3767 
3768   takeOverPtr.p->toMasterStatus = TakeOverRecord::COMMIT_CREATE;
3769   sendCreateFragReq(signal, takeOverPtr.p->startGci,
3770 		    CreateFragReq::COMMIT_STORED, takeOverPtr.i);
3771 }
3772 
toCopyCompletedLab(Signal * signal,TakeOverRecordPtr takeOverPtr)3773 void Dbdih::toCopyCompletedLab(Signal * signal, TakeOverRecordPtr takeOverPtr)
3774 {
3775   signal->theData[0] = NDB_LE_NR_CopyFragsCompleted;
3776   signal->theData[1] = takeOverPtr.p->toStartingNode;
3777   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
3778 
3779   if (getNodeState().getSystemRestartInProgress())
3780   {
3781     jam();
3782     infoEvent("Take over of node %d complete", takeOverPtr.p->toStartingNode);
3783     setNodeActiveStatus(takeOverPtr.p->toStartingNode, Sysfile::NS_Active);
3784     takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
3785     takeOverCompleted(takeOverPtr.p->toStartingNode);
3786     checkToCopy();
3787     checkToCopyCompleted(signal);
3788     return;
3789   }
3790 
3791   c_lcpState.immediateLcpStart = true;
3792   takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
3793 
3794   /*-----------------------------------------------------------------------*/
3795   /* NOW WE CAN ALLOW THE NEW NODE TO PARTICIPATE IN LOCAL CHECKPOINTS.    */
3796   /* WHEN THE FIRST LOCAL CHECKPOINT IS READY WE DECLARE THE TAKE OVER AS  */
3797   /* COMPLETED. SINCE LOCAL CHECKPOINTS HAVE BEEN BLOCKED DURING THE COPY  */
3798   /* PROCESS WE MUST ALSO START A NEW LOCAL CHECKPOINT PROCESS BY ENSURING */
3799   /* THAT IT LOOKS LIKE IT IS TIME FOR A NEW LOCAL CHECKPOINT AND BY       */
3800   /* UNBLOCKING THE LOCAL CHECKPOINT AGAIN.                                */
3801   /* --------------------------------------------------------------------- */
3802 }//Dbdih::toCopyCompletedLab()
3803 
sendEndTo(Signal * signal,Uint32 takeOverPtrI)3804 void Dbdih::sendEndTo(Signal* signal, Uint32 takeOverPtrI)
3805 {
3806   TakeOverRecordPtr takeOverPtr;
3807   CRASH_INSERTION(7156);
3808   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3809   if ((c_endToLock != RNIL) || (ERROR_INSERTED(7164))) {
3810     jam();
3811     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_ENDING;
3812     signal->theData[0] = DihContinueB::ZSEND_END_TO;
3813     signal->theData[1] = takeOverPtrI;
3814     signal->theData[2] = takeOverPtr.p->toStartingNode;
3815     signal->theData[3] = takeOverPtr.p->toFailedNode;
3816     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 4);
3817     return;
3818   }//if
3819   c_endToLock = takeOverPtr.i;
3820   takeOverPtr.p->toMasterStatus = TakeOverRecord::ENDING;
3821   EndToReq * const req = (EndToReq *)&signal->theData[0];
3822   req->userPtr = takeOverPtr.i;
3823   req->userRef = reference();
3824   req->startingNodeId = takeOverPtr.p->toStartingNode;
3825   sendLoopMacro(END_TOREQ, sendEND_TOREQ);
3826 }//Dbdih::sendStartTo()
3827 
execEND_TOREQ(Signal * signal)3828 void Dbdih::execEND_TOREQ(Signal* signal)
3829 {
3830   jamEntry();
3831   const EndToReq * const req = (EndToReq *)&signal->theData[0];
3832   BlockReference ref = req->userRef;
3833   Uint32 startingNodeId = req->startingNodeId;
3834 
3835   CRASH_INSERTION(7144);
3836   RETURN_IF_NODE_NOT_ALIVE(startingNodeId);
3837 
3838   TakeOverRecordPtr takeOverPtr;
3839   takeOverPtr.i = req->userPtr;
3840   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3841 
3842   ndbrequire(startingNodeId == takeOverPtr.p->toStartingNode);
3843   takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_IDLE;
3844 
3845   if (!isMaster()) {
3846     jam();
3847     endTakeOver(takeOverPtr.i);
3848   }//if
3849 
3850   EndToConf * const conf = (EndToConf *)&signal->theData[0];
3851   conf->userPtr = takeOverPtr.i;
3852   conf->sendingNodeId = cownNodeId;
3853   conf->startingNodeId = startingNodeId;
3854   sendSignal(ref, GSN_END_TOCONF, signal, EndToConf::SignalLength, JBB);
3855 }//Dbdih::execEND_TOREQ()
3856 
execEND_TOCONF(Signal * signal)3857 void Dbdih::execEND_TOCONF(Signal* signal)
3858 {
3859   const EndToConf * const conf = (EndToConf *)&signal->theData[0];
3860   jamEntry();
3861 
3862   const Uint32 nodeId = conf->startingNodeId;
3863   CRASH_INSERTION(7145);
3864 
3865   RETURN_IF_NODE_NOT_ALIVE(nodeId);
3866 
3867   TakeOverRecordPtr takeOverPtr;
3868   takeOverPtr.i = conf->userPtr;
3869   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3870 
3871   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::ENDING);
3872   ndbrequire(nodeId == takeOverPtr.p->toStartingNode);
3873 
3874   receiveLoopMacro(END_TOREQ, conf->sendingNodeId);
3875   CRASH_INSERTION(7146);
3876   c_endToLock = RNIL;
3877 
3878   /* -----------------------------------------------------------------------*/
3879   /*  WE HAVE FINALLY COMPLETED THE TAKE OVER. WE RESET THE STATUS AND CHECK*/
3880   /*  IF ANY MORE TAKE OVERS ARE NEEDED AT THE MOMENT.                      */
3881   /*  FIRST WE CHECK IF A RESTART IS ONGOING. IN THAT CASE WE RESTART PHASE */
3882   /*  4 AND CHECK IF ANY MORE TAKE OVERS ARE NEEDED BEFORE WE START NDB     */
3883   /*  CLUSTER. THIS CAN ONLY HAPPEN IN A SYSTEM RESTART.                    */
3884   /* ---------------------------------------------------------------------- */
3885   if (takeOverPtr.p->toNodeRestart) {
3886     jam();
3887     /* ----------------------------------------------------------------------*/
3888     /* THE TAKE OVER NODE WAS A STARTING NODE. WE WILL SEND START_COPYCONF   */
3889     /* TO THE STARTING NODE SUCH THAT THE NODE CAN COMPLETE THE START-UP.    */
3890     /* --------------------------------------------------------------------- */
3891     BlockReference ref = calcDihBlockRef(takeOverPtr.p->toStartingNode);
3892     signal->theData[0] = takeOverPtr.p->toStartingNode;
3893     sendSignal(ref, GSN_START_COPYCONF, signal, 1,JBB);
3894   }//if
3895   endTakeOver(takeOverPtr.i);
3896 
3897   if (cstartPhase == ZNDB_SPH4) {
3898     jam();
3899     if (anyActiveTakeOver()) {
3900       jam();
3901       return;
3902     }//if
3903     ndbsttorry10Lab(signal, __LINE__);
3904     return;
3905   }//if
3906   checkStartTakeOver(signal);
3907 }//Dbdih::execEND_TOCONF()
3908 
allocateTakeOver(TakeOverRecordPtr & takeOverPtr)3909 void Dbdih::allocateTakeOver(TakeOverRecordPtr& takeOverPtr)
3910 {
3911   if (isMaster()) {
3912     jam();
3913     //--------------------------------------------
3914     // Master already seized the take over record.
3915     //--------------------------------------------
3916     return;
3917   }//if
3918   if (takeOverPtr.i == cfirstfreeTakeOver) {
3919     jam();
3920     seizeTakeOver(takeOverPtr);
3921   } else {
3922     TakeOverRecordPtr nextTakeOverptr;
3923     TakeOverRecordPtr prevTakeOverptr;
3924     nextTakeOverptr.i = takeOverPtr.p->nextTakeOver;
3925     prevTakeOverptr.i = takeOverPtr.p->prevTakeOver;
3926     if (prevTakeOverptr.i != RNIL) {
3927       jam();
3928       ptrCheckGuard(prevTakeOverptr, MAX_NDB_NODES, takeOverRecord);
3929       prevTakeOverptr.p->nextTakeOver = nextTakeOverptr.i;
3930     }//if
3931     if (nextTakeOverptr.i != RNIL) {
3932       jam();
3933       ptrCheckGuard(nextTakeOverptr, MAX_NDB_NODES, takeOverRecord);
3934       nextTakeOverptr.p->prevTakeOver = prevTakeOverptr.i;
3935     }//if
3936   }//if
3937 }//Dbdih::allocateTakeOver()
3938 
seizeTakeOver(TakeOverRecordPtr & takeOverPtr)3939 void Dbdih::seizeTakeOver(TakeOverRecordPtr& takeOverPtr)
3940 {
3941   TakeOverRecordPtr nextTakeOverptr;
3942   ndbrequire(cfirstfreeTakeOver != RNIL);
3943   takeOverPtr.i = cfirstfreeTakeOver;
3944   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3945   cfirstfreeTakeOver = takeOverPtr.p->nextTakeOver;
3946   nextTakeOverptr.i = takeOverPtr.p->nextTakeOver;
3947   if (nextTakeOverptr.i != RNIL) {
3948     jam();
3949     ptrCheckGuard(nextTakeOverptr, MAX_NDB_NODES, takeOverRecord);
3950     nextTakeOverptr.p->prevTakeOver = RNIL;
3951   }//if
3952   takeOverPtr.p->nextTakeOver = RNIL;
3953   takeOverPtr.p->prevTakeOver = RNIL;
3954 }//Dbdih::seizeTakeOver()
3955 
endTakeOver(Uint32 takeOverPtrI)3956 void Dbdih::endTakeOver(Uint32 takeOverPtrI)
3957 {
3958   TakeOverRecordPtr takeOverPtr;
3959   takeOverPtr.i = takeOverPtrI;
3960   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3961 
3962   if ((takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) &&
3963       (takeOverPtr.p->toMasterStatus != TakeOverRecord::TO_WAIT_START_TAKE_OVER)) {
3964     jam();
3965     NodeGroupRecordPtr NGPtr;
3966     NodeRecordPtr nodePtr;
3967     nodePtr.i = takeOverPtr.p->toStartingNode;
3968     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3969     NGPtr.i = nodePtr.p->nodeGroup;
3970     ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
3971     NGPtr.p->activeTakeOver = false;
3972   }//if
3973   setAllowNodeStart(takeOverPtr.p->toStartingNode, true);
3974   initTakeOver(takeOverPtr);
3975   releaseTakeOver(takeOverPtrI);
3976 }//Dbdih::endTakeOver()
3977 
releaseTakeOver(Uint32 takeOverPtrI)3978 void Dbdih::releaseTakeOver(Uint32 takeOverPtrI)
3979 {
3980   TakeOverRecordPtr takeOverPtr;
3981   takeOverPtr.i = takeOverPtrI;
3982   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3983 
3984   takeOverPtr.p->nextTakeOver = cfirstfreeTakeOver;
3985   cfirstfreeTakeOver = takeOverPtr.i;
3986 }//Dbdih::releaseTakeOver()
3987 
initTakeOver(TakeOverRecordPtr takeOverPtr)3988 void Dbdih::initTakeOver(TakeOverRecordPtr takeOverPtr)
3989 {
3990   takeOverPtr.p->toCopyNode = RNIL;
3991   takeOverPtr.p->toCurrentFragid = RNIL;
3992   takeOverPtr.p->toCurrentReplica = RNIL;
3993   takeOverPtr.p->toCurrentTabref = RNIL;
3994   takeOverPtr.p->toFailedNode = RNIL;
3995   takeOverPtr.p->toStartingNode = RNIL;
3996   takeOverPtr.p->prevTakeOver = RNIL;
3997   takeOverPtr.p->nextTakeOver = RNIL;
3998   takeOverPtr.p->toNodeRestart = false;
3999   takeOverPtr.p->toMasterStatus = TakeOverRecord::IDLE;
4000   takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_IDLE;
4001 }//Dbdih::initTakeOver()
4002 
anyActiveTakeOver()4003 bool Dbdih::anyActiveTakeOver()
4004 {
4005   TakeOverRecordPtr takeOverPtr;
4006   for (takeOverPtr.i = 0; takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
4007     ptrAss(takeOverPtr, takeOverRecord);
4008     if (takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) {
4009       jam();
4010       return true;
4011     }//if
4012   }//for
4013   return false;
4014 }//Dbdih::anyActiveTakeOver()
4015 
4016 /*****************************************************************************/
4017 /* ------------------------------------------------------------------------- */
4018 /*       WE HAVE BEEN REQUESTED TO PERFORM A SYSTEM RESTART. WE START BY     */
4019 /*       READING THE GCI FILES. THIS REQUEST WILL ONLY BE SENT TO THE MASTER */
4020 /*       DIH. THAT MEANS WE HAVE TO REPLICATE THE INFORMATION WE READ FROM   */
4021 /*       OUR FILES TO ENSURE THAT ALL NODES HAVE THE SAME DISTRIBUTION       */
4022 /*       INFORMATION.                                                        */
4023 /* ------------------------------------------------------------------------- */
4024 /*****************************************************************************/
readGciFileLab(Signal * signal)4025 void Dbdih::readGciFileLab(Signal* signal)
4026 {
4027   FileRecordPtr filePtr;
4028   filePtr.i = crestartInfoFile[0];
4029   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4030   filePtr.p->reqStatus = FileRecord::OPENING_GCP;
4031 
4032   openFileRo(signal, filePtr);
4033 }//Dbdih::readGciFileLab()
4034 
openingGcpLab(Signal * signal,FileRecordPtr filePtr)4035 void Dbdih::openingGcpLab(Signal* signal, FileRecordPtr filePtr)
4036 {
4037   /* ----------------------------------------------------------------------- */
4038   /*     WE HAVE SUCCESSFULLY OPENED A FILE CONTAINING INFORMATION ABOUT     */
4039   /*     THE GLOBAL CHECKPOINTS THAT ARE POSSIBLE TO RESTART.                */
4040   /* ----------------------------------------------------------------------- */
4041   readRestorableGci(signal, filePtr);
4042   filePtr.p->reqStatus = FileRecord::READING_GCP;
4043 }//Dbdih::openingGcpLab()
4044 
readingGcpLab(Signal * signal,FileRecordPtr filePtr)4045 void Dbdih::readingGcpLab(Signal* signal, FileRecordPtr filePtr)
4046 {
4047   /* ----------------------------------------------------------------------- */
4048   /*     WE HAVE NOW SUCCESSFULLY MANAGED TO READ IN THE GLOBAL CHECKPOINT   */
4049   /*     INFORMATION FROM FILE. LATER WE WILL ADD SOME FUNCTIONALITY THAT    */
4050   /*     CHECKS THE RESTART TIMERS TO DEDUCE FROM WHERE TO RESTART.          */
4051   /*     NOW WE WILL SIMPLY RESTART FROM THE NEWEST GLOBAL CHECKPOINT        */
4052   /*     POSSIBLE TO RESTORE.                                                */
4053   /*                                                                         */
4054   /*     BEFORE WE INVOKE DICT WE NEED TO COPY CRESTART_INFO TO ALL NODES.   */
4055   /*     WE ALSO COPY TO OUR OWN NODE. TO ENABLE US TO DO THIS PROPERLY WE   */
4056   /*     START BY CLOSING THIS FILE.                                         */
4057   /* ----------------------------------------------------------------------- */
4058   globalData.m_restart_seq = ++SYSFILE->m_restart_seq;
4059   closeFile(signal, filePtr);
4060   filePtr.p->reqStatus = FileRecord::CLOSING_GCP;
4061 }//Dbdih::readingGcpLab()
4062 
closingGcpLab(Signal * signal,FileRecordPtr filePtr)4063 void Dbdih::closingGcpLab(Signal* signal, FileRecordPtr filePtr)
4064 {
4065   if (Sysfile::getInitialStartOngoing(SYSFILE->systemRestartBits) == false){
4066     jam();
4067     selectMasterCandidateAndSend(signal);
4068     return;
4069   } else {
4070     jam();
4071     sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
4072     return;
4073   }//if
4074 }//Dbdih::closingGcpLab()
4075 
4076 /* ------------------------------------------------------------------------- */
4077 /*       SELECT THE MASTER CANDIDATE TO BE USED IN SYSTEM RESTARTS.          */
4078 /* ------------------------------------------------------------------------- */
selectMasterCandidateAndSend(Signal * signal)4079 void Dbdih::selectMasterCandidateAndSend(Signal* signal)
4080 {
4081   setNodeGroups();
4082   signal->theData[0] = getOwnNodeId();
4083   signal->theData[1] = SYSFILE->lastCompletedGCI[getOwnNodeId()];
4084   sendSignal(cntrlblockref, GSN_DIH_RESTARTCONF, signal, 2, JBB);
4085 
4086   NodeRecordPtr nodePtr;
4087   Uint32 node_groups[MAX_NDB_NODES];
4088   memset(node_groups, 0, sizeof(node_groups));
4089   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
4090     jam();
4091     const Uint32 ng = Sysfile::getNodeGroup(nodePtr.i, SYSFILE->nodeGroups);
4092     if(ng != NO_NODE_GROUP_ID){
4093       ndbrequire(ng < MAX_NDB_NODES);
4094       node_groups[ng]++;
4095     }
4096   }
4097 
4098   for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
4099     jam();
4100     Uint32 count = node_groups[nodePtr.i];
4101     if(count != 0 && count != cnoReplicas){
4102       char buf[255];
4103       BaseString::snprintf(buf, sizeof(buf),
4104 			   "Illegal configuration change."
4105 			   " Initial start needs to be performed "
4106 			   " when changing no of replicas (%d != %d)",
4107 			   node_groups[nodePtr.i], cnoReplicas);
4108       progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
4109     }
4110   }
4111 }//Dbdih::selectMasterCandidate()
4112 
4113 /* ------------------------------------------------------------------------- */
4114 /*       ERROR HANDLING DURING READING RESTORABLE GCI FROM FILE.             */
4115 /* ------------------------------------------------------------------------- */
openingGcpErrorLab(Signal * signal,FileRecordPtr filePtr)4116 void Dbdih::openingGcpErrorLab(Signal* signal, FileRecordPtr filePtr)
4117 {
4118   filePtr.p->fileStatus = FileRecord::CRASHED;
4119   filePtr.p->reqStatus = FileRecord::IDLE;
4120   if (crestartInfoFile[0] == filePtr.i) {
4121     jam();
4122     /* --------------------------------------------------------------------- */
4123     /*   THE FIRST FILE WAS NOT ABLE TO BE OPENED. SET STATUS TO CRASHED AND */
4124     /*   TRY OPEN THE NEXT FILE.                                             */
4125     /* --------------------------------------------------------------------- */
4126     filePtr.i = crestartInfoFile[1];
4127     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4128     openFileRo(signal, filePtr);
4129     filePtr.p->reqStatus = FileRecord::OPENING_GCP;
4130   } else {
4131     jam();
4132     /* --------------------------------------------------------------------- */
4133     /*   WE FAILED IN OPENING THE SECOND FILE. BOTH FILES WERE CORRUPTED. WE */
4134     /*   CANNOT CONTINUE THE RESTART IN THIS CASE. TELL NDBCNTR OF OUR       */
4135     /*   FAILURE.                                                            */
4136     /*---------------------------------------------------------------------- */
4137     sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
4138     return;
4139   }//if
4140 }//Dbdih::openingGcpErrorLab()
4141 
readingGcpErrorLab(Signal * signal,FileRecordPtr filePtr)4142 void Dbdih::readingGcpErrorLab(Signal* signal, FileRecordPtr filePtr)
4143 {
4144   filePtr.p->fileStatus = FileRecord::CRASHED;
4145   /* ----------------------------------------------------------------------- */
4146   /*     WE FAILED IN READING THE FILE AS WELL. WE WILL CLOSE THIS FILE.     */
4147   /* ----------------------------------------------------------------------- */
4148   closeFile(signal, filePtr);
4149   filePtr.p->reqStatus = FileRecord::CLOSING_GCP_CRASH;
4150 }//Dbdih::readingGcpErrorLab()
4151 
closingGcpCrashLab(Signal * signal,FileRecordPtr filePtr)4152 void Dbdih::closingGcpCrashLab(Signal* signal, FileRecordPtr filePtr)
4153 {
4154   if (crestartInfoFile[0] == filePtr.i) {
4155     jam();
4156     /* --------------------------------------------------------------------- */
4157     /*   ERROR IN FIRST FILE, TRY THE SECOND FILE.                           */
4158     /* --------------------------------------------------------------------- */
4159     filePtr.i = crestartInfoFile[1];
4160     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4161     openFileRw(signal, filePtr);
4162     filePtr.p->reqStatus = FileRecord::OPENING_GCP;
4163     return;
4164   }//if
4165   /* ----------------------------------------------------------------------- */
4166   /*     WE DISCOVERED A FAILURE WITH THE SECOND FILE AS WELL. THIS IS A     */
4167   /*     SERIOUS PROBLEM. REPORT FAILURE TO NDBCNTR.                         */
4168   /* ----------------------------------------------------------------------- */
4169   sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
4170 }//Dbdih::closingGcpCrashLab()
4171 
4172 /*****************************************************************************/
4173 /* ------------------------------------------------------------------------- */
4174 /*       THIS IS AN INITIAL RESTART. WE WILL CREATE THE TWO FILES DESCRIBING */
4175 /*       THE GLOBAL CHECKPOINTS THAT ARE RESTORABLE.                         */
4176 /* ------------------------------------------------------------------------- */
4177 /*****************************************************************************/
initGciFilesLab(Signal * signal)4178 void Dbdih::initGciFilesLab(Signal* signal)
4179 {
4180   FileRecordPtr filePtr;
4181   filePtr.i = crestartInfoFile[0];
4182   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4183   createFileRw(signal, filePtr);
4184   filePtr.p->reqStatus = FileRecord::CREATING_GCP;
4185 }//Dbdih::initGciFilesLab()
4186 
4187 /* ------------------------------------------------------------------------- */
4188 /*       GLOBAL CHECKPOINT FILE HAVE BEEN SUCCESSFULLY CREATED.              */
4189 /* ------------------------------------------------------------------------- */
creatingGcpLab(Signal * signal,FileRecordPtr filePtr)4190 void Dbdih::creatingGcpLab(Signal* signal, FileRecordPtr filePtr)
4191 {
4192   if (filePtr.i == crestartInfoFile[0]) {
4193     jam();
4194     /* --------------------------------------------------------------------- */
4195     /*   IF CREATED FIRST THEN ALSO CREATE THE SECOND FILE.                  */
4196     /* --------------------------------------------------------------------- */
4197     filePtr.i = crestartInfoFile[1];
4198     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4199     createFileRw(signal, filePtr);
4200     filePtr.p->reqStatus = FileRecord::CREATING_GCP;
4201   } else {
4202     jam();
4203     /* --------------------------------------------------------------------- */
4204     /*   BOTH FILES HAVE BEEN CREATED. NOW WRITE THE INITIAL DATA TO BOTH    */
4205     /*   OF THE FILES.                                                       */
4206     /* --------------------------------------------------------------------- */
4207     filePtr.i = crestartInfoFile[0];
4208     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4209     writeRestorableGci(signal, filePtr);
4210     filePtr.p->reqStatus = FileRecord::WRITE_INIT_GCP;
4211   }//if
4212 }//Dbdih::creatingGcpLab()
4213 
4214 /* ------------------------------------------------------------------------- */
4215 /*       WE HAVE SUCCESSFULLY WRITTEN A GCI FILE.                            */
4216 /* ------------------------------------------------------------------------- */
writeInitGcpLab(Signal * signal,FileRecordPtr filePtr)4217 void Dbdih::writeInitGcpLab(Signal* signal, FileRecordPtr filePtr)
4218 {
4219   filePtr.p->reqStatus = FileRecord::IDLE;
4220   if (filePtr.i == crestartInfoFile[0]) {
4221     jam();
4222     /* --------------------------------------------------------------------- */
4223     /*   WE HAVE WRITTEN THE FIRST FILE NOW ALSO WRITE THE SECOND FILE.      */
4224     /* --------------------------------------------------------------------- */
4225     filePtr.i = crestartInfoFile[1];
4226     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4227     writeRestorableGci(signal, filePtr);
4228     filePtr.p->reqStatus = FileRecord::WRITE_INIT_GCP;
4229   } else {
4230     /* --------------------------------------------------------------------- */
4231     /*   WE HAVE WRITTEN BOTH FILES. LEAVE BOTH FILES OPEN AND CONFIRM OUR   */
4232     /*   PART OF THE INITIAL START.                                          */
4233     /* --------------------------------------------------------------------- */
4234     if (isMaster()) {
4235       jam();
4236       /*---------------------------------------------------------------------*/
4237       // IN MASTER NODES THE START REQUEST IS RECEIVED FROM NDBCNTR AND WE MUST
4238       // RESPOND WHEN COMPLETED.
4239       /*---------------------------------------------------------------------*/
4240       signal->theData[0] = reference();
4241       sendSignal(cndbStartReqBlockref, GSN_NDB_STARTCONF, signal, 1, JBB);
4242     } else {
4243       jam();
4244       ndbsttorry10Lab(signal, __LINE__);
4245       return;
4246     }//if
4247   }//if
4248 }//Dbdih::writeInitGcpLab()
4249 
4250 /*****************************************************************************/
4251 /* **********     NODES DELETION MODULE                          *************/
4252 /*****************************************************************************/
4253 /*---------------------------------------------------------------------------*/
4254 /*                    LOGIC FOR NODE FAILURE                                 */
4255 /*---------------------------------------------------------------------------*/
execNODE_FAILREP(Signal * signal)4256 void Dbdih::execNODE_FAILREP(Signal* signal)
4257 {
4258   Uint32 i;
4259   Uint32 failedNodes[MAX_NDB_NODES];
4260   jamEntry();
4261   NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
4262 
4263   cfailurenr = nodeFail->failNo;
4264   Uint32 newMasterId = nodeFail->masterNodeId;
4265   const Uint32 noOfFailedNodes = nodeFail->noOfNodes;
4266 
4267   if (ERROR_INSERTED(7179))
4268   {
4269     CLEAR_ERROR_INSERT_VALUE;
4270   }
4271 
4272   if (ERROR_INSERTED(7184))
4273   {
4274     SET_ERROR_INSERT_VALUE(7000);
4275   }
4276 
4277   /*-------------------------------------------------------------------------*/
4278   // The first step is to convert from a bit mask to an array of failed nodes.
4279   /*-------------------------------------------------------------------------*/
4280   Uint32 index = 0;
4281   for (i = 1; i < MAX_NDB_NODES; i++) {
4282     jam();
4283     if(NodeBitmask::get(nodeFail->theNodes, i)){
4284       jam();
4285       failedNodes[index] = i;
4286       index++;
4287     }//if
4288   }//for
4289   ndbrequire(noOfFailedNodes == index);
4290   ndbrequire(noOfFailedNodes - 1 < MAX_NDB_NODES);
4291 
4292   /*-------------------------------------------------------------------------*/
4293   // The second step is to update the node status of the failed nodes, remove
4294   // them from the alive node list and put them into the dead node list. Also
4295   // update the number of nodes on-line.
4296   // We also set certain state variables ensuring that the node no longer is
4297   // used in transactions and also mark that we received this signal.
4298   /*-------------------------------------------------------------------------*/
4299   for (i = 0; i < noOfFailedNodes; i++) {
4300     jam();
4301     NodeRecordPtr TNodePtr;
4302     TNodePtr.i = failedNodes[i];
4303     ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRecord);
4304     TNodePtr.p->useInTransactions = false;
4305     TNodePtr.p->m_inclDihLcp = false;
4306     TNodePtr.p->recNODE_FAILREP = ZTRUE;
4307     if (TNodePtr.p->nodeStatus == NodeRecord::ALIVE) {
4308       jam();
4309       con_lineNodes--;
4310       TNodePtr.p->nodeStatus = NodeRecord::DIED_NOW;
4311       removeAlive(TNodePtr);
4312       insertDeadNode(TNodePtr);
4313     }//if
4314   }//for
4315 
4316   /*-------------------------------------------------------------------------*/
4317   // Verify that we can continue to operate the cluster. If we cannot we will
4318   // not return from checkEscalation.
4319   /*-------------------------------------------------------------------------*/
4320   checkEscalation();
4321 
4322   /*------------------------------------------------------------------------*/
4323   // Verify that a starting node has also crashed. Reset the node start record.
4324   /*-------------------------------------------------------------------------*/
4325 #if 0
4326   /**
4327    * Node will crash by itself...
4328    *   nodeRestart is run then...
4329    */
4330   if (false && c_nodeStartMaster.startNode != RNIL && getNodeStatus(c_nodeStartMaster.startNode) == NodeRecord::ALIVE)
4331   {
4332     BlockReference cntrRef = calcNdbCntrBlockRef(c_nodeStartMaster.startNode);
4333     SystemError * const sysErr = (SystemError*)&signal->theData[0];
4334     sysErr->errorCode = SystemError::StartInProgressError;
4335     sysErr->errorRef = reference();
4336     sysErr->data1= 0;
4337     sysErr->data2= __LINE__;
4338     sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,  SystemError::SignalLength, JBA);
4339     nodeResetStart();
4340   }//if
4341 #endif
4342 
4343   /*--------------------------------------------------*/
4344   /*                                                  */
4345   /*       WE CHANGE THE REFERENCE TO MASTER DIH      */
4346   /*       BLOCK AND POINTER AT THIS PLACE IN THE CODE*/
4347   /*--------------------------------------------------*/
4348   Uint32 oldMasterId = cmasterNodeId;
4349   BlockReference oldMasterRef = cmasterdihref;
4350   cmasterdihref = calcDihBlockRef(newMasterId);
4351   cmasterNodeId = newMasterId;
4352 
4353   const bool masterTakeOver = (oldMasterId != newMasterId);
4354 
4355   for(i = 0; i < noOfFailedNodes; i++) {
4356     NodeRecordPtr failedNodePtr;
4357     failedNodePtr.i = failedNodes[i];
4358     ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
4359     Uint32 activeTakeOverPtr = findTakeOver(failedNodes[i]);
4360     if (oldMasterRef == reference()) {
4361       /*-------------------------------------------------------*/
4362       // Functions that need to be called only for master nodes.
4363       /*-------------------------------------------------------*/
4364       checkCopyTab(failedNodePtr);
4365       checkStopPermMaster(signal, failedNodePtr);
4366       checkWaitGCPMaster(signal, failedNodes[i]);
4367       checkTakeOverInMasterAllNodeFailure(signal, failedNodePtr);
4368       checkTakeOverInMasterCopyNodeFailure(signal, failedNodePtr.i);
4369       checkTakeOverInMasterStartNodeFailure(signal, activeTakeOverPtr);
4370       checkGcpOutstanding(signal, failedNodePtr.i);
4371     } else {
4372       jam();
4373       /*-----------------------------------------------------------*/
4374       // Functions that need to be called only for nodes that were
4375       // not master before these failures.
4376       /*-----------------------------------------------------------*/
4377       checkStopPermProxy(signal, failedNodes[i]);
4378       checkWaitGCPProxy(signal, failedNodes[i]);
4379       if (isMaster()) {
4380 	/*-----------------------------------------------------------*/
4381 	// We take over as master since old master has failed
4382 	/*-----------------------------------------------------------*/
4383         handleTakeOverNewMaster(signal, activeTakeOverPtr);
4384       } else {
4385 	/*-----------------------------------------------------------*/
4386 	// We are not master and will not become master.
4387 	/*-----------------------------------------------------------*/
4388         checkTakeOverInNonMasterStartNodeFailure(signal, activeTakeOverPtr);
4389       }//if
4390     }//if
4391     /*--------------------------------------------------*/
4392     // Functions that need to be called for all nodes.
4393     /*--------------------------------------------------*/
4394     checkStopMe(signal, failedNodePtr);
4395     failedNodeLcpHandling(signal, failedNodePtr);
4396     checkWaitDropTabFailedLqh(signal, failedNodePtr.i, 0); // 0 = start w/ tab 0
4397     startRemoveFailedNode(signal, failedNodePtr);
4398 
4399     /**
4400      * This is the last function called
4401      *   It modifies failedNodePtr.p->nodeStatus
4402      */
4403     failedNodeSynchHandling(signal, failedNodePtr);
4404   }//for
4405 
4406   if(masterTakeOver){
4407     jam();
4408     startLcpMasterTakeOver(signal, oldMasterId);
4409     startGcpMasterTakeOver(signal, oldMasterId);
4410 
4411     if(getNodeState().getNodeRestartInProgress()){
4412       jam();
4413       progError(__LINE__, NDBD_EXIT_MASTER_FAILURE_DURING_NR);
4414     }
4415   }
4416 
4417 
4418   if (isMaster()) {
4419     jam();
4420     setNodeRestartInfoBits();
4421   }//if
4422 }//Dbdih::execNODE_FAILREP()
4423 
checkCopyTab(NodeRecordPtr failedNodePtr)4424 void Dbdih::checkCopyTab(NodeRecordPtr failedNodePtr)
4425 {
4426   jam();
4427 
4428   if(c_nodeStartMaster.startNode != failedNodePtr.i){
4429     jam();
4430     return;
4431   }
4432 
4433   switch(c_nodeStartMaster.m_outstandingGsn){
4434   case GSN_COPY_TABREQ:
4435     jam();
4436     ndbrequire(c_COPY_TABREQ_Counter.isWaitingFor(failedNodePtr.i));
4437     releaseTabPages(failedNodePtr.p->activeTabptr);
4438     c_COPY_TABREQ_Counter.clearWaitingFor(failedNodePtr.i);
4439     c_nodeStartMaster.wait = ZFALSE;
4440     break;
4441   case GSN_START_INFOREQ:
4442   case GSN_START_PERMCONF:
4443   case GSN_DICTSTARTREQ:
4444   case GSN_START_MECONF:
4445     jam();
4446     break;
4447   default:
4448     g_eventLogger.error("outstanding gsn: %s(%d)",
4449                         getSignalName(c_nodeStartMaster.m_outstandingGsn),
4450                         c_nodeStartMaster.m_outstandingGsn);
4451     ndbrequire(false);
4452   }
4453 
4454   nodeResetStart();
4455 }//Dbdih::checkCopyTab()
4456 
checkStopMe(Signal * signal,NodeRecordPtr failedNodePtr)4457 void Dbdih::checkStopMe(Signal* signal, NodeRecordPtr failedNodePtr)
4458 {
4459   jam();
4460   if (c_STOP_ME_REQ_Counter.isWaitingFor(failedNodePtr.i)){
4461     jam();
4462     ndbrequire(c_stopMe.clientRef != 0);
4463     StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
4464     stopMeConf->senderRef = calcDihBlockRef(failedNodePtr.i);
4465     stopMeConf->senderData = c_stopMe.clientData;
4466     sendSignal(reference(), GSN_STOP_ME_CONF, signal,
4467 	       StopMeConf::SignalLength, JBB);
4468   }//if
4469 }//Dbdih::checkStopMe()
4470 
checkStopPermMaster(Signal * signal,NodeRecordPtr failedNodePtr)4471 void Dbdih::checkStopPermMaster(Signal* signal, NodeRecordPtr failedNodePtr)
4472 {
4473   DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
4474   jam();
4475   if (c_DIH_SWITCH_REPLICA_REQ_Counter.isWaitingFor(failedNodePtr.i)){
4476     jam();
4477     ndbrequire(c_stopPermMaster.clientRef != 0);
4478     ref->senderNode = failedNodePtr.i;
4479     ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
4480     sendSignal(reference(), GSN_DIH_SWITCH_REPLICA_REF, signal,
4481                DihSwitchReplicaRef::SignalLength, JBB);
4482     return;
4483   }//if
4484 }//Dbdih::checkStopPermMaster()
4485 
checkStopPermProxy(Signal * signal,NodeId failedNodeId)4486 void Dbdih::checkStopPermProxy(Signal* signal, NodeId failedNodeId)
4487 {
4488   jam();
4489   if(c_stopPermProxy.clientRef != 0 &&
4490      refToNode(c_stopPermProxy.masterRef) == failedNodeId){
4491 
4492     /**
4493      * The master has failed report to proxy-client
4494      */
4495     jam();
4496     StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
4497 
4498     ref->senderData = c_stopPermProxy.clientData;
4499     ref->errorCode  = StopPermRef::NF_CausedAbortOfStopProcedure;
4500     sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_REF, signal, 2, JBB);
4501     c_stopPermProxy.clientRef = 0;
4502   }//if
4503 }//Dbdih::checkStopPermProxy()
4504 
4505 void
checkTakeOverInMasterAllNodeFailure(Signal * signal,NodeRecordPtr failedNodePtr)4506 Dbdih::checkTakeOverInMasterAllNodeFailure(Signal* signal,
4507 					   NodeRecordPtr failedNodePtr)
4508 {
4509   //------------------------------------------------------------------------
4510   // This code is used to handle the failure of "all" nodes during the
4511   // take over when "all" nodes are informed about state changes in
4512   // the take over protocol.
4513   //--------------------------------------------------------------------------
4514   if (c_START_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
4515     jam();
4516     StartToConf * const conf = (StartToConf *)&signal->theData[0];
4517     conf->userPtr = c_startToLock;
4518     conf->sendingNodeId = failedNodePtr.i;
4519     conf->startingNodeId = getStartNode(c_startToLock);
4520     sendSignal(reference(), GSN_START_TOCONF, signal,
4521 	       StartToConf::SignalLength, JBB);
4522   }//if
4523   if (c_CREATE_FRAGREQ_Counter.isWaitingFor(failedNodePtr.i)){
4524     jam();
4525     CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
4526     TakeOverRecordPtr takeOverPtr;
4527     takeOverPtr.i = c_createFragmentLock;
4528     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4529     conf->userPtr = takeOverPtr.i;
4530     conf->tableId = takeOverPtr.p->toCurrentTabref;
4531     conf->fragId = takeOverPtr.p->toCurrentFragid;
4532     conf->sendingNodeId = failedNodePtr.i;
4533     conf->startingNodeId = takeOverPtr.p->toStartingNode;
4534     sendSignal(reference(), GSN_CREATE_FRAGCONF, signal,
4535                CreateFragConf::SignalLength, JBB);
4536   }//if
4537   if (c_UPDATE_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
4538     jam();
4539     UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
4540     conf->userPtr = c_updateToLock;
4541     conf->sendingNodeId = failedNodePtr.i;
4542     conf->startingNodeId = getStartNode(c_updateToLock);
4543     sendSignal(reference(), GSN_UPDATE_TOCONF, signal,
4544 	       UpdateToConf::SignalLength, JBB);
4545   }//if
4546 
4547   if (c_END_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
4548     jam();
4549     EndToConf * const conf = (EndToConf *)&signal->theData[0];
4550     conf->userPtr = c_endToLock;
4551     conf->sendingNodeId = failedNodePtr.i;
4552     conf->startingNodeId = getStartNode(c_endToLock);
4553     sendSignal(reference(), GSN_END_TOCONF, signal,
4554 	       EndToConf::SignalLength, JBB);
4555   }//if
4556 }//Dbdih::checkTakeOverInMasterAllNodeFailure()
4557 
checkTakeOverInMasterCopyNodeFailure(Signal * signal,Uint32 failedNodeId)4558 void Dbdih::checkTakeOverInMasterCopyNodeFailure(Signal* signal,
4559 						 Uint32 failedNodeId)
4560 {
4561   //---------------------------------------------------------------------------
4562   // This code is used to handle failure of the copying node during a take over
4563   //---------------------------------------------------------------------------
4564   TakeOverRecordPtr takeOverPtr;
4565   for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
4566     jam();
4567     takeOverPtr.i = i;
4568     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4569     if ((takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG) &&
4570         (takeOverPtr.p->toCopyNode == failedNodeId)) {
4571       jam();
4572       /**
4573        * The copying node failed but the system is still operational.
4574        * We restart the copy process by selecting a new copy node.
4575        * We do not need to add a fragment however since it is already added.
4576        * We start again from the prepare create fragment phase.
4577        */
4578       prepareSendCreateFragReq(signal, takeOverPtr.i);
4579     }//if
4580   }//for
4581 }//Dbdih::checkTakeOverInMasterCopyNodeFailure()
4582 
checkTakeOverInMasterStartNodeFailure(Signal * signal,Uint32 takeOverPtrI)4583 void Dbdih::checkTakeOverInMasterStartNodeFailure(Signal* signal,
4584 						  Uint32 takeOverPtrI)
4585 {
4586   jam();
4587   ndbout_c("checkTakeOverInMasterStartNodeFailure %x",
4588 	   takeOverPtrI);
4589   if (takeOverPtrI == RNIL) {
4590     jam();
4591     return;
4592   }
4593   //-----------------------------------------------------------------------
4594   // We are the master and the starting node has failed during a take over.
4595   // We need to handle this failure in different ways depending on the state.
4596   //-----------------------------------------------------------------------
4597 
4598   TakeOverRecordPtr takeOverPtr;
4599   takeOverPtr.i = takeOverPtrI;
4600   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4601 
4602   ndbout_c("takeOverPtr.p->toMasterStatus: %x",
4603 	   takeOverPtr.p->toMasterStatus);
4604 
4605   bool ok = false;
4606   switch (takeOverPtr.p->toMasterStatus) {
4607   case TakeOverRecord::IDLE:
4608     //-----------------------------------------------------------------------
4609     // The state cannot be idle when it has a starting node.
4610     //-----------------------------------------------------------------------
4611     ndbrequire(false);
4612     break;
4613   case TakeOverRecord::TO_WAIT_START_TAKE_OVER:
4614     jam();
4615   case TakeOverRecord::TO_START_COPY:
4616     jam();
4617   case TakeOverRecord::TO_START_COPY_ONGOING:
4618     jam();
4619   case TakeOverRecord::TO_WAIT_START:
4620     jam();
4621   case TakeOverRecord::TO_WAIT_PREPARE_CREATE:
4622     jam();
4623   case TakeOverRecord::TO_WAIT_UPDATE_TO:
4624     jam();
4625   case TakeOverRecord::TO_WAIT_COMMIT_CREATE:
4626     jam();
4627   case TakeOverRecord::TO_END_COPY:
4628     jam();
4629   case TakeOverRecord::TO_END_COPY_ONGOING:
4630     jam();
4631   case TakeOverRecord::TO_WAIT_ENDING:
4632     jam();
4633     //-----------------------------------------------------------------------
4634     // We will not do anything since an internal signal process is outstanding.
4635     // When the signal arrives the take over will be released.
4636     //-----------------------------------------------------------------------
4637     ok = true;
4638     break;
4639   case TakeOverRecord::STARTING:
4640     jam();
4641     ok = true;
4642     c_startToLock = RNIL;
4643     c_START_TOREQ_Counter.clearWaitingFor();
4644     endTakeOver(takeOverPtr.i);
4645     break;
4646   case TakeOverRecord::TO_UPDATE_TO:
4647     jam();
4648     ok = true;
4649     c_updateToLock = RNIL;
4650     c_UPDATE_TOREQ_Counter.clearWaitingFor();
4651     endTakeOver(takeOverPtr.i);
4652     break;
4653   case TakeOverRecord::ENDING:
4654     jam();
4655     ok = true;
4656     c_endToLock = RNIL;
4657     c_END_TOREQ_Counter.clearWaitingFor();
4658     endTakeOver(takeOverPtr.i);
4659     break;
4660   case TakeOverRecord::COMMIT_CREATE:
4661     ok = true;
4662     jam();
4663     {// We have mutex
4664       Mutex m(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
4665       m.unlock(); // Ignore result
4666     }
4667     // Fall through
4668   case TakeOverRecord::PREPARE_CREATE:
4669     ok = true;
4670     jam();
4671     c_createFragmentLock = RNIL;
4672     c_CREATE_FRAGREQ_Counter.clearWaitingFor();
4673     endTakeOver(takeOverPtr.i);
4674     break;
4675   case TakeOverRecord::LOCK_MUTEX:
4676     ok = true;
4677     jam();
4678     // Lock mutex will return and do endTakeOver
4679     break;
4680 
4681     //-----------------------------------------------------------------------
4682     // Signals are outstanding to external nodes. These signals carry the node
4683     // id of the starting node and will not use the take over record if the
4684     // starting node has failed.
4685     //-----------------------------------------------------------------------
4686   case TakeOverRecord::COPY_FRAG:
4687     ok = true;
4688     jam();
4689     //-----------------------------------------------------------------------
4690     // The copying node will discover the problem. We will receive either
4691     // COPY_FRAGREQ or COPY_FRAGCONF and then we can release the take over
4692     // record and end the process. If the copying node should also die then
4693     // we will try to send prepare create fragment and will then discover
4694     // that the starting node has failed.
4695     //-----------------------------------------------------------------------
4696     break;
4697   case TakeOverRecord::PREPARE_COPY:
4698     ok = true;
4699     jam();
4700     /**
4701      * We're waiting for the starting node...which just died...
4702      *  endTakeOver
4703      */
4704     endTakeOver(takeOverPtr.i);
4705     break;
4706   case TakeOverRecord::COPY_ACTIVE:
4707     ok = true;
4708     jam();
4709     //-----------------------------------------------------------------------
4710     // In this we are waiting for a signal from the starting node. Thus we
4711     // can release the take over record and end the process.
4712     //-----------------------------------------------------------------------
4713     endTakeOver(takeOverPtr.i);
4714     break;
4715   case TakeOverRecord::WAIT_LCP:
4716     ok = true;
4717     jam();
4718     //-----------------------------------------------------------------------
4719     //-----------------------------------------------------------------------
4720     endTakeOver(takeOverPtr.i);
4721     break;
4722 
4723   case TakeOverRecord::STARTING_LOCAL_FRAGMENTS:
4724     ok = true;
4725     jam();
4726     endTakeOver(takeOverPtr.i);
4727     break;
4728 
4729     /**
4730      * The following are states that it should not be possible to "be" in
4731      */
4732   case TakeOverRecord::SELECTING_NEXT:
4733     jam();
4734   case TakeOverRecord::TO_COPY_COMPLETED:
4735     jam();
4736     ndbrequire(false);
4737   }
4738   if(!ok){
4739     jamLine(takeOverPtr.p->toSlaveStatus);
4740     ndbrequire(ok);
4741   }
4742 }//Dbdih::checkTakeOverInMasterStartNodeFailure()
4743 
checkTakeOverInNonMasterStartNodeFailure(Signal * signal,Uint32 takeOverPtrI)4744 void Dbdih::checkTakeOverInNonMasterStartNodeFailure(Signal* signal,
4745 						     Uint32 takeOverPtrI)
4746 {
4747   jam();
4748   if (takeOverPtrI == RNIL) {
4749     jam();
4750     return;
4751   }
4752   //-----------------------------------------------------------------------
4753   // We are not master and not taking over as master. A take over was ongoing
4754   // but the starting node has now failed. Handle it according to the state
4755   // of the take over.
4756   //-----------------------------------------------------------------------
4757   TakeOverRecordPtr takeOverPtr;
4758   takeOverPtr.i = takeOverPtrI;
4759   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4760   bool ok = false;
4761   switch (takeOverPtr.p->toSlaveStatus) {
4762   case TakeOverRecord::TO_SLAVE_IDLE:
4763     ndbrequire(false);
4764     break;
4765   case TakeOverRecord::TO_SLAVE_STARTED:
4766     jam();
4767   case TakeOverRecord::TO_SLAVE_CREATE_PREPARE:
4768     jam();
4769   case TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED:
4770     jam();
4771   case TakeOverRecord::TO_SLAVE_CREATE_COMMIT:
4772     jam();
4773   case TakeOverRecord::TO_SLAVE_COPY_COMPLETED:
4774     jam();
4775     ok = true;
4776     endTakeOver(takeOverPtr.i);
4777     break;
4778   }//switch
4779   if(!ok){
4780     jamLine(takeOverPtr.p->toSlaveStatus);
4781     ndbrequire(ok);
4782   }
4783 }//Dbdih::checkTakeOverInNonMasterStartNodeFailure()
4784 
failedNodeSynchHandling(Signal * signal,NodeRecordPtr failedNodePtr)4785 void Dbdih::failedNodeSynchHandling(Signal* signal,
4786 				    NodeRecordPtr failedNodePtr)
4787 {
4788   jam();
4789   /*----------------------------------------------------*/
4790   /*       INITIALISE THE VARIABLES THAT KEEP TRACK OF  */
4791   /*       WHEN A NODE FAILURE IS COMPLETED.            */
4792   /*----------------------------------------------------*/
4793   failedNodePtr.p->dbdictFailCompleted = ZFALSE;
4794   failedNodePtr.p->dbtcFailCompleted = ZFALSE;
4795   failedNodePtr.p->dbdihFailCompleted = ZFALSE;
4796   failedNodePtr.p->dblqhFailCompleted = ZFALSE;
4797 
4798   failedNodePtr.p->m_NF_COMPLETE_REP.clearWaitingFor();
4799 
4800   NodeRecordPtr nodePtr;
4801   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
4802     ptrAss(nodePtr, nodeRecord);
4803     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
4804       jam();
4805       /**
4806        * We'r waiting for nodePtr.i to complete
4807        * handling of failedNodePtr.i's death
4808        */
4809 
4810       failedNodePtr.p->m_NF_COMPLETE_REP.setWaitingFor(nodePtr.i);
4811     } else {
4812       jam();
4813       if ((nodePtr.p->nodeStatus == NodeRecord::DYING) &&
4814           (nodePtr.p->m_NF_COMPLETE_REP.isWaitingFor(failedNodePtr.i))){
4815         jam();
4816 	/*----------------------------------------------------*/
4817 	/*       THE NODE FAILED BEFORE REPORTING THE FAILURE */
4818 	/*       HANDLING COMPLETED ON THIS FAILED NODE.      */
4819 	/*       REPORT THAT NODE FAILURE HANDLING WAS        */
4820 	/*       COMPLETED ON THE NEW FAILED NODE FOR THIS    */
4821 	/*       PARTICULAR OLD FAILED NODE.                  */
4822 	/*----------------------------------------------------*/
4823         NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
4824         nf->blockNo = 0;
4825         nf->nodeId  = failedNodePtr.i;
4826         nf->failedNodeId = nodePtr.i;
4827 	nf->from    = __LINE__;
4828         sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
4829                    NFCompleteRep::SignalLength, JBB);
4830       }//if
4831     }//if
4832   }//for
4833   if (failedNodePtr.p->nodeStatus == NodeRecord::DIED_NOW) {
4834     jam();
4835     failedNodePtr.p->nodeStatus = NodeRecord::DYING;
4836   } else {
4837     jam();
4838     /*----------------------------------------------------*/
4839     // No more processing needed when node not even started
4840     // yet. We give the node status to DEAD since we do not
4841     // care whether all nodes complete the node failure
4842     // handling. The node have not been included in the
4843     // node failure protocols.
4844     /*----------------------------------------------------*/
4845     failedNodePtr.p->nodeStatus = NodeRecord::DEAD;
4846     /**-----------------------------------------------------------------------
4847      * WE HAVE COMPLETED HANDLING THE NODE FAILURE IN DIH. WE CAN REPORT THIS
4848      * TO DIH THAT WAIT FOR THE OTHER BLOCKS TO BE CONCLUDED AS WELL.
4849      *-----------------------------------------------------------------------*/
4850     NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
4851     nf->blockNo      = DBDIH;
4852     nf->nodeId       = cownNodeId;
4853     nf->failedNodeId = failedNodePtr.i;
4854     nf->from         = __LINE__;
4855     sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
4856                NFCompleteRep::SignalLength, JBB);
4857   }//if
4858 }//Dbdih::failedNodeSynchHandling()
4859 
findTakeOver(Uint32 failedNodeId)4860 Uint32 Dbdih::findTakeOver(Uint32 failedNodeId)
4861 {
4862   for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
4863     jam();
4864     TakeOverRecordPtr takeOverPtr;
4865     takeOverPtr.i = i;
4866     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4867     if (takeOverPtr.p->toStartingNode == failedNodeId) {
4868       jam();
4869       return i;
4870     }//if
4871   }//for
4872   return RNIL;
4873 }//Dbdih::findTakeOver()
4874 
getStartNode(Uint32 takeOverPtrI)4875 Uint32 Dbdih::getStartNode(Uint32 takeOverPtrI)
4876 {
4877   TakeOverRecordPtr takeOverPtr;
4878   takeOverPtr.i = takeOverPtrI;
4879   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4880   return takeOverPtr.p->toStartingNode;
4881 }//Dbdih::getStartNode()
4882 
failedNodeLcpHandling(Signal * signal,NodeRecordPtr failedNodePtr)4883 void Dbdih::failedNodeLcpHandling(Signal* signal, NodeRecordPtr failedNodePtr)
4884 {
4885   jam();
4886   const Uint32 nodeId = failedNodePtr.i;
4887 
4888   if (isMaster() && c_lcpState.m_participatingLQH.get(failedNodePtr.i))
4889   {
4890     /*----------------------------------------------------*/
4891     /*  THE NODE WAS INVOLVED IN A LOCAL CHECKPOINT. WE   */
4892     /* MUST UPDATE THE ACTIVE STATUS TO INDICATE THAT     */
4893     /* THE NODE HAVE MISSED A LOCAL CHECKPOINT.           */
4894     /*----------------------------------------------------*/
4895 
4896     /**
4897      * Bug#28717, Only master should do this, as this status is copied
4898      *   to other nodes
4899      */
4900     switch (failedNodePtr.p->activeStatus) {
4901     case Sysfile::NS_Active:
4902       jam();
4903       failedNodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
4904       break;
4905     case Sysfile::NS_ActiveMissed_1:
4906       jam();
4907       failedNodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
4908       break;
4909     case Sysfile::NS_ActiveMissed_2:
4910       jam();
4911       failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
4912       break;
4913     case Sysfile::NS_TakeOver:
4914       jam();
4915       failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
4916       break;
4917     default:
4918       g_eventLogger.error("activeStatus = %u "
4919                           "at failure after NODE_FAILREP of node = %u",
4920                           (Uint32) failedNodePtr.p->activeStatus,
4921                           failedNodePtr.i);
4922       ndbrequire(false);
4923       break;
4924     }//switch
4925   }//if
4926 
4927   c_lcpState.m_participatingDIH.clear(failedNodePtr.i);
4928   c_lcpState.m_participatingLQH.clear(failedNodePtr.i);
4929 
4930   if(c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.isWaitingFor(failedNodePtr.i)){
4931     jam();
4932     LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
4933     rep->nodeId = failedNodePtr.i;
4934     rep->lcpId = SYSFILE->latestLCP_ID;
4935     rep->blockNo = DBDIH;
4936     sendSignal(reference(), GSN_LCP_COMPLETE_REP, signal,
4937 	       LcpCompleteRep::SignalLength, JBB);
4938   }
4939 
4940   /**
4941    * Check if we'r waiting for the failed node's LQH to complete
4942    *
4943    * Note that this is ran "before" LCP master take over
4944    */
4945   if(c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(nodeId)){
4946     jam();
4947 
4948     LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
4949     rep->nodeId  = nodeId;
4950     rep->lcpId   = SYSFILE->latestLCP_ID;
4951     rep->blockNo = DBLQH;
4952     sendSignal(reference(), GSN_LCP_COMPLETE_REP, signal,
4953 	       LcpCompleteRep::SignalLength, JBB);
4954 
4955     if(c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodeId)){
4956       jam();
4957       /**
4958        * Make sure we're ready to accept it
4959        */
4960       c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor(nodeId);
4961     }
4962   }
4963 
4964   if (c_TCGETOPSIZEREQ_Counter.isWaitingFor(failedNodePtr.i)) {
4965     jam();
4966     signal->theData[0] = failedNodePtr.i;
4967     signal->theData[1] = 0;
4968     sendSignal(reference(), GSN_TCGETOPSIZECONF, signal, 2, JBB);
4969   }//if
4970 
4971   if (c_TC_CLOPSIZEREQ_Counter.isWaitingFor(failedNodePtr.i)) {
4972     jam();
4973     signal->theData[0] = failedNodePtr.i;
4974     sendSignal(reference(), GSN_TC_CLOPSIZECONF, signal, 1, JBB);
4975   }//if
4976 
4977   if (c_START_LCP_REQ_Counter.isWaitingFor(failedNodePtr.i)) {
4978     jam();
4979     StartLcpConf * conf = (StartLcpConf*)signal->getDataPtrSend();
4980     conf->senderRef = numberToRef(DBLQH, failedNodePtr.i);
4981     conf->lcpId = SYSFILE->latestLCP_ID;
4982     sendSignal(reference(), GSN_START_LCP_CONF, signal,
4983 	       StartLcpConf::SignalLength, JBB);
4984   }//if
4985 
4986   if (c_EMPTY_LCP_REQ_Counter.isWaitingFor(failedNodePtr.i)) {
4987     jam();
4988     EmptyLcpConf * const rep = (EmptyLcpConf *)&signal->theData[0];
4989     rep->senderNodeId = failedNodePtr.i;
4990     rep->tableId = ~0;
4991     rep->fragmentId = ~0;
4992     rep->lcpNo = 0;
4993     rep->lcpId = SYSFILE->latestLCP_ID;
4994     rep->idle = true;
4995     sendSignal(reference(), GSN_EMPTY_LCP_CONF, signal,
4996 	       EmptyLcpConf::SignalLength, JBB);
4997   }//if
4998 
4999   if (c_MASTER_LCPREQ_Counter.isWaitingFor(failedNodePtr.i)) {
5000     jam();
5001     MasterLCPRef * const ref = (MasterLCPRef *)&signal->theData[0];
5002     ref->senderNodeId = failedNodePtr.i;
5003     ref->failedNodeId = cmasterTakeOverNode;
5004     sendSignal(reference(), GSN_MASTER_LCPREF, signal,
5005 	       MasterLCPRef::SignalLength, JBB);
5006   }//if
5007 
5008 }//Dbdih::failedNodeLcpHandling()
5009 
checkGcpOutstanding(Signal * signal,Uint32 failedNodeId)5010 void Dbdih::checkGcpOutstanding(Signal* signal, Uint32 failedNodeId){
5011   if (c_GCP_PREPARE_Counter.isWaitingFor(failedNodeId)){
5012     jam();
5013     signal->theData[0] = failedNodeId;
5014     signal->theData[1] = cnewgcp;
5015     sendSignal(reference(), GSN_GCP_PREPARECONF, signal, 2, JBB);
5016   }//if
5017 
5018   if (c_GCP_COMMIT_Counter.isWaitingFor(failedNodeId)) {
5019     jam();
5020     signal->theData[0] = failedNodeId;
5021     signal->theData[1] = coldgcp;
5022     signal->theData[2] = cfailurenr;
5023     sendSignal(reference(), GSN_GCP_NODEFINISH, signal, 3, JBB);
5024   }//if
5025 
5026   if (c_GCP_SAVEREQ_Counter.isWaitingFor(failedNodeId)) {
5027     jam();
5028     GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
5029     saveRef->dihPtr = failedNodeId;
5030     saveRef->nodeId = failedNodeId;
5031     saveRef->gci    = coldgcp;
5032     saveRef->errorCode = GCPSaveRef::FakedSignalDueToNodeFailure;
5033     sendSignal(reference(), GSN_GCP_SAVEREF, signal,
5034 	       GCPSaveRef::SignalLength, JBB);
5035   }//if
5036 
5037   if (c_COPY_GCIREQ_Counter.isWaitingFor(failedNodeId)) {
5038     jam();
5039     signal->theData[0] = failedNodeId;
5040     sendSignal(reference(), GSN_COPY_GCICONF, signal, 1, JBB);
5041   }//if
5042 
5043   if (c_MASTER_GCPREQ_Counter.isWaitingFor(failedNodeId)){
5044     jam();
5045     MasterGCPRef * const ref = (MasterGCPRef *)&signal->theData[0];
5046     ref->senderNodeId = failedNodeId;
5047     ref->failedNodeId = cmasterTakeOverNode;
5048     sendSignal(reference(), GSN_MASTER_GCPREF, signal,
5049 	       MasterGCPRef::SignalLength, JBB);
5050   }//if
5051 }//Dbdih::handleGcpStateInMaster()
5052 
5053 
5054 void
startLcpMasterTakeOver(Signal * signal,Uint32 nodeId)5055 Dbdih::startLcpMasterTakeOver(Signal* signal, Uint32 nodeId){
5056   jam();
5057 
5058   Uint32 oldNode = c_lcpMasterTakeOverState.failedNodeId;
5059 
5060   c_lcpMasterTakeOverState.minTableId = ~0;
5061   c_lcpMasterTakeOverState.minFragId = ~0;
5062   c_lcpMasterTakeOverState.failedNodeId = nodeId;
5063 
5064   c_lcpMasterTakeOverState.set(LMTOS_WAIT_EMPTY_LCP, __LINE__);
5065 
5066   if(c_EMPTY_LCP_REQ_Counter.done()){
5067     jam();
5068     c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor();
5069 
5070     EmptyLcpReq* req = (EmptyLcpReq*)signal->getDataPtrSend();
5071     req->senderRef = reference();
5072     sendLoopMacro(EMPTY_LCP_REQ, sendEMPTY_LCP_REQ);
5073     ndbrequire(!c_EMPTY_LCP_REQ_Counter.done());
5074   } else {
5075     /**
5076      * Node failure during master take over...
5077      */
5078     g_eventLogger.info("Nodefail during master take over (old: %d)", oldNode);
5079   }
5080 
5081   NodeRecordPtr nodePtr;
5082   nodePtr.i = oldNode;
5083   if (oldNode > 0 && oldNode < MAX_NDB_NODES)
5084   {
5085     jam();
5086     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5087     if (nodePtr.p->m_nodefailSteps.get(NF_LCP_TAKE_OVER))
5088     {
5089       jam();
5090       checkLocalNodefailComplete(signal, oldNode, NF_LCP_TAKE_OVER);
5091     }
5092   }
5093 
5094   setLocalNodefailHandling(signal, nodeId, NF_LCP_TAKE_OVER);
5095 }
5096 
startGcpMasterTakeOver(Signal * signal,Uint32 oldMasterId)5097 void Dbdih::startGcpMasterTakeOver(Signal* signal, Uint32 oldMasterId){
5098   jam();
5099   /*--------------------------------------------------*/
5100   /*                                                  */
5101   /*       THE MASTER HAVE FAILED AND WE WERE ELECTED */
5102   /*       TO BE THE NEW MASTER NODE. WE NEED TO QUERY*/
5103   /*       ALL THE OTHER NODES ABOUT THEIR STATUS IN  */
5104   /*       ORDER TO BE ABLE TO TAKE OVER CONTROL OF   */
5105   /*       THE GLOBAL CHECKPOINT PROTOCOL AND THE     */
5106   /*       LOCAL CHECKPOINT PROTOCOL.                 */
5107   /*--------------------------------------------------*/
5108   if(!isMaster()){
5109     jam();
5110     return;
5111   }
5112   cmasterState = MASTER_TAKE_OVER_GCP;
5113   cmasterTakeOverNode = oldMasterId;
5114   MasterGCPReq * const req = (MasterGCPReq *)&signal->theData[0];
5115   req->masterRef = reference();
5116   req->failedNodeId = oldMasterId;
5117   sendLoopMacro(MASTER_GCPREQ, sendMASTER_GCPREQ);
5118   cgcpMasterTakeOverState = GMTOS_INITIAL;
5119 
5120   signal->theData[0] = NDB_LE_GCP_TakeoverStarted;
5121   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
5122 
5123   setLocalNodefailHandling(signal, oldMasterId, NF_GCP_TAKE_OVER);
5124 }//Dbdih::handleNewMaster()
5125 
handleTakeOverNewMaster(Signal * signal,Uint32 takeOverPtrI)5126 void Dbdih::handleTakeOverNewMaster(Signal* signal, Uint32 takeOverPtrI)
5127 {
5128   jam();
5129   if (takeOverPtrI != RNIL) {
5130     jam();
5131     TakeOverRecordPtr takeOverPtr;
5132     takeOverPtr.i = takeOverPtrI;
5133     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
5134     bool ok = false;
5135     switch (takeOverPtr.p->toSlaveStatus) {
5136     case TakeOverRecord::TO_SLAVE_IDLE:
5137       ndbrequire(false);
5138       break;
5139     case TakeOverRecord::TO_SLAVE_STARTED:
5140       jam();
5141     case TakeOverRecord::TO_SLAVE_CREATE_PREPARE:
5142       jam();
5143     case TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED:
5144       jam();
5145     case TakeOverRecord::TO_SLAVE_CREATE_COMMIT:
5146       jam();
5147       ok = true;
5148       infoEvent("Unhandled MasterTO of TO slaveStatus=%d killing node %d",
5149 		takeOverPtr.p->toSlaveStatus,
5150 		takeOverPtr.p->toStartingNode);
5151       takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_ACTIVE;
5152 
5153       {
5154 	BlockReference cntrRef = calcNdbCntrBlockRef(takeOverPtr.p->toStartingNode);
5155 	SystemError * const sysErr = (SystemError*)&signal->theData[0];
5156 	sysErr->errorCode = SystemError::CopyFragRefError;
5157 	sysErr->errorRef = reference();
5158 	sysErr->data1= 0;
5159 	sysErr->data2= __LINE__;
5160 	sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
5161 		   SystemError::SignalLength, JBB);
5162       }
5163       break;
5164     case TakeOverRecord::TO_SLAVE_COPY_COMPLETED:
5165       ok = true;
5166       jam();
5167       takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
5168       break;
5169     }
5170     ndbrequire(ok);
5171     endTakeOver(takeOverPtr.i);
5172   }//if
5173 }//Dbdih::handleTakeOverNewMaster()
5174 
startRemoveFailedNode(Signal * signal,NodeRecordPtr failedNodePtr)5175 void Dbdih::startRemoveFailedNode(Signal* signal, NodeRecordPtr failedNodePtr)
5176 {
5177   Uint32 nodeId = failedNodePtr.i;
5178   if(failedNodePtr.p->nodeStatus != NodeRecord::DIED_NOW){
5179     jam();
5180     /**
5181      * Is node isn't alive. It can't be part of LCP
5182      */
5183     ndbrequire(!c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(nodeId));
5184 
5185     /**
5186      * And there is no point in removing any replicas
5187      *   It's dead...
5188      */
5189     return;
5190   }
5191 
5192   /**
5193    * If node has node complete LCP
5194    *   we need to remove it as undo might not be complete
5195    *   bug#31257
5196    */
5197   failedNodePtr.p->m_remove_node_from_table_lcp_id = RNIL;
5198   if (c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(failedNodePtr.i))
5199   {
5200     jam();
5201     failedNodePtr.p->m_remove_node_from_table_lcp_id = SYSFILE->latestLCP_ID;
5202   }
5203 
5204   jam();
5205 
5206   if (!ERROR_INSERTED(7194))
5207   {
5208     signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
5209     signal->theData[1] = failedNodePtr.i;
5210     signal->theData[2] = 0; // Tab id
5211     sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5212   }
5213   else
5214   {
5215     ndbout_c("7194 Not starting ZREMOVE_NODE_FROM_TABLE");
5216   }
5217 
5218   setLocalNodefailHandling(signal, failedNodePtr.i, NF_REMOVE_NODE_FROM_TABLE);
5219 }//Dbdih::startRemoveFailedNode()
5220 
5221 /*--------------------------------------------------*/
5222 /*       THE MASTER HAS FAILED AND THE NEW MASTER IS*/
5223 /*       QUERYING THIS NODE ABOUT THE STATE OF THE  */
5224 /*       GLOBAL CHECKPOINT PROTOCOL                 */
5225 /*--------------------------------------------------*/
execMASTER_GCPREQ(Signal * signal)5226 void Dbdih::execMASTER_GCPREQ(Signal* signal)
5227 {
5228   NodeRecordPtr failedNodePtr;
5229   MasterGCPReq * const masterGCPReq = (MasterGCPReq *)&signal->theData[0];
5230   jamEntry();
5231   const BlockReference newMasterBlockref = masterGCPReq->masterRef;
5232   const Uint32 failedNodeId = masterGCPReq->failedNodeId;
5233   if (c_copyGCISlave.m_copyReason != CopyGCIReq::IDLE) {
5234     jam();
5235     /*--------------------------------------------------*/
5236     /*       WE ARE CURRENTLY WRITING THE RESTART INFO  */
5237     /*       IN THIS NODE. SINCE ONLY ONE PROCESS IS    */
5238     /*       ALLOWED TO DO THIS AT A TIME WE MUST ENSURE*/
5239     /*       THAT THIS IS NOT ONGOING WHEN THE NEW      */
5240     /*       MASTER TAKES OVER CONTROL. IF NOT ALL NODES*/
5241     /*       RECEIVE THE SAME RESTART INFO DUE TO THE   */
5242     /*       FAILURE OF THE MASTER IT IS TAKEN CARE OF  */
5243     /*       BY THE NEW MASTER.                         */
5244     /*--------------------------------------------------*/
5245     sendSignalWithDelay(reference(), GSN_MASTER_GCPREQ,
5246                         signal, 10, MasterGCPReq::SignalLength);
5247     return;
5248   }//if
5249   failedNodePtr.i = failedNodeId;
5250   ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
5251   if (failedNodePtr.p->nodeStatus == NodeRecord::ALIVE) {
5252     jam();
5253     /*--------------------------------------------------*/
5254     /*       ENSURE THAT WE HAVE PROCESSED THE SIGNAL   */
5255     /*       NODE_FAILURE BEFORE WE PROCESS THIS REQUEST*/
5256     /*       FROM THE NEW MASTER. THIS ENSURES THAT WE  */
5257     /*       HAVE REMOVED THE FAILED NODE FROM THE LIST */
5258     /*       OF ACTIVE NODES AND SO FORTH.              */
5259     /*--------------------------------------------------*/
5260     sendSignalWithDelay(reference(), GSN_MASTER_GCPREQ,
5261                         signal, 10, MasterGCPReq::SignalLength);
5262     return;
5263   } else {
5264     ndbrequire(failedNodePtr.p->nodeStatus == NodeRecord::DYING);
5265   }//if
5266 
5267   if (ERROR_INSERTED(7181))
5268   {
5269     ndbout_c("execGCP_TCFINISHED in MASTER_GCPREQ");
5270     CLEAR_ERROR_INSERT_VALUE;
5271     signal->theData[0] = c_error_7181_ref;
5272     signal->theData[1] = coldgcp;
5273     execGCP_TCFINISHED(signal);
5274   }
5275 
5276   MasterGCPConf::State gcpState;
5277   switch (cgcpParticipantState) {
5278   case GCP_PARTICIPANT_READY:
5279     jam();
5280     /*--------------------------------------------------*/
5281     /*       THE GLOBAL CHECKPOINT IS NOT ACTIVE SINCE  */
5282     /*       THE PREVIOUS GLOBAL CHECKPOINT IS COMPLETED*/
5283     /*       AND THE NEW HAVE NOT STARTED YET.          */
5284     /*--------------------------------------------------*/
5285     gcpState = MasterGCPConf::GCP_READY;
5286     break;
5287   case GCP_PARTICIPANT_PREPARE_RECEIVED:
5288     jam();
5289     /*--------------------------------------------------*/
5290     /*       GCP_PREPARE HAVE BEEN RECEIVED AND RESPONSE*/
5291     /*       HAVE BEEN SENT.                            */
5292     /*--------------------------------------------------*/
5293     gcpState = MasterGCPConf::GCP_PREPARE_RECEIVED;
5294     break;
5295   case GCP_PARTICIPANT_COMMIT_RECEIVED:
5296     jam();
5297     /*------------------------------------------------*/
5298     /*       GCP_COMMIT HAVE BEEN RECEIVED BUT NOT YET*/
5299     /*       GCP_TCFINISHED FROM LOCAL TC.            */
5300     /*------------------------------------------------*/
5301     gcpState = MasterGCPConf::GCP_COMMIT_RECEIVED;
5302     break;
5303   case GCP_PARTICIPANT_TC_FINISHED:
5304     jam();
5305     /*------------------------------------------------*/
5306     /*       GCP_COMMIT HAS BEEN RECEIVED AND ALSO    */
5307     /*       GCP_TCFINISHED HAVE BEEN RECEIVED.       */
5308     /*------------------------------------------------*/
5309     gcpState = MasterGCPConf::GCP_TC_FINISHED;
5310     break;
5311   case GCP_PARTICIPANT_COPY_GCI_RECEIVED:
5312     /*--------------------------------------------------*/
5313     /*       COPY RESTART INFORMATION HAS BEEN RECEIVED */
5314     /*       BUT NOT YET COMPLETED.                     */
5315     /*--------------------------------------------------*/
5316     ndbrequire(false);
5317     gcpState= MasterGCPConf::GCP_READY; // remove warning
5318     break;
5319   default:
5320     /*------------------------------------------------*/
5321     /*                                                */
5322     /*       THIS SHOULD NOT OCCUR SINCE THE ABOVE    */
5323     /*       STATES ARE THE ONLY POSSIBLE STATES AT A */
5324     /*       NODE WHICH WAS NOT A MASTER NODE.        */
5325     /*------------------------------------------------*/
5326     ndbrequire(false);
5327     gcpState= MasterGCPConf::GCP_READY; // remove warning
5328     break;
5329   }//switch
5330   MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0];
5331   masterGCPConf->gcpState  = gcpState;
5332   masterGCPConf->senderNodeId = cownNodeId;
5333   masterGCPConf->failedNodeId = failedNodeId;
5334   masterGCPConf->newGCP = cnewgcp;
5335   masterGCPConf->latestLCP = SYSFILE->latestLCP_ID;
5336   masterGCPConf->oldestRestorableGCI = SYSFILE->oldestRestorableGCI;
5337   masterGCPConf->keepGCI = SYSFILE->keepGCI;
5338   for(Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
5339     masterGCPConf->lcpActive[i] = SYSFILE->lcpActive[i];
5340   sendSignal(newMasterBlockref, GSN_MASTER_GCPCONF, signal,
5341              MasterGCPConf::SignalLength, JBB);
5342 
5343   if (ERROR_INSERTED(7182))
5344   {
5345     ndbout_c("execGCP_TCFINISHED in MASTER_GCPREQ");
5346     CLEAR_ERROR_INSERT_VALUE;
5347     signal->theData[0] = c_error_7181_ref;
5348     signal->theData[1] = coldgcp;
5349     execGCP_TCFINISHED(signal);
5350   }
5351 }//Dbdih::execMASTER_GCPREQ()
5352 
execMASTER_GCPCONF(Signal * signal)5353 void Dbdih::execMASTER_GCPCONF(Signal* signal)
5354 {
5355   NodeRecordPtr senderNodePtr;
5356   MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0];
5357   jamEntry();
5358   senderNodePtr.i = masterGCPConf->senderNodeId;
5359   ptrCheckGuard(senderNodePtr, MAX_NDB_NODES, nodeRecord);
5360 
5361   MasterGCPConf::State gcpState = (MasterGCPConf::State)masterGCPConf->gcpState;
5362   const Uint32 failedNodeId = masterGCPConf->failedNodeId;
5363   const Uint32 newGcp = masterGCPConf->newGCP;
5364   const Uint32 latestLcpId = masterGCPConf->latestLCP;
5365   const Uint32 oldestRestorableGci = masterGCPConf->oldestRestorableGCI;
5366   const Uint32 oldestKeepGci = masterGCPConf->keepGCI;
5367   if (latestLcpId > SYSFILE->latestLCP_ID) {
5368     jam();
5369 #if 0
5370     g_eventLogger.info("Dbdih: Setting SYSFILE->latestLCP_ID to %d",
5371                        latestLcpId);
5372     SYSFILE->latestLCP_ID = latestLcpId;
5373 #endif
5374     SYSFILE->keepGCI = oldestKeepGci;
5375     SYSFILE->oldestRestorableGCI = oldestRestorableGci;
5376     for(Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
5377       SYSFILE->lcpActive[i] = masterGCPConf->lcpActive[i];
5378   }//if
5379   switch (gcpState) {
5380   case MasterGCPConf::GCP_READY:
5381     jam();
5382     senderNodePtr.p->gcpstate = NodeRecord::READY;
5383     break;
5384   case MasterGCPConf::GCP_PREPARE_RECEIVED:
5385     jam();
5386     senderNodePtr.p->gcpstate = NodeRecord::PREPARE_RECEIVED;
5387     cnewgcp = newGcp;
5388     break;
5389   case MasterGCPConf::GCP_COMMIT_RECEIVED:
5390     jam();
5391     senderNodePtr.p->gcpstate = NodeRecord::COMMIT_SENT;
5392     break;
5393   case MasterGCPConf::GCP_TC_FINISHED:
5394     jam();
5395     senderNodePtr.p->gcpstate = NodeRecord::NODE_FINISHED;
5396     break;
5397   default:
5398     ndbrequire(false);
5399     break;
5400   }//switch
5401   switch (cgcpMasterTakeOverState) {
5402   case GMTOS_INITIAL:
5403     switch (gcpState) {
5404     case MasterGCPConf::GCP_READY:
5405       jam();
5406       cgcpMasterTakeOverState = ALL_READY;
5407       break;
5408     case MasterGCPConf::GCP_PREPARE_RECEIVED:
5409       jam();
5410       cgcpMasterTakeOverState = ALL_PREPARED;
5411       break;
5412     case MasterGCPConf::GCP_COMMIT_RECEIVED:
5413       jam();
5414       cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
5415       break;
5416     case MasterGCPConf::GCP_TC_FINISHED:
5417       jam();
5418       cgcpMasterTakeOverState = COMMIT_COMPLETED;
5419       break;
5420     default:
5421       ndbrequire(false);
5422       break;
5423     }//switch
5424     break;
5425   case ALL_READY:
5426     switch (gcpState) {
5427     case MasterGCPConf::GCP_READY:
5428       jam();
5429       /*empty*/;
5430       break;
5431     case MasterGCPConf::GCP_PREPARE_RECEIVED:
5432       jam();
5433       cgcpMasterTakeOverState = PREPARE_STARTED_NOT_COMMITTED;
5434       break;
5435     case MasterGCPConf::GCP_COMMIT_RECEIVED:
5436       ndbrequire(false);
5437       break;
5438     case MasterGCPConf::GCP_TC_FINISHED:
5439       jam();
5440       cgcpMasterTakeOverState = SAVE_STARTED_NOT_COMPLETED;
5441       break;
5442     default:
5443       ndbrequire(false);
5444       break;
5445     }//switch
5446     break;
5447   case PREPARE_STARTED_NOT_COMMITTED:
5448     switch (gcpState) {
5449     case MasterGCPConf::GCP_READY:
5450       jam();
5451       break;
5452     case MasterGCPConf::GCP_PREPARE_RECEIVED:
5453       jam();
5454       break;
5455     case MasterGCPConf::GCP_COMMIT_RECEIVED:
5456       ndbrequire(false);
5457       break;
5458     case MasterGCPConf::GCP_TC_FINISHED:
5459       ndbrequire(false);
5460       break;
5461     default:
5462       ndbrequire(false);
5463       break;
5464     }//switch
5465     break;
5466   case ALL_PREPARED:
5467     switch (gcpState) {
5468     case MasterGCPConf::GCP_READY:
5469       jam();
5470       cgcpMasterTakeOverState = PREPARE_STARTED_NOT_COMMITTED;
5471       break;
5472     case MasterGCPConf::GCP_PREPARE_RECEIVED:
5473       jam();
5474       break;
5475     case MasterGCPConf::GCP_COMMIT_RECEIVED:
5476       jam();
5477       cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
5478       break;
5479     case MasterGCPConf::GCP_TC_FINISHED:
5480       jam();
5481       cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
5482       break;
5483     default:
5484       ndbrequire(false);
5485       break;
5486     }//switch
5487     break;
5488   case COMMIT_STARTED_NOT_COMPLETED:
5489     switch (gcpState) {
5490     case MasterGCPConf::GCP_READY:
5491       ndbrequire(false);
5492       break;
5493     case MasterGCPConf::GCP_PREPARE_RECEIVED:
5494       jam();
5495       break;
5496     case MasterGCPConf::GCP_COMMIT_RECEIVED:
5497       jam();
5498       break;
5499     case MasterGCPConf::GCP_TC_FINISHED:
5500       jam();
5501       break;
5502     default:
5503       ndbrequire(false);
5504       break;
5505     }//switch
5506     break;
5507   case COMMIT_COMPLETED:
5508     switch (gcpState) {
5509     case MasterGCPConf::GCP_READY:
5510       cgcpMasterTakeOverState = SAVE_STARTED_NOT_COMPLETED;
5511       break;
5512     case MasterGCPConf::GCP_PREPARE_RECEIVED:
5513       jam();
5514       cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
5515       break;
5516     case MasterGCPConf::GCP_COMMIT_RECEIVED:
5517       jam();
5518       cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
5519       break;
5520     case MasterGCPConf::GCP_TC_FINISHED:
5521       jam();
5522       break;
5523     default:
5524       ndbrequire(false);
5525       break;
5526     }//switch
5527     break;
5528   case SAVE_STARTED_NOT_COMPLETED:
5529     switch (gcpState) {
5530     case MasterGCPConf::GCP_READY:
5531       jam();
5532       break;
5533     case MasterGCPConf::GCP_PREPARE_RECEIVED:
5534       ndbrequire(false);
5535       break;
5536     case MasterGCPConf::GCP_COMMIT_RECEIVED:
5537       ndbrequire(false);
5538       break;
5539     case MasterGCPConf::GCP_TC_FINISHED:
5540       jam();
5541       break;
5542     default:
5543       ndbrequire(false);
5544       break;
5545     }//switch
5546     break;
5547   default:
5548     ndbrequire(false);
5549     break;
5550   }//switch
5551   receiveLoopMacro(MASTER_GCPREQ, senderNodePtr.i);
5552   /*-------------------------------------------------------------------------*/
5553   // We have now received all responses and are ready to take over the GCP
5554   // protocol as master.
5555   /*-------------------------------------------------------------------------*/
5556   MASTER_GCPhandling(signal, failedNodeId);
5557   return;
5558 }//Dbdih::execMASTER_GCPCONF()
5559 
execMASTER_GCPREF(Signal * signal)5560 void Dbdih::execMASTER_GCPREF(Signal* signal)
5561 {
5562   const MasterGCPRef * const ref = (MasterGCPRef *)&signal->theData[0];
5563   jamEntry();
5564   receiveLoopMacro(MASTER_GCPREQ, ref->senderNodeId);
5565   /*-------------------------------------------------------------------------*/
5566   // We have now received all responses and are ready to take over the GCP
5567   // protocol as master.
5568   /*-------------------------------------------------------------------------*/
5569   MASTER_GCPhandling(signal, ref->failedNodeId);
5570 }//Dbdih::execMASTER_GCPREF()
5571 
MASTER_GCPhandling(Signal * signal,Uint32 failedNodeId)5572 void Dbdih::MASTER_GCPhandling(Signal* signal, Uint32 failedNodeId)
5573 {
5574   NodeRecordPtr failedNodePtr;
5575   cmasterState = MASTER_ACTIVE;
5576   /*----------------------------------------------------------*/
5577   /*       REMOVE ALL ACTIVE STATUS ON ALREADY FAILED NODES   */
5578   /*       THIS IS PERFORMED HERE SINCE WE GET THE LCP ACTIVE */
5579   /*       STATUS AS PART OF THE COPY RESTART INFO AND THIS IS*/
5580   /*       HANDLED BY THE MASTER GCP TAKE OVER PROTOCOL.      */
5581   /*----------------------------------------------------------*/
5582 
5583   failedNodePtr.i = failedNodeId;
5584   ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
5585   switch (cgcpMasterTakeOverState) {
5586   case ALL_READY:
5587     jam();
5588     startGcp(signal);
5589     break;
5590   case PREPARE_STARTED_NOT_COMMITTED:
5591     {
5592       NodeRecordPtr nodePtr;
5593       jam();
5594       c_GCP_PREPARE_Counter.clearWaitingFor();
5595       nodePtr.i = cfirstAliveNode;
5596       do {
5597 	jam();
5598 	ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5599 	if (nodePtr.p->gcpstate == NodeRecord::READY) {
5600 	  jam();
5601 	  c_GCP_PREPARE_Counter.setWaitingFor(nodePtr.i);
5602 	  sendGCP_PREPARE(signal, nodePtr.i);
5603 	}//if
5604 	nodePtr.i = nodePtr.p->nextNode;
5605       } while(nodePtr.i != RNIL);
5606       if (c_GCP_PREPARE_Counter.done()) {
5607 	jam();
5608 	gcpcommitreqLab(signal);
5609       }//if
5610       break;
5611     }
5612   case ALL_PREPARED:
5613     jam();
5614     gcpcommitreqLab(signal);
5615     break;
5616   case COMMIT_STARTED_NOT_COMPLETED:
5617     {
5618       NodeRecordPtr nodePtr;
5619       jam();
5620       c_GCP_COMMIT_Counter.clearWaitingFor();
5621       nodePtr.i = cfirstAliveNode;
5622       do {
5623 	jam();
5624 	ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5625 	if (nodePtr.p->gcpstate == NodeRecord::PREPARE_RECEIVED) {
5626 	  jam();
5627 	  sendGCP_COMMIT(signal, nodePtr.i);
5628 	  c_GCP_COMMIT_Counter.setWaitingFor(nodePtr.i);
5629 	} else {
5630 	  ndbrequire((nodePtr.p->gcpstate == NodeRecord::NODE_FINISHED) ||
5631 		     (nodePtr.p->gcpstate == NodeRecord::COMMIT_SENT));
5632 	}//if
5633 	nodePtr.i = nodePtr.p->nextNode;
5634       } while(nodePtr.i != RNIL);
5635       if (c_GCP_COMMIT_Counter.done()){
5636 	jam();
5637 	gcpsavereqLab(signal);
5638       }//if
5639       break;
5640     }
5641   case COMMIT_COMPLETED:
5642     jam();
5643     gcpsavereqLab(signal);
5644     break;
5645   case SAVE_STARTED_NOT_COMPLETED:
5646     {
5647       NodeRecordPtr nodePtr;
5648       jam();
5649       SYSFILE->newestRestorableGCI = coldgcp;
5650       nodePtr.i = cfirstAliveNode;
5651       do {
5652 	jam();
5653 	ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5654 	SYSFILE->lastCompletedGCI[nodePtr.i] = coldgcp;
5655 	nodePtr.i = nodePtr.p->nextNode;
5656       } while (nodePtr.i != RNIL);
5657       /**-------------------------------------------------------------------
5658        * THE FAILED NODE DID ALSO PARTICIPATE IN THIS GLOBAL CHECKPOINT
5659        * WHICH IS RECORDED.
5660        *-------------------------------------------------------------------*/
5661       SYSFILE->lastCompletedGCI[failedNodeId] = coldgcp;
5662       copyGciLab(signal, CopyGCIReq::GLOBAL_CHECKPOINT);
5663       break;
5664     }
5665   default:
5666     ndbrequire(false);
5667     break;
5668   }//switch
5669 
5670   signal->theData[0] = NDB_LE_GCP_TakeoverCompleted;
5671   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
5672 
5673   /*--------------------------------------------------*/
5674   /*       WE SEPARATE HANDLING OF GLOBAL CHECKPOINTS */
5675   /*       AND LOCAL CHECKPOINTS HERE. LCP'S HAVE TO  */
5676   /*       REMOVE ALL FAILED FRAGMENTS BEFORE WE CAN  */
5677   /*       HANDLE THE LCP PROTOCOL.                   */
5678   /*--------------------------------------------------*/
5679   checkLocalNodefailComplete(signal, failedNodeId, NF_GCP_TAKE_OVER);
5680 
5681   return;
5682 }//Dbdih::masterGcpConfFromFailedLab()
5683 
5684 void
invalidateNodeLCP(Signal * signal,Uint32 nodeId,Uint32 tableId)5685 Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, Uint32 tableId)
5686 {
5687   jamEntry();
5688   TabRecordPtr tabPtr;
5689   tabPtr.i = tableId;
5690   const Uint32 RT_BREAK = 64;
5691   if (ERROR_INSERTED(7125)) {
5692     return;
5693   }//if
5694   for (Uint32 i = 0; i<RT_BREAK; i++) {
5695     jam();
5696     if (tabPtr.i >= ctabFileSize){
5697       jam();
5698       /**
5699        * Ready with entire loop
5700        * Return to master
5701        */
5702       setAllowNodeStart(nodeId, true);
5703       if (getNodeStatus(nodeId) == NodeRecord::STARTING) {
5704         jam();
5705         StartInfoConf * conf = (StartInfoConf*)&signal->theData[0];
5706         conf->sendingNodeId = cownNodeId;
5707         conf->startingNodeId = nodeId;
5708         sendSignal(cmasterdihref, GSN_START_INFOCONF, signal,
5709                    StartInfoConf::SignalLength, JBB);
5710       }//if
5711       return;
5712     }//if
5713     ptrAss(tabPtr, tabRecord);
5714     if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
5715       jam();
5716       invalidateNodeLCP(signal, nodeId, tabPtr);
5717       return;
5718     }//if
5719     tabPtr.i++;
5720   }//for
5721   signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
5722   signal->theData[1] = nodeId;
5723   signal->theData[2] = tabPtr.i;
5724   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5725 }//Dbdih::invalidateNodeLCP()
5726 
5727 void
invalidateNodeLCP(Signal * signal,Uint32 nodeId,TabRecordPtr tabPtr)5728 Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, TabRecordPtr tabPtr)
5729 {
5730   /**
5731    * Check so that no one else is using the tab descriptior
5732    */
5733   if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
5734     jam();
5735     signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
5736     signal->theData[1] = nodeId;
5737     signal->theData[2] = tabPtr.i;
5738     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
5739     return;
5740   }//if
5741 
5742   /**
5743    * For each fragment
5744    */
5745   bool modified = false;
5746   FragmentstorePtr fragPtr;
5747   for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
5748     jam();
5749     getFragstore(tabPtr.p, fragNo, fragPtr);
5750     /**
5751      * For each of replica record
5752      */
5753     ReplicaRecordPtr replicaPtr;
5754     for(replicaPtr.i = fragPtr.p->oldStoredReplicas; replicaPtr.i != RNIL;
5755         replicaPtr.i = replicaPtr.p->nextReplica) {
5756       jam();
5757       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
5758       if(replicaPtr.p->procNode == nodeId){
5759         jam();
5760         /**
5761          * Found one with correct node id
5762          */
5763         /**
5764          * Invalidate all LCP's
5765          */
5766         modified = true;
5767         for(int i = 0; i < MAX_LCP_STORED; i++) {
5768           replicaPtr.p->lcpStatus[i] = ZINVALID;
5769         }//if
5770         /**
5771          * And reset nextLcp
5772          */
5773         replicaPtr.p->nextLcp = 0;
5774         replicaPtr.p->noCrashedReplicas = 0;
5775       }//if
5776     }//for
5777   }//for
5778 
5779   if (modified) {
5780     jam();
5781     /**
5782      * Save table description to disk
5783      */
5784     tabPtr.p->tabCopyStatus  = TabRecord::CS_INVALIDATE_NODE_LCP;
5785     tabPtr.p->tabUpdateState = TabRecord::US_INVALIDATE_NODE_LCP;
5786     tabPtr.p->tabRemoveNode  = nodeId;
5787     signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
5788     signal->theData[1] = tabPtr.i;
5789     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
5790     return;
5791   }
5792 
5793   jam();
5794   /**
5795    * Move to next table
5796    */
5797   tabPtr.i++;
5798   signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
5799   signal->theData[1] = nodeId;
5800   signal->theData[2] = tabPtr.i;
5801   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5802   return;
5803 }//Dbdih::invalidateNodeLCP()
5804 
5805 /*------------------------------------------------*/
5806 /*       INPUT:  TABPTR                           */
5807 /*               TNODEID                          */
5808 /*------------------------------------------------*/
removeNodeFromTables(Signal * signal,Uint32 nodeId,Uint32 tableId)5809 void Dbdih::removeNodeFromTables(Signal* signal,
5810 				 Uint32 nodeId, Uint32 tableId)
5811 {
5812   jamEntry();
5813   TabRecordPtr tabPtr;
5814   tabPtr.i = tableId;
5815   const Uint32 RT_BREAK = 64;
5816   for (Uint32 i = 0; i<RT_BREAK; i++) {
5817     jam();
5818     if (tabPtr.i >= ctabFileSize){
5819       jam();
5820       removeNodeFromTablesComplete(signal, nodeId);
5821       return;
5822     }//if
5823 
5824     ptrAss(tabPtr, tabRecord);
5825     if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
5826       jam();
5827       removeNodeFromTable(signal, nodeId, tabPtr);
5828       return;
5829     }//if
5830     tabPtr.i++;
5831   }//for
5832   signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
5833   signal->theData[1] = nodeId;
5834   signal->theData[2] = tabPtr.i;
5835   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5836 }
5837 
removeNodeFromTable(Signal * signal,Uint32 nodeId,TabRecordPtr tabPtr)5838 void Dbdih::removeNodeFromTable(Signal* signal,
5839 				Uint32 nodeId, TabRecordPtr tabPtr){
5840 
5841   /**
5842    * Check so that no one else is using the tab descriptior
5843    */
5844   if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
5845     jam();
5846     signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
5847     signal->theData[1] = nodeId;
5848     signal->theData[2] = tabPtr.i;
5849     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
5850     return;
5851   }//if
5852 
5853   NodeRecordPtr nodePtr;
5854   nodePtr.i = nodeId;
5855   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5856   const Uint32 lcpId = nodePtr.p->m_remove_node_from_table_lcp_id;
5857 
5858   /**
5859    * For each fragment
5860    */
5861   Uint32 noOfRemovedReplicas = 0;     // No of replicas removed
5862   Uint32 noOfRemovedLcpReplicas = 0;  // No of replicas in LCP removed
5863   Uint32 noOfRemainingLcpReplicas = 0;// No of replicas in LCP remaining
5864 
5865   const bool lcpOngoingFlag = (tabPtr.p->tabLcpStatus== TabRecord::TLS_ACTIVE);
5866   const bool unlogged = (tabPtr.p->tabStorage != TabRecord::ST_NORMAL);
5867 
5868   FragmentstorePtr fragPtr;
5869   for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
5870     jam();
5871     getFragstore(tabPtr.p, fragNo, fragPtr);
5872 
5873     /**
5874      * For each of replica record
5875      */
5876     bool found = false;
5877     ReplicaRecordPtr replicaPtr;
5878     for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL;
5879         replicaPtr.i = replicaPtr.p->nextReplica) {
5880       jam();
5881 
5882       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
5883       if(replicaPtr.p->procNode == nodeId){
5884         jam();
5885 	found = true;
5886 	noOfRemovedReplicas++;
5887 	removeNodeFromStored(nodeId, fragPtr, replicaPtr, unlogged);
5888 	if(replicaPtr.p->lcpOngoingFlag){
5889 	  jam();
5890 	  /**
5891 	   * This replica is currently LCP:ed
5892 	   */
5893 	  ndbrequire(fragPtr.p->noLcpReplicas > 0);
5894 	  fragPtr.p->noLcpReplicas --;
5895 
5896 	  noOfRemovedLcpReplicas ++;
5897 	  replicaPtr.p->lcpOngoingFlag = false;
5898 	}
5899 
5900         if (lcpId != RNIL)
5901         {
5902           jam();
5903           Uint32 lcpNo = prevLcpNo(replicaPtr.p->nextLcp);
5904           if (replicaPtr.p->lcpStatus[lcpNo] == ZVALID &&
5905               replicaPtr.p->lcpId[lcpNo] == SYSFILE->latestLCP_ID)
5906           {
5907             jam();
5908             replicaPtr.p->lcpStatus[lcpNo] = ZINVALID;
5909             replicaPtr.p->lcpId[lcpNo] = 0;
5910             replicaPtr.p->nextLcp = lcpNo;
5911             ndbout_c("REMOVING lcp: %u from table: %u frag: %u node: %u",
5912                      SYSFILE->latestLCP_ID,
5913                      tabPtr.i, fragNo, nodeId);
5914           }
5915         }
5916       }
5917     }
5918     if (!found)
5919     {
5920       jam();
5921       /**
5922        * Run updateNodeInfo to remove any dead nodes from list of activeNodes
5923        *  see bug#15587
5924        */
5925       updateNodeInfo(fragPtr);
5926     }
5927     noOfRemainingLcpReplicas += fragPtr.p->noLcpReplicas;
5928   }
5929 
5930   if(noOfRemovedReplicas == 0){
5931     jam();
5932     /**
5933      * The table had no replica on the failed node
5934      *   continue with next table
5935      */
5936     tabPtr.i++;
5937     signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
5938     signal->theData[1] = nodeId;
5939     signal->theData[2] = tabPtr.i;
5940     sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5941     return;
5942   }
5943 
5944   /**
5945    * We did remove at least one replica
5946    */
5947   bool ok = false;
5948   switch(tabPtr.p->tabLcpStatus){
5949   case TabRecord::TLS_COMPLETED:
5950     ok = true;
5951     jam();
5952     /**
5953      * WE WILL WRITE THE TABLE DESCRIPTION TO DISK AT THIS TIME
5954      * INDEPENDENT OF WHAT THE LOCAL CHECKPOINT NEEDED.
5955      * THIS IS TO ENSURE THAT THE FAILED NODES ARE ALSO UPDATED ON DISK
5956      * IN THE DIH DATA STRUCTURES BEFORE WE COMPLETE HANDLING OF THE
5957      * NODE FAILURE.
5958      */
5959     ndbrequire(noOfRemovedLcpReplicas == 0);
5960 
5961     tabPtr.p->tabCopyStatus = TabRecord::CS_REMOVE_NODE;
5962     tabPtr.p->tabUpdateState = TabRecord::US_REMOVE_NODE;
5963     tabPtr.p->tabRemoveNode = nodeId;
5964     signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
5965     signal->theData[1] = tabPtr.i;
5966     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
5967     return;
5968     break;
5969   case TabRecord::TLS_ACTIVE:
5970     ok = true;
5971     jam();
5972     /**
5973      * The table is participating in an LCP currently
5974      */
5975     // Fall through
5976     break;
5977   case TabRecord::TLS_WRITING_TO_FILE:
5978     ok = true;
5979     jam();
5980     /**
5981      * This should never happen since we in the beginning of this function
5982      * checks the tabCopyStatus
5983      */
5984     ndbrequire(lcpOngoingFlag);
5985     ndbrequire(false);
5986     break;
5987   }
5988   ndbrequire(ok);
5989 
5990   /**
5991    * The table is participating in an LCP currently
5992    *   and we removed some replicas that should have been checkpointed
5993    */
5994   ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
5995   ndbrequire(tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE);
5996 
5997   /**
5998    * Save the table
5999    */
6000   tabPtr.p->tabCopyStatus = TabRecord::CS_REMOVE_NODE;
6001   tabPtr.p->tabUpdateState = TabRecord::US_REMOVE_NODE;
6002   tabPtr.p->tabRemoveNode = nodeId;
6003   signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
6004   signal->theData[1] = tabPtr.i;
6005   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
6006 
6007   if(noOfRemainingLcpReplicas == 0){
6008     jam();
6009     /**
6010      * The removal on the failed node made the LCP complete
6011      */
6012     tabPtr.p->tabLcpStatus = TabRecord::TLS_WRITING_TO_FILE;
6013     checkLcpAllTablesDoneInLqh();
6014   }
6015 }
6016 
6017 void
removeNodeFromTablesComplete(Signal * signal,Uint32 nodeId)6018 Dbdih::removeNodeFromTablesComplete(Signal* signal, Uint32 nodeId){
6019   jam();
6020 
6021   /**
6022    * Check if we "accidently" completed a LCP
6023    */
6024   checkLcpCompletedLab(signal);
6025 
6026   /**
6027    * Check if we (DIH) are finished with node fail handling
6028    */
6029   checkLocalNodefailComplete(signal, nodeId, NF_REMOVE_NODE_FROM_TABLE);
6030 }
6031 
6032 void
checkLocalNodefailComplete(Signal * signal,Uint32 failedNodeId,NodefailHandlingStep step)6033 Dbdih::checkLocalNodefailComplete(Signal* signal, Uint32 failedNodeId,
6034 				  NodefailHandlingStep step){
6035   jam();
6036 
6037   NodeRecordPtr nodePtr;
6038   nodePtr.i = failedNodeId;
6039   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
6040 
6041   ndbrequire(nodePtr.p->m_nodefailSteps.get(step));
6042   nodePtr.p->m_nodefailSteps.clear(step);
6043 
6044   if(nodePtr.p->m_nodefailSteps.count() > 0){
6045     jam();
6046     return;
6047   }
6048 
6049   if (ERROR_INSERTED(7030))
6050   {
6051     g_eventLogger.info("Reenable GCP_PREPARE");
6052     CLEAR_ERROR_INSERT_VALUE;
6053   }
6054 
6055   NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
6056   nf->blockNo = DBDIH;
6057   nf->nodeId = cownNodeId;
6058   nf->failedNodeId = failedNodeId;
6059   nf->from = __LINE__;
6060   sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
6061              NFCompleteRep::SignalLength, JBB);
6062 }
6063 
6064 
6065 void
setLocalNodefailHandling(Signal * signal,Uint32 failedNodeId,NodefailHandlingStep step)6066 Dbdih::setLocalNodefailHandling(Signal* signal, Uint32 failedNodeId,
6067 				NodefailHandlingStep step){
6068   jam();
6069 
6070   NodeRecordPtr nodePtr;
6071   nodePtr.i = failedNodeId;
6072   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
6073 
6074   ndbrequire(!nodePtr.p->m_nodefailSteps.get(step));
6075   nodePtr.p->m_nodefailSteps.set(step);
6076 }
6077 
startLcpTakeOverLab(Signal * signal,Uint32 failedNodeId)6078 void Dbdih::startLcpTakeOverLab(Signal* signal, Uint32 failedNodeId)
6079 {
6080   /*--------------------------------------------------------------------*/
6081   // Start LCP master take over process. Consists of the following steps.
6082   // 1) Ensure that all LQH's have reported all fragments they have been
6083   // told to checkpoint. Can be a fairly long step time-wise.
6084   // 2) Query all nodes about their LCP status.
6085   // During the query process we do not want our own state to change.
6086   // This can change due to delayed reception of LCP_REPORT, completed
6087   // save of table on disk or reception of DIH_LCPCOMPLETE from other
6088   // node.
6089   /*--------------------------------------------------------------------*/
6090 }//Dbdih::startLcpTakeOver()
6091 
execEMPTY_LCP_CONF(Signal * signal)6092 void Dbdih::execEMPTY_LCP_CONF(Signal* signal)
6093 {
6094   jamEntry();
6095 
6096   ndbrequire(c_lcpMasterTakeOverState.state == LMTOS_WAIT_EMPTY_LCP);
6097 
6098   const EmptyLcpConf * const conf = (EmptyLcpConf *)&signal->theData[0];
6099   Uint32 nodeId = conf->senderNodeId;
6100 
6101   if(!conf->idle){
6102     jam();
6103     if (conf->tableId < c_lcpMasterTakeOverState.minTableId) {
6104       jam();
6105       c_lcpMasterTakeOverState.minTableId = conf->tableId;
6106       c_lcpMasterTakeOverState.minFragId = conf->fragmentId;
6107     } else if (conf->tableId == c_lcpMasterTakeOverState.minTableId &&
6108 	       conf->fragmentId < c_lcpMasterTakeOverState.minFragId) {
6109       jam();
6110       c_lcpMasterTakeOverState.minFragId = conf->fragmentId;
6111     }//if
6112     if(isMaster()){
6113       jam();
6114       c_lcpState.m_LAST_LCP_FRAG_ORD.setWaitingFor(nodeId);
6115     }
6116   }
6117 
6118   receiveLoopMacro(EMPTY_LCP_REQ, nodeId);
6119   /*--------------------------------------------------------------------*/
6120   // Received all EMPTY_LCPCONF. We can continue with next phase of the
6121   // take over LCP master process.
6122   /*--------------------------------------------------------------------*/
6123   c_lcpMasterTakeOverState.set(LMTOS_WAIT_LCP_FRAG_REP, __LINE__);
6124   checkEmptyLcpComplete(signal);
6125   return;
6126 }//Dbdih::execEMPTY_LCPCONF()
6127 
6128 void
checkEmptyLcpComplete(Signal * signal)6129 Dbdih::checkEmptyLcpComplete(Signal *signal){
6130 
6131   ndbrequire(c_lcpMasterTakeOverState.state == LMTOS_WAIT_LCP_FRAG_REP);
6132 
6133   if(c_lcpState.noOfLcpFragRepOutstanding > 0){
6134     jam();
6135     return;
6136   }
6137 
6138   if(isMaster()){
6139     jam();
6140 
6141     signal->theData[0] = NDB_LE_LCP_TakeoverStarted;
6142     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
6143 
6144     signal->theData[0] = 7012;
6145     execDUMP_STATE_ORD(signal);
6146 
6147     if (ERROR_INSERTED(7194))
6148     {
6149       ndbout_c("7194 starting ZREMOVE_NODE_FROM_TABLE");
6150       signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
6151       signal->theData[1] = c_lcpMasterTakeOverState.failedNodeId;
6152       signal->theData[2] = 0; // Tab id
6153       sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
6154     }
6155 
6156     c_lcpMasterTakeOverState.set(LMTOS_INITIAL, __LINE__);
6157     MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
6158     req->masterRef = reference();
6159     req->failedNodeId = c_lcpMasterTakeOverState.failedNodeId;
6160     sendLoopMacro(MASTER_LCPREQ, sendMASTER_LCPREQ);
6161 
6162   } else {
6163     sendMASTER_LCPCONF(signal);
6164   }
6165 }
6166 
6167 /*--------------------------------------------------*/
6168 /*       THE MASTER HAS FAILED AND THE NEW MASTER IS*/
6169 /*       QUERYING THIS NODE ABOUT THE STATE OF THE  */
6170 /*       LOCAL CHECKPOINT PROTOCOL.                 */
6171 /*--------------------------------------------------*/
execMASTER_LCPREQ(Signal * signal)6172 void Dbdih::execMASTER_LCPREQ(Signal* signal)
6173 {
6174   const MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
6175   jamEntry();
6176   const BlockReference newMasterBlockref = req->masterRef;
6177 
6178   if (newMasterBlockref != cmasterdihref)
6179   {
6180     jam();
6181     ndbout_c("resending GSN_MASTER_LCPREQ");
6182     sendSignalWithDelay(reference(), GSN_MASTER_LCPREQ, signal,
6183 			50, signal->getLength());
6184     return;
6185   }
6186   Uint32 failedNodeId = req->failedNodeId;
6187 
6188   /**
6189    * There can be no take over with the same master
6190    */
6191   ndbrequire(c_lcpState.m_masterLcpDihRef != newMasterBlockref);
6192   c_lcpState.m_masterLcpDihRef = newMasterBlockref;
6193   c_lcpState.m_MASTER_LCPREQ_Received = true;
6194   c_lcpState.m_MASTER_LCPREQ_FailedNodeId = failedNodeId;
6195 
6196   if(newMasterBlockref != cmasterdihref){
6197     jam();
6198     ndbrequire(0);
6199   }
6200 
6201   sendMASTER_LCPCONF(signal);
6202 }//Dbdih::execMASTER_LCPREQ()
6203 
6204 void
sendMASTER_LCPCONF(Signal * signal)6205 Dbdih::sendMASTER_LCPCONF(Signal * signal){
6206 
6207   if(!c_EMPTY_LCP_REQ_Counter.done()){
6208     /**
6209      * Have not received all EMPTY_LCP_REP
6210      * dare not answer MASTER_LCP_CONF yet
6211      */
6212     jam();
6213     return;
6214   }
6215 
6216   if(!c_lcpState.m_MASTER_LCPREQ_Received){
6217     jam();
6218     /**
6219      * Has not received MASTER_LCPREQ yet
6220      */
6221     return;
6222   }
6223 
6224   if(c_lcpState.lcpStatus == LCP_INIT_TABLES){
6225     jam();
6226     /**
6227      * Still aborting old initLcpLab
6228      */
6229     return;
6230   }
6231 
6232   if(c_lcpState.lcpStatus == LCP_COPY_GCI){
6233     jam();
6234     /**
6235      * Restart it
6236      */
6237     //Uint32 lcpId = SYSFILE->latestLCP_ID;
6238     SYSFILE->latestLCP_ID--;
6239     c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
6240 #if 0
6241     if(c_copyGCISlave.m_copyReason == CopyGCIReq::LOCAL_CHECKPOINT){
6242       g_eventLogger.info("Dbdih: Also resetting c_copyGCISlave");
6243       c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
6244       c_copyGCISlave.m_expectedNextWord = 0;
6245     }
6246 #endif
6247   }
6248 
6249   MasterLCPConf::State lcpState;
6250   switch (c_lcpState.lcpStatus) {
6251   case LCP_STATUS_IDLE:
6252     jam();
6253     /*------------------------------------------------*/
6254     /*       LOCAL CHECKPOINT IS CURRENTLY NOT ACTIVE */
6255     /*       SINCE NO COPY OF RESTART INFORMATION HAVE*/
6256     /*       BEEN RECEIVED YET. ALSO THE PREVIOUS     */
6257     /*       CHECKPOINT HAVE BEEN FULLY COMPLETED.    */
6258     /*------------------------------------------------*/
6259     lcpState = MasterLCPConf::LCP_STATUS_IDLE;
6260     break;
6261   case LCP_STATUS_ACTIVE:
6262     jam();
6263     /*--------------------------------------------------*/
6264     /*       COPY OF RESTART INFORMATION HAS BEEN       */
6265     /*       PERFORMED AND ALSO RESPONSE HAVE BEEN SENT.*/
6266     /*--------------------------------------------------*/
6267     lcpState = MasterLCPConf::LCP_STATUS_ACTIVE;
6268     break;
6269   case LCP_TAB_COMPLETED:
6270     jam();
6271     /*--------------------------------------------------------*/
6272     /*       ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR         */
6273     /*       ALL TABLES.     SAVE OF AT LEAST ONE TABLE IS    */
6274     /*       ONGOING YET.                                     */
6275     /*--------------------------------------------------------*/
6276     lcpState = MasterLCPConf::LCP_TAB_COMPLETED;
6277     break;
6278   case LCP_TAB_SAVED:
6279     jam();
6280     /*--------------------------------------------------------*/
6281     /*       ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR         */
6282     /*       ALL TABLES.     ALL TABLES HAVE ALSO BEEN SAVED  */
6283     /*       ALL OTHER NODES ARE NOT YET FINISHED WITH        */
6284     /*       THE LOCAL CHECKPOINT.                            */
6285     /*--------------------------------------------------------*/
6286     lcpState = MasterLCPConf::LCP_TAB_SAVED;
6287     break;
6288   case LCP_TCGET:
6289   case LCP_CALCULATE_KEEP_GCI:
6290   case LCP_TC_CLOPSIZE:
6291   case LCP_START_LCP_ROUND:
6292     /**
6293      * These should only exists on the master
6294      *   but since this is master take over
6295      *   it not allowed
6296      */
6297     ndbrequire(false);
6298     lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
6299     break;
6300   case LCP_COPY_GCI:
6301   case LCP_INIT_TABLES:
6302     /**
6303      * These two states are handled by if statements above
6304      */
6305     ndbrequire(false);
6306     lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
6307     break;
6308   default:
6309     ndbrequire(false);
6310     lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
6311   }//switch
6312 
6313   Uint32 failedNodeId = c_lcpState.m_MASTER_LCPREQ_FailedNodeId;
6314   MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
6315   conf->senderNodeId = cownNodeId;
6316   conf->lcpState = lcpState;
6317   conf->failedNodeId = failedNodeId;
6318   sendSignal(c_lcpState.m_masterLcpDihRef, GSN_MASTER_LCPCONF,
6319              signal, MasterLCPConf::SignalLength, JBB);
6320 
6321   // Answer to MASTER_LCPREQ sent, reset flag so
6322   // that it's not sent again before another request comes in
6323   c_lcpState.m_MASTER_LCPREQ_Received = false;
6324 
6325   if(c_lcpState.lcpStatus == LCP_TAB_SAVED){
6326 #ifdef VM_TRACE
6327     g_eventLogger.info("Sending extra GSN_LCP_COMPLETE_REP to new master");
6328 #endif
6329     sendLCP_COMPLETE_REP(signal);
6330   }
6331 
6332   if(!isMaster()){
6333     c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
6334     checkLocalNodefailComplete(signal, failedNodeId, NF_LCP_TAKE_OVER);
6335   }
6336 
6337   return;
6338 }
6339 
6340 NdbOut&
operator <<(NdbOut & out,const Dbdih::LcpMasterTakeOverState state)6341 operator<<(NdbOut& out, const Dbdih::LcpMasterTakeOverState state){
6342   switch(state){
6343   case Dbdih::LMTOS_IDLE:
6344     out << "LMTOS_IDLE";
6345     break;
6346   case Dbdih::LMTOS_WAIT_EMPTY_LCP:
6347     out << "LMTOS_WAIT_EMPTY_LCP";
6348     break;
6349   case Dbdih::LMTOS_WAIT_LCP_FRAG_REP:
6350     out << "LMTOS_WAIT_EMPTY_LCP";
6351     break;
6352   case Dbdih::LMTOS_INITIAL:
6353     out << "LMTOS_INITIAL";
6354     break;
6355   case Dbdih::LMTOS_ALL_IDLE:
6356     out << "LMTOS_ALL_IDLE";
6357     break;
6358   case Dbdih::LMTOS_ALL_ACTIVE:
6359     out << "LMTOS_ALL_ACTIVE";
6360     break;
6361   case Dbdih::LMTOS_LCP_CONCLUDING:
6362     out << "LMTOS_LCP_CONCLUDING";
6363     break;
6364   case Dbdih::LMTOS_COPY_ONGOING:
6365     out << "LMTOS_COPY_ONGOING";
6366     break;
6367   }
6368   return out;
6369 }
6370 
6371 struct MASTERLCP_StateTransitions {
6372   Dbdih::LcpMasterTakeOverState CurrentState;
6373   MasterLCPConf::State ParticipantState;
6374   Dbdih::LcpMasterTakeOverState NewState;
6375 };
6376 
6377 static const
6378 MASTERLCP_StateTransitions g_masterLCPTakeoverStateTransitions[] = {
6379   /**
6380    * Current = LMTOS_INITIAL
6381    */
6382   { Dbdih::LMTOS_INITIAL,
6383     MasterLCPConf::LCP_STATUS_IDLE,
6384     Dbdih::LMTOS_ALL_IDLE },
6385 
6386   { Dbdih::LMTOS_INITIAL,
6387     MasterLCPConf::LCP_STATUS_ACTIVE,
6388     Dbdih::LMTOS_ALL_ACTIVE },
6389 
6390   { Dbdih::LMTOS_INITIAL,
6391     MasterLCPConf::LCP_TAB_COMPLETED,
6392     Dbdih::LMTOS_LCP_CONCLUDING },
6393 
6394   { Dbdih::LMTOS_INITIAL,
6395     MasterLCPConf::LCP_TAB_SAVED,
6396     Dbdih::LMTOS_LCP_CONCLUDING },
6397 
6398   /**
6399    * Current = LMTOS_ALL_IDLE
6400    */
6401   { Dbdih::LMTOS_ALL_IDLE,
6402     MasterLCPConf::LCP_STATUS_IDLE,
6403     Dbdih::LMTOS_ALL_IDLE },
6404 
6405   { Dbdih::LMTOS_ALL_IDLE,
6406     MasterLCPConf::LCP_STATUS_ACTIVE,
6407     Dbdih::LMTOS_COPY_ONGOING },
6408 
6409   { Dbdih::LMTOS_ALL_IDLE,
6410     MasterLCPConf::LCP_TAB_COMPLETED,
6411     Dbdih::LMTOS_LCP_CONCLUDING },
6412 
6413   { Dbdih::LMTOS_ALL_IDLE,
6414     MasterLCPConf::LCP_TAB_SAVED,
6415     Dbdih::LMTOS_LCP_CONCLUDING },
6416 
6417   /**
6418    * Current = LMTOS_COPY_ONGOING
6419    */
6420   { Dbdih::LMTOS_COPY_ONGOING,
6421     MasterLCPConf::LCP_STATUS_IDLE,
6422     Dbdih::LMTOS_COPY_ONGOING },
6423 
6424   { Dbdih::LMTOS_COPY_ONGOING,
6425     MasterLCPConf::LCP_STATUS_ACTIVE,
6426     Dbdih::LMTOS_COPY_ONGOING },
6427 
6428   /**
6429    * Current = LMTOS_ALL_ACTIVE
6430    */
6431   { Dbdih::LMTOS_ALL_ACTIVE,
6432     MasterLCPConf::LCP_STATUS_IDLE,
6433     Dbdih::LMTOS_COPY_ONGOING },
6434 
6435   { Dbdih::LMTOS_ALL_ACTIVE,
6436     MasterLCPConf::LCP_STATUS_ACTIVE,
6437     Dbdih::LMTOS_ALL_ACTIVE },
6438 
6439   { Dbdih::LMTOS_ALL_ACTIVE,
6440     MasterLCPConf::LCP_TAB_COMPLETED,
6441     Dbdih::LMTOS_LCP_CONCLUDING },
6442 
6443   { Dbdih::LMTOS_ALL_ACTIVE,
6444     MasterLCPConf::LCP_TAB_SAVED,
6445     Dbdih::LMTOS_LCP_CONCLUDING },
6446 
6447   /**
6448    * Current = LMTOS_LCP_CONCLUDING
6449    */
6450   { Dbdih::LMTOS_LCP_CONCLUDING,
6451     MasterLCPConf::LCP_STATUS_IDLE,
6452     Dbdih::LMTOS_LCP_CONCLUDING },
6453 
6454   { Dbdih::LMTOS_LCP_CONCLUDING,
6455     MasterLCPConf::LCP_STATUS_ACTIVE,
6456     Dbdih::LMTOS_LCP_CONCLUDING },
6457 
6458   { Dbdih::LMTOS_LCP_CONCLUDING,
6459     MasterLCPConf::LCP_TAB_COMPLETED,
6460     Dbdih::LMTOS_LCP_CONCLUDING },
6461 
6462   { Dbdih::LMTOS_LCP_CONCLUDING,
6463     MasterLCPConf::LCP_TAB_SAVED,
6464     Dbdih::LMTOS_LCP_CONCLUDING }
6465 };
6466 
6467 const Uint32 g_masterLCPTakeoverStateTransitionsRows =
6468 sizeof(g_masterLCPTakeoverStateTransitions) / sizeof(struct MASTERLCP_StateTransitions);
6469 
execMASTER_LCPCONF(Signal * signal)6470 void Dbdih::execMASTER_LCPCONF(Signal* signal)
6471 {
6472   const MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
6473   jamEntry();
6474 
6475   if (ERROR_INSERTED(7194))
6476   {
6477     ndbout_c("delaying MASTER_LCPCONF due to error 7194");
6478     sendSignalWithDelay(reference(), GSN_MASTER_LCPCONF, signal,
6479                         300, signal->getLength());
6480     return;
6481   }
6482 
6483   Uint32 senderNodeId = conf->senderNodeId;
6484   MasterLCPConf::State lcpState = (MasterLCPConf::State)conf->lcpState;
6485   const Uint32 failedNodeId = conf->failedNodeId;
6486   NodeRecordPtr nodePtr;
6487   nodePtr.i = senderNodeId;
6488   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
6489   nodePtr.p->lcpStateAtTakeOver = lcpState;
6490 
6491   CRASH_INSERTION(7180);
6492 
6493 #ifdef VM_TRACE
6494   g_eventLogger.info("MASTER_LCPCONF");
6495   printMASTER_LCP_CONF(stdout, &signal->theData[0], 0, 0);
6496 #endif
6497 
6498   bool found = false;
6499   for(Uint32 i = 0; i<g_masterLCPTakeoverStateTransitionsRows; i++){
6500     const struct MASTERLCP_StateTransitions * valid =
6501       &g_masterLCPTakeoverStateTransitions[i];
6502 
6503     if(valid->CurrentState == c_lcpMasterTakeOverState.state &&
6504        valid->ParticipantState == lcpState){
6505       jam();
6506       found = true;
6507       c_lcpMasterTakeOverState.set(valid->NewState, __LINE__);
6508       break;
6509     }
6510   }
6511   ndbrequire(found);
6512 
6513   bool ok = false;
6514   switch(lcpState){
6515   case MasterLCPConf::LCP_STATUS_IDLE:
6516     ok = true;
6517     break;
6518   case MasterLCPConf::LCP_STATUS_ACTIVE:
6519   case MasterLCPConf::LCP_TAB_COMPLETED:
6520   case MasterLCPConf::LCP_TAB_SAVED:
6521     ok = true;
6522     c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.setWaitingFor(nodePtr.i);
6523     break;
6524   }
6525   ndbrequire(ok);
6526 
6527   receiveLoopMacro(MASTER_LCPREQ, senderNodeId);
6528   /*-------------------------------------------------------------------------*/
6529   // We have now received all responses and are ready to take over the LCP
6530   // protocol as master.
6531   /*-------------------------------------------------------------------------*/
6532   MASTER_LCPhandling(signal, failedNodeId);
6533 }//Dbdih::execMASTER_LCPCONF()
6534 
execMASTER_LCPREF(Signal * signal)6535 void Dbdih::execMASTER_LCPREF(Signal* signal)
6536 {
6537   const MasterLCPRef * const ref = (MasterLCPRef *)&signal->theData[0];
6538   jamEntry();
6539   receiveLoopMacro(MASTER_LCPREQ, ref->senderNodeId);
6540   /*-------------------------------------------------------------------------*/
6541   // We have now received all responses and are ready to take over the LCP
6542   // protocol as master.
6543   /*-------------------------------------------------------------------------*/
6544   MASTER_LCPhandling(signal, ref->failedNodeId);
6545 }//Dbdih::execMASTER_LCPREF()
6546 
MASTER_LCPhandling(Signal * signal,Uint32 failedNodeId)6547 void Dbdih::MASTER_LCPhandling(Signal* signal, Uint32 failedNodeId)
6548 {
6549   /*-------------------------------------------------------------------------
6550    *
6551    * WE ARE NOW READY TO CONCLUDE THE TAKE OVER AS MASTER.
6552    * WE HAVE ENOUGH INFO TO START UP ACTIVITIES IN THE PROPER PLACE.
6553    * ALSO SET THE PROPER STATE VARIABLES.
6554    *------------------------------------------------------------------------*/
6555   c_lcpState.currentFragment.tableId = c_lcpMasterTakeOverState.minTableId;
6556   c_lcpState.currentFragment.fragmentId = c_lcpMasterTakeOverState.minFragId;
6557   c_lcpState.m_LAST_LCP_FRAG_ORD = c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH;
6558 
6559   NodeRecordPtr failedNodePtr;
6560   failedNodePtr.i = failedNodeId;
6561   ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
6562 
6563   switch (c_lcpMasterTakeOverState.state) {
6564   case LMTOS_ALL_IDLE:
6565     jam();
6566     /* --------------------------------------------------------------------- */
6567     // All nodes were idle in the LCP protocol. Start checking for start of LCP
6568     // protocol.
6569     /* --------------------------------------------------------------------- */
6570 #ifdef VM_TRACE
6571     g_eventLogger.info("MASTER_LCPhandling:: LMTOS_ALL_IDLE -> checkLcpStart");
6572 #endif
6573     checkLcpStart(signal, __LINE__);
6574     break;
6575   case LMTOS_COPY_ONGOING:
6576     jam();
6577     /* --------------------------------------------------------------------- */
6578     // We were in the starting process of the LCP protocol. We will restart the
6579     // protocol by calculating the keep gci and storing the new lcp id.
6580     /* --------------------------------------------------------------------- */
6581 #ifdef VM_TRACE
6582     g_eventLogger.info("MASTER_LCPhandling:: LMTOS_COPY_ONGOING -> storeNewLcpId");
6583 #endif
6584     if (c_lcpState.lcpStatus == LCP_STATUS_ACTIVE) {
6585       jam();
6586       /*---------------------------------------------------------------------*/
6587       /*  WE NEED TO DECREASE THE LATEST LCP ID SINCE WE HAVE ALREADY        */
6588       /*  STARTED THIS */
6589       /*  LOCAL CHECKPOINT.                                                  */
6590       /*---------------------------------------------------------------------*/
6591       Uint32 lcpId = SYSFILE->latestLCP_ID;
6592 #ifdef VM_TRACE
6593       g_eventLogger.info("Decreasing latestLCP_ID from %d to %d", lcpId, lcpId - 1);
6594 #endif
6595       SYSFILE->latestLCP_ID--;
6596     }//if
6597     storeNewLcpIdLab(signal);
6598     break;
6599   case LMTOS_ALL_ACTIVE:
6600     {
6601       jam();
6602       /* -------------------------------------------------------------------
6603        * Everybody was in the active phase. We will restart sending
6604        * LCP_FRAGORD to the nodes from the new master.
6605        * We also need to set dihLcpStatus to ZACTIVE
6606        * in the master node since the master will wait for all nodes to
6607        * complete before finalising the LCP process.
6608        * ------------------------------------------------------------------ */
6609 #ifdef VM_TRACE
6610       g_eventLogger.info("MASTER_LCPhandling:: LMTOS_ALL_ACTIVE -> "
6611                          "startLcpRoundLoopLab(table=%u, fragment=%u)",
6612                          c_lcpMasterTakeOverState.minTableId,
6613                          c_lcpMasterTakeOverState.minFragId);
6614 #endif
6615 
6616       c_lcpState.keepGci = SYSFILE->keepGCI;
6617       startLcpRoundLoopLab(signal, 0, 0);
6618       break;
6619     }
6620   case LMTOS_LCP_CONCLUDING:
6621     {
6622       jam();
6623       /* ------------------------------------------------------------------- */
6624       // The LCP process is in the finalisation phase. We simply wait for it to
6625       // complete with signals arriving in. We need to check also if we should
6626       // change state due to table write completion during state
6627       // collection phase.
6628       /* ------------------------------------------------------------------- */
6629       ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
6630       startLcpRoundLoopLab(signal, 0, 0);
6631       break;
6632     }
6633   default:
6634     ndbrequire(false);
6635     break;
6636   }//switch
6637   signal->theData[0] = NDB_LE_LCP_TakeoverCompleted;
6638   signal->theData[1] = c_lcpMasterTakeOverState.state;
6639   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
6640 
6641   signal->theData[0] = 7012;
6642   execDUMP_STATE_ORD(signal);
6643 
6644   c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
6645 
6646   checkLocalNodefailComplete(signal, failedNodePtr.i, NF_LCP_TAKE_OVER);
6647 }
6648 
6649 /* ------------------------------------------------------------------------- */
6650 /*       A BLOCK OR A NODE HAS COMPLETED THE HANDLING OF THE NODE FAILURE.   */
6651 /* ------------------------------------------------------------------------- */
execNF_COMPLETEREP(Signal * signal)6652 void Dbdih::execNF_COMPLETEREP(Signal* signal)
6653 {
6654   NodeRecordPtr failedNodePtr;
6655   NFCompleteRep * const nfCompleteRep = (NFCompleteRep *)&signal->theData[0];
6656   jamEntry();
6657   const Uint32 blockNo = nfCompleteRep->blockNo;
6658   Uint32 nodeId       = nfCompleteRep->nodeId;
6659   failedNodePtr.i = nfCompleteRep->failedNodeId;
6660 
6661   ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
6662   switch (blockNo) {
6663   case DBTC:
6664     jam();
6665     ndbrequire(failedNodePtr.p->dbtcFailCompleted == ZFALSE);
6666     /* -------------------------------------------------------------------- */
6667     // Report the event that DBTC completed node failure handling.
6668     /* -------------------------------------------------------------------- */
6669     signal->theData[0] = NDB_LE_NodeFailCompleted;
6670     signal->theData[1] = DBTC;
6671     signal->theData[2] = failedNodePtr.i;
6672     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
6673 
6674     failedNodePtr.p->dbtcFailCompleted = ZTRUE;
6675     break;
6676   case DBDICT:
6677     jam();
6678     ndbrequire(failedNodePtr.p->dbdictFailCompleted == ZFALSE);
6679     /* --------------------------------------------------------------------- */
6680     // Report the event that DBDICT completed node failure handling.
6681     /* --------------------------------------------------------------------- */
6682     signal->theData[0] = NDB_LE_NodeFailCompleted;
6683     signal->theData[1] = DBDICT;
6684     signal->theData[2] = failedNodePtr.i;
6685     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
6686 
6687     failedNodePtr.p->dbdictFailCompleted = ZTRUE;
6688     break;
6689   case DBDIH:
6690     jam();
6691     ndbrequire(failedNodePtr.p->dbdihFailCompleted == ZFALSE);
6692     /* --------------------------------------------------------------------- */
6693     // Report the event that DBDIH completed node failure handling.
6694     /* --------------------------------------------------------------------- */
6695     signal->theData[0] = NDB_LE_NodeFailCompleted;
6696     signal->theData[1] = DBDIH;
6697     signal->theData[2] = failedNodePtr.i;
6698     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
6699 
6700     failedNodePtr.p->dbdihFailCompleted = ZTRUE;
6701     break;
6702   case DBLQH:
6703     jam();
6704     ndbrequire(failedNodePtr.p->dblqhFailCompleted == ZFALSE);
6705     /* --------------------------------------------------------------------- */
6706     // Report the event that DBDIH completed node failure handling.
6707     /* --------------------------------------------------------------------- */
6708     signal->theData[0] = NDB_LE_NodeFailCompleted;
6709     signal->theData[1] = DBLQH;
6710     signal->theData[2] = failedNodePtr.i;
6711     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
6712 
6713     failedNodePtr.p->dblqhFailCompleted = ZTRUE;
6714     break;
6715   case 0: /* Node has finished */
6716     jam();
6717     ndbrequire(nodeId < MAX_NDB_NODES);
6718 
6719     if (failedNodePtr.p->recNODE_FAILREP == ZFALSE) {
6720       jam();
6721       /* ------------------------------------------------------------------- */
6722       // We received a report about completion of node failure before we
6723       // received the message about the NODE failure ourselves.
6724       // We will send the signal to ourselves with a small delay
6725       // (10 milliseconds).
6726       /* ------------------------------------------------------------------- */
6727       //nf->from = __LINE__;
6728       sendSignalWithDelay(reference(), GSN_NF_COMPLETEREP, signal, 10,
6729 			  signal->length());
6730       return;
6731     }//if
6732 
6733     if (!failedNodePtr.p->m_NF_COMPLETE_REP.isWaitingFor(nodeId)){
6734       jam();
6735       return;
6736     }
6737 
6738     failedNodePtr.p->m_NF_COMPLETE_REP.clearWaitingFor(nodeId);;
6739 
6740     /* -------------------------------------------------------------------- */
6741     // Report the event that nodeId has completed node failure handling.
6742     /* -------------------------------------------------------------------- */
6743     signal->theData[0] = NDB_LE_NodeFailCompleted;
6744     signal->theData[1] = 0;
6745     signal->theData[2] = failedNodePtr.i;
6746     signal->theData[3] = nodeId;
6747     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
6748 
6749     nodeFailCompletedCheckLab(signal, failedNodePtr);
6750     return;
6751     break;
6752   default:
6753     ndbrequire(false);
6754     return;
6755     break;
6756   }//switch
6757   if (failedNodePtr.p->dbtcFailCompleted == ZFALSE) {
6758     jam();
6759     return;
6760   }//if
6761   if (failedNodePtr.p->dbdictFailCompleted == ZFALSE) {
6762     jam();
6763     return;
6764   }//if
6765   if (failedNodePtr.p->dbdihFailCompleted == ZFALSE) {
6766     jam();
6767     return;
6768   }//if
6769   if (failedNodePtr.p->dblqhFailCompleted == ZFALSE) {
6770     jam();
6771     return;
6772   }//if
6773   /* ----------------------------------------------------------------------- */
6774   /*     ALL BLOCKS IN THIS NODE HAVE COMPLETED THEIR PART OF HANDLING THE   */
6775   /*     NODE FAILURE. WE CAN NOW REPORT THIS COMPLETION TO ALL OTHER NODES. */
6776   /* ----------------------------------------------------------------------- */
6777   NodeRecordPtr nodePtr;
6778   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
6779     jam();
6780     ptrAss(nodePtr, nodeRecord);
6781     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
6782       jam();
6783       BlockReference ref = calcDihBlockRef(nodePtr.i);
6784       NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
6785       nf->blockNo      = 0;
6786       nf->nodeId       = cownNodeId;
6787       nf->failedNodeId = failedNodePtr.i;
6788       nf->from = __LINE__;
6789       sendSignal(ref, GSN_NF_COMPLETEREP, signal,
6790                  NFCompleteRep::SignalLength, JBB);
6791     }//if
6792   }//for
6793   return;
6794 }//Dbdih::execNF_COMPLETEREP()
6795 
nodeFailCompletedCheckLab(Signal * signal,NodeRecordPtr failedNodePtr)6796 void Dbdih::nodeFailCompletedCheckLab(Signal* signal,
6797 				      NodeRecordPtr failedNodePtr)
6798 {
6799   jam();
6800   if (!failedNodePtr.p->m_NF_COMPLETE_REP.done()){
6801     jam();
6802     return;
6803   }//if
6804   /* ---------------------------------------------------------------------- */
6805   /*    ALL BLOCKS IN ALL NODES HAVE NOW REPORTED COMPLETION OF THE NODE    */
6806   /*    FAILURE HANDLING. WE ARE NOW READY TO ACCEPT THAT THIS NODE STARTS  */
6807   /*    AGAIN.                                                              */
6808   /* ---------------------------------------------------------------------- */
6809   jam();
6810   failedNodePtr.p->nodeStatus = NodeRecord::DEAD;
6811   failedNodePtr.p->recNODE_FAILREP = ZFALSE;
6812 
6813   /* ---------------------------------------------------------------------- */
6814   // Report the event that all nodes completed node failure handling.
6815   /* ---------------------------------------------------------------------- */
6816   signal->theData[0] = NDB_LE_NodeFailCompleted;
6817   signal->theData[1] = 0;
6818   signal->theData[2] = failedNodePtr.i;
6819   signal->theData[3] = 0;
6820   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
6821 
6822   /* ---------------------------------------------------------------------- */
6823   // Report to QMGR that we have concluded recovery handling of this node.
6824   /* ---------------------------------------------------------------------- */
6825   signal->theData[0] = failedNodePtr.i;
6826   sendSignal(QMGR_REF, GSN_NDB_FAILCONF, signal, 1, JBB);
6827 
6828   if (isMaster()) {
6829     jam();
6830     /* --------------------------------------------------------------------- */
6831     /*   IF WE ARE MASTER WE MUST CHECK IF COPY FRAGMENT WAS INTERRUPTED     */
6832     /*   BY THE FAILED NODES.                                                */
6833     /* --------------------------------------------------------------------- */
6834     TakeOverRecordPtr takeOverPtr;
6835     takeOverPtr.i = 0;
6836     ptrAss(takeOverPtr, takeOverRecord);
6837     if ((takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG) &&
6838         (failedNodePtr.i == takeOverPtr.p->toCopyNode)) {
6839       jam();
6840 #ifdef VM_TRACE
6841       ndbrequire("Tell jonas" == 0);
6842 #endif
6843       /*------------------------------------------------------------------*/
6844       /*       WE ARE CURRENTLY IN THE PROCESS OF COPYING A FRAGMENT. WE  */
6845       /*       WILL CHECK IF THE COPY NODE HAVE FAILED.                   */
6846       /*------------------------------------------------------------------*/
6847       takeOverPtr.p->toMasterStatus = TakeOverRecord::SELECTING_NEXT;
6848       startNextCopyFragment(signal, takeOverPtr.i);
6849       return;
6850     }//if
6851     checkStartTakeOver(signal);
6852   }//if
6853   return;
6854 }//Dbdih::nodeFailCompletedCheckLab()
6855 
6856 /*****************************************************************************/
6857 /* **********     SEIZING / RELEASING MODULE                     *************/
6858 /*****************************************************************************/
6859 /*
6860   3.4   L O C A L  N O D E   S E I Z E
6861   ************************************
6862   */
6863 /*
6864   3.4.1   L O C A L  N O D E   S E I Z E   R E Q U E S T
6865   ******************************************************
6866   */
execDISEIZEREQ(Signal * signal)6867 void Dbdih::execDISEIZEREQ(Signal* signal)
6868 {
6869   ConnectRecordPtr connectPtr;
6870   jamEntry();
6871   Uint32 userPtr = signal->theData[0];
6872   BlockReference userRef = signal->theData[1];
6873   ndbrequire(cfirstconnect != RNIL);
6874   connectPtr.i = cfirstconnect;
6875   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
6876   cfirstconnect = connectPtr.p->nfConnect;
6877   connectPtr.p->nfConnect = RNIL;
6878   connectPtr.p->userpointer = userPtr;
6879   connectPtr.p->userblockref = userRef;
6880   connectPtr.p->connectState = ConnectRecord::INUSE;
6881   signal->theData[0] = connectPtr.p->userpointer;
6882   signal->theData[1] = connectPtr.i;
6883   sendSignal(userRef, GSN_DISEIZECONF, signal, 2, JBB);
6884 }//Dbdih::execDISEIZEREQ()
6885 
6886 /*
6887   3.5   L O C A L  N O D E   R E L E A S E
6888   ****************************************
6889   */
6890 /*
6891   3.5.1   L O C A L  N O D E   R E L E A S E   R E Q U E S T
6892   *******************************************************=
6893   */
execDIRELEASEREQ(Signal * signal)6894 void Dbdih::execDIRELEASEREQ(Signal* signal)
6895 {
6896   ConnectRecordPtr connectPtr;
6897   jamEntry();
6898   connectPtr.i = signal->theData[0];
6899   Uint32 userRef = signal->theData[2];
6900   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
6901   ndbrequire(connectPtr.p->connectState != ConnectRecord::FREE);
6902   ndbrequire(connectPtr.p->userblockref == userRef);
6903   signal->theData[0] = connectPtr.p->userpointer;
6904   sendSignal(connectPtr.p->userblockref, GSN_DIRELEASECONF, signal, 1, JBB);
6905   release_connect(connectPtr);
6906 }//Dbdih::execDIRELEASEREQ()
6907 
6908 /*
6909   3.7   A D D   T A B L E
6910   **********************=
6911   */
6912 /*****************************************************************************/
6913 /* **********     TABLE ADDING MODULE                            *************/
6914 /*****************************************************************************/
6915 /*
6916   3.7.1   A D D   T A B L E   M A I N L Y
6917   ***************************************
6918   */
6919 
inc_node_or_group(Uint32 & node,Uint32 max_node)6920 static inline void inc_node_or_group(Uint32 &node, Uint32 max_node)
6921 {
6922   Uint32 next = node + 1;
6923   node = (next == max_node ? 0 : next);
6924 }
6925 
6926 /*
6927   Spread fragments in backwards compatible mode
6928 */
set_default_node_groups(Signal * signal,Uint32 noFrags)6929 static void set_default_node_groups(Signal *signal, Uint32 noFrags)
6930 {
6931   Uint16 *node_group_array = (Uint16*)&signal->theData[25];
6932   Uint32 i;
6933   node_group_array[0] = 0;
6934   for (i = 1; i < noFrags; i++)
6935     node_group_array[i] = UNDEF_NODEGROUP;
6936 }
execCREATE_FRAGMENTATION_REQ(Signal * signal)6937 void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal)
6938 {
6939   Uint16 node_group_id[MAX_NDB_PARTITIONS];
6940   jamEntry();
6941   CreateFragmentationReq * const req =
6942     (CreateFragmentationReq*)signal->getDataPtr();
6943 
6944   const Uint32 senderRef = req->senderRef;
6945   const Uint32 senderData = req->senderData;
6946   Uint32 noOfFragments = req->noOfFragments;
6947   const Uint32 fragType = req->fragmentationType;
6948   const Uint32 primaryTableId = req->primaryTableId;
6949 
6950   Uint32 err = 0;
6951 
6952   do {
6953     NodeGroupRecordPtr NGPtr;
6954     TabRecordPtr primTabPtr;
6955     Uint32 count = 2;
6956     Uint16 noOfReplicas = cnoReplicas;
6957     Uint16 *fragments = (Uint16*)(signal->theData+25);
6958     if (primaryTableId == RNIL) {
6959       jam();
6960       switch ((DictTabInfo::FragmentType)fragType)
6961       {
6962         /*
6963           Backward compatability and for all places in code not changed.
6964         */
6965         case DictTabInfo::AllNodesSmallTable:
6966           jam();
6967           noOfFragments = csystemnodes;
6968           set_default_node_groups(signal, noOfFragments);
6969           break;
6970         case DictTabInfo::AllNodesMediumTable:
6971           jam();
6972           noOfFragments = 2 * csystemnodes;
6973           set_default_node_groups(signal, noOfFragments);
6974           break;
6975         case DictTabInfo::AllNodesLargeTable:
6976           jam();
6977           noOfFragments = 4 * csystemnodes;
6978           set_default_node_groups(signal, noOfFragments);
6979           break;
6980         case DictTabInfo::SingleFragment:
6981           jam();
6982           noOfFragments = 1;
6983           set_default_node_groups(signal, noOfFragments);
6984           break;
6985         case DictTabInfo::DistrKeyHash:
6986           jam();
6987         case DictTabInfo::DistrKeyLin:
6988           jam();
6989           if (noOfFragments == 0)
6990           {
6991             jam();
6992             noOfFragments = csystemnodes;
6993             set_default_node_groups(signal, noOfFragments);
6994           }
6995           break;
6996         default:
6997           jam();
6998           if (noOfFragments == 0)
6999           {
7000             jam();
7001             err = CreateFragmentationRef::InvalidFragmentationType;
7002           }
7003           break;
7004       }
7005       if (err)
7006         break;
7007       /*
7008         When we come here the the exact partition is specified
7009         and there is an array of node groups sent along as well.
7010       */
7011       memcpy(&node_group_id[0], &signal->theData[25], 2 * noOfFragments);
7012       Uint16 next_replica_node[MAX_NDB_NODES];
7013       memset(next_replica_node,0,sizeof(next_replica_node));
7014       Uint32 default_node_group= c_nextNodeGroup;
7015       for(Uint32 fragNo = 0; fragNo < noOfFragments; fragNo++)
7016       {
7017         jam();
7018         NGPtr.i = node_group_id[fragNo];
7019         if (NGPtr.i == UNDEF_NODEGROUP)
7020         {
7021           jam();
7022 	  NGPtr.i = default_node_group;
7023         }
7024         if (NGPtr.i > cnoOfNodeGroups)
7025         {
7026           jam();
7027           err = CreateFragmentationRef::InvalidNodeGroup;
7028           break;
7029         }
7030         ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
7031         const Uint32 max = NGPtr.p->nodeCount;
7032 
7033 	fragments[count++] = c_nextLogPart++; // Store logpart first
7034 	Uint32 tmp= next_replica_node[NGPtr.i];
7035         for(Uint32 replicaNo = 0; replicaNo < noOfReplicas; replicaNo++)
7036         {
7037           jam();
7038           const Uint16 nodeId = NGPtr.p->nodesInGroup[tmp];
7039           fragments[count++]= nodeId;
7040           inc_node_or_group(tmp, max);
7041         }
7042         inc_node_or_group(tmp, max);
7043 	next_replica_node[NGPtr.i]= tmp;
7044 
7045         /**
7046          * Next node group for next fragment
7047          */
7048         inc_node_or_group(default_node_group, cnoOfNodeGroups);
7049       }
7050       if (err)
7051       {
7052         jam();
7053         break;
7054       }
7055       else
7056       {
7057         jam();
7058         c_nextNodeGroup = default_node_group;
7059       }
7060     } else {
7061       if (primaryTableId >= ctabFileSize) {
7062         jam();
7063         err = CreateFragmentationRef::InvalidPrimaryTable;
7064         break;
7065       }
7066       primTabPtr.i = primaryTableId;
7067       ptrAss(primTabPtr, tabRecord);
7068       if (primTabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
7069         jam();
7070         err = CreateFragmentationRef::InvalidPrimaryTable;
7071         break;
7072       }
7073       noOfFragments= primTabPtr.p->totalfragments;
7074       for (Uint32 fragNo = 0;
7075            fragNo < noOfFragments; fragNo++) {
7076         jam();
7077         FragmentstorePtr fragPtr;
7078         ReplicaRecordPtr replicaPtr;
7079         getFragstore(primTabPtr.p, fragNo, fragPtr);
7080 	fragments[count++] = fragPtr.p->m_log_part_id;
7081         fragments[count++] = fragPtr.p->preferredPrimary;
7082         for (replicaPtr.i = fragPtr.p->storedReplicas;
7083              replicaPtr.i != RNIL;
7084              replicaPtr.i = replicaPtr.p->nextReplica) {
7085           jam();
7086           ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7087           if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
7088             jam();
7089             fragments[count++]= replicaPtr.p->procNode;
7090           }
7091         }
7092         for (replicaPtr.i = fragPtr.p->oldStoredReplicas;
7093              replicaPtr.i != RNIL;
7094              replicaPtr.i = replicaPtr.p->nextReplica) {
7095           jam();
7096           ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7097           if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
7098             jam();
7099             fragments[count++]= replicaPtr.p->procNode;
7100           }
7101         }
7102       }
7103     }
7104     if(count != (2U + (1 + noOfReplicas) * noOfFragments)){
7105         char buf[255];
7106         BaseString::snprintf(buf, sizeof(buf),
7107                            "Illegal configuration change: NoOfReplicas."
7108                            " Can't be applied online ");
7109         progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
7110     }
7111 
7112     CreateFragmentationConf * const conf =
7113       (CreateFragmentationConf*)signal->getDataPtrSend();
7114     conf->senderRef = reference();
7115     conf->senderData = senderData;
7116     conf->noOfReplicas = (Uint32)noOfReplicas;
7117     conf->noOfFragments = (Uint32)noOfFragments;
7118 
7119     fragments[0]= noOfReplicas;
7120     fragments[1]= noOfFragments;
7121 
7122     if(senderRef != 0)
7123     {
7124       jam();
7125       LinearSectionPtr ptr[3];
7126       ptr[0].p = (Uint32*)&fragments[0];
7127       ptr[0].sz = (count + 1) / 2;
7128       sendSignal(senderRef,
7129 		 GSN_CREATE_FRAGMENTATION_CONF,
7130 		 signal,
7131 		 CreateFragmentationConf::SignalLength,
7132 		 JBB,
7133 		 ptr,
7134 		 1);
7135     }
7136     // Always ACK/NACK (here ACK)
7137     signal->theData[0] = 0;
7138     return;
7139   } while(false);
7140   // Always ACK/NACK (here NACK)
7141   signal->theData[0] = err;
7142 }
7143 
execDIADDTABREQ(Signal * signal)7144 void Dbdih::execDIADDTABREQ(Signal* signal)
7145 {
7146   Uint32 fragType;
7147   jamEntry();
7148 
7149   DiAddTabReq * const req = (DiAddTabReq*)signal->getDataPtr();
7150 
7151   // Seize connect record
7152   ndbrequire(cfirstconnect != RNIL);
7153   ConnectRecordPtr connectPtr;
7154   connectPtr.i = cfirstconnect;
7155   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7156   cfirstconnect = connectPtr.p->nfConnect;
7157 
7158   const Uint32 userPtr = req->connectPtr;
7159   const BlockReference userRef = signal->getSendersBlockRef();
7160   connectPtr.p->nfConnect = RNIL;
7161   connectPtr.p->userpointer = userPtr;
7162   connectPtr.p->userblockref = userRef;
7163   connectPtr.p->connectState = ConnectRecord::INUSE;
7164   connectPtr.p->table = req->tableId;
7165 
7166   TabRecordPtr tabPtr;
7167   tabPtr.i = req->tableId;
7168   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7169   tabPtr.p->connectrec = connectPtr.i;
7170   tabPtr.p->tableType = req->tableType;
7171   fragType= req->fragType;
7172   tabPtr.p->schemaVersion = req->schemaVersion;
7173   tabPtr.p->primaryTableId = req->primaryTableId;
7174 
7175   if(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE){
7176     jam();
7177     tabPtr.p->tabStatus = TabRecord::TS_CREATING;
7178     sendAddFragreq(signal, connectPtr, tabPtr, 0);
7179     return;
7180   }
7181 
7182   if(getNodeState().getSystemRestartInProgress() &&
7183      tabPtr.p->tabStatus == TabRecord::TS_IDLE){
7184     jam();
7185 
7186     ndbrequire(cmasterNodeId == getOwnNodeId());
7187     tabPtr.p->tabStatus = TabRecord::TS_CREATING;
7188 
7189     initTableFile(tabPtr);
7190     FileRecordPtr filePtr;
7191     filePtr.i = tabPtr.p->tabFile[0];
7192     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
7193     openFileRw(signal, filePtr);
7194     filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
7195     return;
7196   }
7197 
7198   /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
7199   /* AT THE TIME OF INITIATING THE FILE OF TABLE         */
7200   /* DESCRIPTION IS CREATED FOR APPROPRIATE SIZE. EACH   */
7201   /* EACH RECORD IN THIS FILE HAS THE INFORMATION ABOUT  */
7202   /* ONE TABLE. THE POINTER TO THIS RECORD IS THE TABLE  */
7203   /* REFERENCE. IN THE BEGINNING ALL RECORDS ARE CREATED */
7204   /* BUT THEY DO NOT HAVE ANY INFORMATION ABOUT ANY TABLE*/
7205   /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
7206   tabPtr.p->tabStatus = TabRecord::TS_CREATING;
7207   if(req->loggedTable)
7208     tabPtr.p->tabStorage= TabRecord::ST_NORMAL;
7209   else if(req->temporaryTable)
7210     tabPtr.p->tabStorage= TabRecord::ST_TEMPORARY;
7211   else
7212     tabPtr.p->tabStorage= TabRecord::ST_NOLOGGING;
7213   tabPtr.p->kvalue = req->kValue;
7214 
7215   switch ((DictTabInfo::FragmentType)fragType)
7216   {
7217     case DictTabInfo::AllNodesSmallTable:
7218     case DictTabInfo::AllNodesMediumTable:
7219     case DictTabInfo::AllNodesLargeTable:
7220     case DictTabInfo::SingleFragment:
7221       jam();
7222     case DictTabInfo::DistrKeyLin:
7223       jam();
7224       tabPtr.p->method= TabRecord::LINEAR_HASH;
7225       break;
7226     case DictTabInfo::DistrKeyHash:
7227     case DictTabInfo::DistrKeyUniqueHashIndex:
7228     case DictTabInfo::DistrKeyOrderedIndex:
7229       jam();
7230       tabPtr.p->method= TabRecord::NORMAL_HASH;
7231       break;
7232     case DictTabInfo::UserDefined:
7233       jam();
7234       tabPtr.p->method= TabRecord::USER_DEFINED;
7235       break;
7236     default:
7237       ndbrequire(false);
7238   }
7239 
7240   union {
7241     Uint16 fragments[2 + MAX_FRAG_PER_NODE*MAX_REPLICAS*MAX_NDB_NODES];
7242     Uint32 align;
7243   };
7244   SegmentedSectionPtr fragDataPtr;
7245   LINT_INIT(fragDataPtr.i);
7246   LINT_INIT(fragDataPtr.sz);
7247   signal->getSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
7248   copy((Uint32*)fragments, fragDataPtr);
7249   releaseSections(signal);
7250 
7251   const Uint32 noReplicas = fragments[0];
7252   const Uint32 noFragments = fragments[1];
7253 
7254   tabPtr.p->noOfBackups = noReplicas - 1;
7255   tabPtr.p->totalfragments = noFragments;
7256   ndbrequire(noReplicas == cnoReplicas); // Only allowed
7257 
7258   if (ERROR_INSERTED(7173)) {
7259     CLEAR_ERROR_INSERT_VALUE;
7260     addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
7261     return;
7262   }
7263   if ((noReplicas * noFragments) > cnoFreeReplicaRec) {
7264     jam();
7265     addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
7266     return;
7267   }//if
7268   if (noFragments > cremainingfrags) {
7269     jam();
7270     addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
7271     return;
7272   }//if
7273 
7274   Uint32 logTotalFragments = 1;
7275   while (logTotalFragments <= tabPtr.p->totalfragments) {
7276     jam();
7277     logTotalFragments <<= 1;
7278   }
7279   logTotalFragments >>= 1;
7280   tabPtr.p->mask = logTotalFragments - 1;
7281   tabPtr.p->hashpointer = tabPtr.p->totalfragments - logTotalFragments;
7282   allocFragments(tabPtr.p->totalfragments, tabPtr);
7283 
7284   Uint32 index = 2;
7285   for (Uint32 fragId = 0; fragId < noFragments; fragId++) {
7286     jam();
7287     FragmentstorePtr fragPtr;
7288     Uint32 activeIndex = 0;
7289     getFragstore(tabPtr.p, fragId, fragPtr);
7290     fragPtr.p->m_log_part_id = fragments[index++];
7291     fragPtr.p->preferredPrimary = fragments[index];
7292 
7293     for (Uint32 i = 0; i<noReplicas; i++) {
7294       const Uint32 nodeId = fragments[index++];
7295       ReplicaRecordPtr replicaPtr;
7296       allocStoredReplica(fragPtr, replicaPtr, nodeId);
7297       if (getNodeStatus(nodeId) == NodeRecord::ALIVE) {
7298         jam();
7299         ndbrequire(activeIndex < MAX_REPLICAS);
7300         fragPtr.p->activeNodes[activeIndex] = nodeId;
7301         activeIndex++;
7302       } else {
7303         jam();
7304         removeStoredReplica(fragPtr, replicaPtr);
7305         linkOldStoredReplica(fragPtr, replicaPtr);
7306       }//if
7307     }//for
7308     fragPtr.p->fragReplicas = activeIndex;
7309     ndbrequire(activeIndex > 0 && fragPtr.p->storedReplicas != RNIL);
7310   }
7311   initTableFile(tabPtr);
7312   tabPtr.p->tabCopyStatus = TabRecord::CS_ADD_TABLE_MASTER;
7313   signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
7314   signal->theData[1] = tabPtr.i;
7315   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
7316 }
7317 
7318 void
addTable_closeConf(Signal * signal,Uint32 tabPtrI)7319 Dbdih::addTable_closeConf(Signal * signal, Uint32 tabPtrI){
7320   TabRecordPtr tabPtr;
7321   tabPtr.i = tabPtrI;
7322   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7323 
7324   ConnectRecordPtr connectPtr;
7325   connectPtr.i = tabPtr.p->connectrec;
7326   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7327 
7328   sendAddFragreq(signal, connectPtr, tabPtr, 0);
7329 }
7330 
7331 void
sendAddFragreq(Signal * signal,ConnectRecordPtr connectPtr,TabRecordPtr tabPtr,Uint32 fragId)7332 Dbdih::sendAddFragreq(Signal* signal, ConnectRecordPtr connectPtr,
7333 		      TabRecordPtr tabPtr, Uint32 fragId){
7334   jam();
7335   const Uint32 fragCount = tabPtr.p->totalfragments;
7336   ReplicaRecordPtr replicaPtr;
7337   LINT_INIT(replicaPtr.p);
7338   replicaPtr.i = RNIL;
7339   FragmentstorePtr fragPtr;
7340   for(; fragId<fragCount; fragId++){
7341     jam();
7342     getFragstore(tabPtr.p, fragId, fragPtr);
7343 
7344     replicaPtr.i = fragPtr.p->storedReplicas;
7345     while(replicaPtr.i != RNIL){
7346       jam();
7347       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7348       if(replicaPtr.p->procNode == getOwnNodeId()){
7349 	break;
7350       }
7351       replicaPtr.i = replicaPtr.p->nextReplica;
7352     }
7353 
7354     if(replicaPtr.i != RNIL){
7355       jam();
7356       break;
7357     }
7358 
7359     replicaPtr.i = fragPtr.p->oldStoredReplicas;
7360     while(replicaPtr.i != RNIL){
7361       jam();
7362       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7363       if(replicaPtr.p->procNode == getOwnNodeId()){
7364 	break;
7365       }
7366       replicaPtr.i = replicaPtr.p->nextReplica;
7367     }
7368 
7369     if(replicaPtr.i != RNIL){
7370       jam();
7371       break;
7372     }
7373   }
7374 
7375   if(replicaPtr.i != RNIL){
7376     jam();
7377     ndbrequire(fragId < fragCount);
7378     ndbrequire(replicaPtr.p->procNode == getOwnNodeId());
7379 
7380     Uint32 requestInfo = 0;
7381     if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
7382       requestInfo |= LqhFragReq::TemporaryTable;
7383     }
7384 
7385     if(getNodeState().getNodeRestartInProgress()){
7386       requestInfo |= LqhFragReq::CreateInRunning;
7387     }
7388 
7389     AddFragReq* const req = (AddFragReq*)signal->getDataPtr();
7390     req->dihPtr = connectPtr.i;
7391     req->senderData = connectPtr.p->userpointer;
7392     req->fragmentId = fragId;
7393     req->requestInfo = requestInfo;
7394     req->tableId = tabPtr.i;
7395     req->nextLCP = 0;
7396     req->nodeId = getOwnNodeId();
7397     req->totalFragments = fragCount;
7398     req->startGci = SYSFILE->newestRestorableGCI;
7399     req->logPartId = fragPtr.p->m_log_part_id;
7400     sendSignal(DBDICT_REF, GSN_ADD_FRAGREQ, signal,
7401 	       AddFragReq::SignalLength, JBB);
7402     return;
7403   }
7404 
7405   // Done
7406   DiAddTabConf * const conf = (DiAddTabConf*)signal->getDataPtr();
7407   conf->senderData = connectPtr.p->userpointer;
7408   sendSignal(connectPtr.p->userblockref, GSN_DIADDTABCONF, signal,
7409 	     DiAddTabConf::SignalLength, JBB);
7410 
7411   // Release
7412   release_connect(connectPtr);
7413 }
7414 void
release_connect(ConnectRecordPtr ptr)7415 Dbdih::release_connect(ConnectRecordPtr ptr)
7416 {
7417   ptr.p->userblockref = ZNIL;
7418   ptr.p->userpointer = RNIL;
7419   ptr.p->connectState = ConnectRecord::FREE;
7420   ptr.p->nfConnect = cfirstconnect;
7421   cfirstconnect = ptr.i;
7422 }
7423 
7424 void
execADD_FRAGCONF(Signal * signal)7425 Dbdih::execADD_FRAGCONF(Signal* signal){
7426   jamEntry();
7427   AddFragConf * const conf = (AddFragConf*)signal->getDataPtr();
7428 
7429   ConnectRecordPtr connectPtr;
7430   connectPtr.i = conf->dihPtr;
7431   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7432 
7433   TabRecordPtr tabPtr;
7434   tabPtr.i = connectPtr.p->table;
7435   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7436 
7437   sendAddFragreq(signal, connectPtr, tabPtr, conf->fragId + 1);
7438 }
7439 
7440 void
execADD_FRAGREF(Signal * signal)7441 Dbdih::execADD_FRAGREF(Signal* signal){
7442   jamEntry();
7443   AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
7444 
7445   ConnectRecordPtr connectPtr;
7446   connectPtr.i = ref->dihPtr;
7447   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7448 
7449   {
7450     DiAddTabRef * const ref = (DiAddTabRef*)signal->getDataPtr();
7451     ref->senderData = connectPtr.p->userpointer;
7452     ref->errorCode = ~0;
7453     sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal,
7454 	       DiAddTabRef::SignalLength, JBB);
7455   }
7456 
7457   // Release
7458   release_connect(connectPtr);
7459 }
7460 
7461 /*
7462   3.7.1.3   R E F U S E
7463   *********************
7464   */
addtabrefuseLab(Signal * signal,ConnectRecordPtr connectPtr,Uint32 errorCode)7465 void Dbdih::addtabrefuseLab(Signal* signal, ConnectRecordPtr connectPtr, Uint32 errorCode)
7466 {
7467   signal->theData[0] = connectPtr.p->userpointer;
7468   signal->theData[1] = errorCode;
7469   sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal, 2, JBB);
7470   release_connect(connectPtr);
7471   return;
7472 }//Dbdih::addtabrefuseLab()
7473 
7474 /*
7475   3.7.2   A D D   T A B L E   D U P L I C A T I O N
7476   *************************************************
7477   */
7478 /*
7479   3.7.2.1    A D D   T A B L E   D U P L I C A T I O N   R E Q U E S T
7480   *******************************************************************=
7481   */
7482 
7483 /*
7484   D E L E T E   T A B L E
7485   **********************=
7486   */
7487 /*****************************************************************************/
7488 /***********              DELETE TABLE  MODULE                   *************/
7489 /*****************************************************************************/
7490 void
execDROP_TAB_REQ(Signal * signal)7491 Dbdih::execDROP_TAB_REQ(Signal* signal){
7492   jamEntry();
7493   DropTabReq* req = (DropTabReq*)signal->getDataPtr();
7494 
7495   TabRecordPtr tabPtr;
7496   tabPtr.i = req->tableId;
7497   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7498 
7499   tabPtr.p->m_dropTab.tabUserRef = req->senderRef;
7500   tabPtr.p->m_dropTab.tabUserPtr = req->senderData;
7501 
7502   DropTabReq::RequestType rt = (DropTabReq::RequestType)req->requestType;
7503 
7504   switch(rt){
7505   case DropTabReq::OnlineDropTab:
7506     jam();
7507     ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
7508     releaseTable(tabPtr);
7509     break;
7510   case DropTabReq::CreateTabDrop:
7511     jam();
7512     releaseTable(tabPtr);
7513     break;
7514   case DropTabReq::RestartDropTab:
7515     break;
7516   }
7517 
7518   startDeleteFile(signal, tabPtr);
7519 }
7520 
startDeleteFile(Signal * signal,TabRecordPtr tabPtr)7521 void Dbdih::startDeleteFile(Signal* signal, TabRecordPtr tabPtr)
7522 {
7523   if (tabPtr.p->tabFile[0] == RNIL) {
7524     jam();
7525     initTableFile(tabPtr);
7526   }//if
7527   openTableFileForDelete(signal, tabPtr.p->tabFile[0]);
7528 }//Dbdih::startDeleteFile()
7529 
openTableFileForDelete(Signal * signal,Uint32 fileIndex)7530 void Dbdih::openTableFileForDelete(Signal* signal, Uint32 fileIndex)
7531 {
7532   FileRecordPtr filePtr;
7533   filePtr.i = fileIndex;
7534   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
7535   openFileRw(signal, filePtr);
7536   filePtr.p->reqStatus = FileRecord::TABLE_OPEN_FOR_DELETE;
7537 }//Dbdih::openTableFileForDelete()
7538 
tableOpenLab(Signal * signal,FileRecordPtr filePtr)7539 void Dbdih::tableOpenLab(Signal* signal, FileRecordPtr filePtr)
7540 {
7541   closeFileDelete(signal, filePtr);
7542   filePtr.p->reqStatus = FileRecord::TABLE_CLOSE_DELETE;
7543   return;
7544 }//Dbdih::tableOpenLab()
7545 
tableDeleteLab(Signal * signal,FileRecordPtr filePtr)7546 void Dbdih::tableDeleteLab(Signal* signal, FileRecordPtr filePtr)
7547 {
7548   TabRecordPtr tabPtr;
7549   tabPtr.i = filePtr.p->tabRef;
7550   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7551   if (filePtr.i == tabPtr.p->tabFile[0]) {
7552     jam();
7553     openTableFileForDelete(signal, tabPtr.p->tabFile[1]);
7554     return;
7555   }//if
7556   ndbrequire(filePtr.i == tabPtr.p->tabFile[1]);
7557 
7558   releaseFile(tabPtr.p->tabFile[0]);
7559   releaseFile(tabPtr.p->tabFile[1]);
7560   tabPtr.p->tabFile[0] = tabPtr.p->tabFile[1] = RNIL;
7561 
7562   tabPtr.p->tabStatus = TabRecord::TS_IDLE;
7563 
7564   DropTabConf * const dropConf = (DropTabConf *)signal->getDataPtrSend();
7565   dropConf->senderRef = reference();
7566   dropConf->senderData = tabPtr.p->m_dropTab.tabUserPtr;
7567   dropConf->tableId = tabPtr.i;
7568   sendSignal(tabPtr.p->m_dropTab.tabUserRef, GSN_DROP_TAB_CONF,
7569 	     signal, DropTabConf::SignalLength, JBB);
7570 
7571   tabPtr.p->m_dropTab.tabUserPtr = RNIL;
7572   tabPtr.p->m_dropTab.tabUserRef = 0;
7573 }//Dbdih::tableDeleteLab()
7574 
7575 
releaseTable(TabRecordPtr tabPtr)7576 void Dbdih::releaseTable(TabRecordPtr tabPtr)
7577 {
7578   FragmentstorePtr fragPtr;
7579   if (tabPtr.p->noOfFragChunks > 0) {
7580     for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
7581       jam();
7582       getFragstore(tabPtr.p, fragId, fragPtr);
7583       releaseReplicas(fragPtr.p->storedReplicas);
7584       releaseReplicas(fragPtr.p->oldStoredReplicas);
7585     }//for
7586     releaseFragments(tabPtr);
7587   }
7588   if (tabPtr.p->tabFile[0] != RNIL) {
7589     jam();
7590     releaseFile(tabPtr.p->tabFile[0]);
7591     releaseFile(tabPtr.p->tabFile[1]);
7592     tabPtr.p->tabFile[0] = tabPtr.p->tabFile[1] = RNIL;
7593   }//if
7594 }//Dbdih::releaseTable()
7595 
releaseReplicas(Uint32 replicaPtrI)7596 void Dbdih::releaseReplicas(Uint32 replicaPtrI)
7597 {
7598   ReplicaRecordPtr replicaPtr;
7599   replicaPtr.i = replicaPtrI;
7600   jam();
7601   while (replicaPtr.i != RNIL) {
7602     jam();
7603     ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7604     Uint32 tmp = replicaPtr.p->nextReplica;
7605     replicaPtr.p->nextReplica = cfirstfreeReplica;
7606     cfirstfreeReplica = replicaPtr.i;
7607     replicaPtr.i = tmp;
7608     cnoFreeReplicaRec++;
7609   }//while
7610 }//Dbdih::releaseReplicas()
7611 
seizeReplicaRec(ReplicaRecordPtr & replicaPtr)7612 void Dbdih::seizeReplicaRec(ReplicaRecordPtr& replicaPtr)
7613 {
7614   replicaPtr.i = cfirstfreeReplica;
7615   ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7616   cfirstfreeReplica = replicaPtr.p->nextReplica;
7617   cnoFreeReplicaRec--;
7618   replicaPtr.p->nextReplica = RNIL;
7619 }//Dbdih::seizeReplicaRec()
7620 
releaseFile(Uint32 fileIndex)7621 void Dbdih::releaseFile(Uint32 fileIndex)
7622 {
7623   FileRecordPtr filePtr;
7624   filePtr.i = fileIndex;
7625   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
7626   filePtr.p->nextFile = cfirstfreeFile;
7627   cfirstfreeFile = filePtr.i;
7628 }//Dbdih::releaseFile()
7629 
7630 
execALTER_TAB_REQ(Signal * signal)7631 void Dbdih::execALTER_TAB_REQ(Signal * signal)
7632 {
7633   AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
7634   const Uint32 senderRef = req->senderRef;
7635   const Uint32 senderData = req->senderData;
7636   const Uint32 changeMask = req->changeMask;
7637   const Uint32 tableId = req->tableId;
7638   const Uint32 tableVersion = req->tableVersion;
7639   const Uint32 gci = req->gci;
7640   AlterTabReq::RequestType requestType =
7641     (AlterTabReq::RequestType) req->requestType;
7642 
7643   TabRecordPtr tabPtr;
7644   tabPtr.i = tableId;
7645   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7646   tabPtr.p->schemaVersion = tableVersion;
7647 
7648   // Request handled successfully
7649   AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
7650   conf->senderRef = reference();
7651   conf->senderData = senderData;
7652   conf->changeMask = changeMask;
7653   conf->tableId = tableId;
7654   conf->tableVersion = tableVersion;
7655   conf->gci = gci;
7656   conf->requestType = requestType;
7657   sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
7658 	     AlterTabConf::SignalLength, JBB);
7659 }
7660 
7661 /*
7662   G E T   N O D E S
7663   **********************=
7664   */
7665 /*****************************************************************************/
7666 /* **********     TRANSACTION  HANDLING  MODULE                  *************/
7667 /*****************************************************************************/
7668 /*
7669   3.8.1    G E T   N O D E S   R E Q U E S T
7670   ******************************************
7671   Asks what nodes should be part of a transaction.
7672 */
execDIGETNODESREQ(Signal * signal)7673 void Dbdih::execDIGETNODESREQ(Signal* signal)
7674 {
7675   const DiGetNodesReq * const req = (DiGetNodesReq *)&signal->theData[0];
7676   FragmentstorePtr fragPtr;
7677   TabRecordPtr tabPtr;
7678   tabPtr.i = req->tableId;
7679   Uint32 hashValue = req->hashValue;
7680   Uint32 ttabFileSize = ctabFileSize;
7681   Uint32 fragId;
7682   DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
7683   TabRecord* regTabDesc = tabRecord;
7684   jamEntry();
7685   ptrCheckGuard(tabPtr, ttabFileSize, regTabDesc);
7686   if (tabPtr.p->method == TabRecord::LINEAR_HASH)
7687   {
7688     jam();
7689     fragId = hashValue & tabPtr.p->mask;
7690     ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
7691     if (fragId < tabPtr.p->hashpointer) {
7692       jam();
7693       fragId = hashValue & ((tabPtr.p->mask << 1) + 1);
7694     }//if
7695   }
7696   else if (tabPtr.p->method == TabRecord::NORMAL_HASH)
7697   {
7698     jam();
7699     fragId= hashValue % tabPtr.p->totalfragments;
7700   }
7701   else
7702   {
7703     jam();
7704     ndbassert(tabPtr.p->method == TabRecord::USER_DEFINED);
7705     fragId= hashValue;
7706     if (fragId >= tabPtr.p->totalfragments)
7707     {
7708       jam();
7709       conf->zero= 1; //Indicate error;
7710       signal->theData[1]= ZUNDEFINED_FRAGMENT_ERROR;
7711       return;
7712     }
7713   }
7714   getFragstore(tabPtr.p, fragId, fragPtr);
7715   Uint32 nodeCount = extractNodeInfo(fragPtr.p, conf->nodes);
7716   Uint32 sig2 = (nodeCount - 1) +
7717     (fragPtr.p->distributionKey << 16);
7718   conf->zero = 0;
7719   conf->reqinfo = sig2;
7720   conf->fragId = fragId;
7721 }//Dbdih::execDIGETNODESREQ()
7722 
extractNodeInfo(const Fragmentstore * fragPtr,Uint32 nodes[])7723 Uint32 Dbdih::extractNodeInfo(const Fragmentstore * fragPtr, Uint32 nodes[])
7724 {
7725   Uint32 nodeCount = 0;
7726   for (Uint32 i = 0; i < fragPtr->fragReplicas; i++) {
7727     jam();
7728     NodeRecordPtr nodePtr;
7729     ndbrequire(i < MAX_REPLICAS);
7730     nodePtr.i = fragPtr->activeNodes[i];
7731     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
7732     if (nodePtr.p->useInTransactions) {
7733       jam();
7734       nodes[nodeCount] = nodePtr.i;
7735       nodeCount++;
7736     }//if
7737   }//for
7738   ndbrequire(nodeCount > 0);
7739   return nodeCount;
7740 }//Dbdih::extractNodeInfo()
7741 
7742 void
getFragstore(TabRecord * tab,Uint32 fragNo,FragmentstorePtr & fragptr)7743 Dbdih::getFragstore(TabRecord * tab,        //In parameter
7744                     Uint32 fragNo,              //In parameter
7745                     FragmentstorePtr & fragptr) //Out parameter
7746 {
7747   FragmentstorePtr fragPtr;
7748   Uint32 chunkNo = fragNo >> LOG_NO_OF_FRAGS_PER_CHUNK;
7749   Uint32 chunkIndex = fragNo & (NO_OF_FRAGS_PER_CHUNK - 1);
7750   Uint32 TfragstoreFileSize = cfragstoreFileSize;
7751   Fragmentstore* TfragStore = fragmentstore;
7752   if (chunkNo < MAX_NDB_NODES) {
7753     fragPtr.i = tab->startFid[chunkNo] + chunkIndex;
7754     ptrCheckGuard(fragPtr, TfragstoreFileSize, TfragStore);
7755     fragptr = fragPtr;
7756     return;
7757   }//if
7758   ndbrequire(false);
7759 }//Dbdih::getFragstore()
7760 
allocFragments(Uint32 noOfFragments,TabRecordPtr tabPtr)7761 void Dbdih::allocFragments(Uint32 noOfFragments, TabRecordPtr tabPtr)
7762 {
7763   FragmentstorePtr fragPtr;
7764   Uint32 noOfChunks = (noOfFragments + (NO_OF_FRAGS_PER_CHUNK - 1)) >> LOG_NO_OF_FRAGS_PER_CHUNK;
7765   ndbrequire(cremainingfrags >= noOfFragments);
7766   for (Uint32 i = 0; i < noOfChunks; i++) {
7767     jam();
7768     Uint32 baseFrag = cfirstfragstore;
7769     tabPtr.p->startFid[i] = baseFrag;
7770     fragPtr.i = baseFrag;
7771     ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
7772     cfirstfragstore = fragPtr.p->nextFragmentChunk;
7773     cremainingfrags -= NO_OF_FRAGS_PER_CHUNK;
7774     for (Uint32 j = 0; j < NO_OF_FRAGS_PER_CHUNK; j++) {
7775       jam();
7776       fragPtr.i = baseFrag + j;
7777       ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
7778       initFragstore(fragPtr);
7779     }//if
7780   }//for
7781   tabPtr.p->noOfFragChunks = noOfChunks;
7782 }//Dbdih::allocFragments()
7783 
releaseFragments(TabRecordPtr tabPtr)7784 void Dbdih::releaseFragments(TabRecordPtr tabPtr)
7785 {
7786   FragmentstorePtr fragPtr;
7787   for (Uint32 i = 0; i < tabPtr.p->noOfFragChunks; i++) {
7788     jam();
7789     Uint32 baseFrag = tabPtr.p->startFid[i];
7790     fragPtr.i = baseFrag;
7791     ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
7792     fragPtr.p->nextFragmentChunk = cfirstfragstore;
7793     cfirstfragstore = baseFrag;
7794     tabPtr.p->startFid[i] = RNIL;
7795     cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
7796   }//for
7797   tabPtr.p->noOfFragChunks = 0;
7798 }//Dbdih::releaseFragments()
7799 
initialiseFragstore()7800 void Dbdih::initialiseFragstore()
7801 {
7802   Uint32 i;
7803   FragmentstorePtr fragPtr;
7804   for (i = 0; i < cfragstoreFileSize; i++) {
7805     fragPtr.i = i;
7806     ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
7807     initFragstore(fragPtr);
7808   }//for
7809   Uint32 noOfChunks = cfragstoreFileSize >> LOG_NO_OF_FRAGS_PER_CHUNK;
7810   fragPtr.i = 0;
7811   cfirstfragstore = RNIL;
7812   cremainingfrags = 0;
7813   for (i = 0; i < noOfChunks; i++) {
7814     refresh_watch_dog();
7815     ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
7816     fragPtr.p->nextFragmentChunk = cfirstfragstore;
7817     cfirstfragstore = fragPtr.i;
7818     fragPtr.i += NO_OF_FRAGS_PER_CHUNK;
7819     cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
7820   }//for
7821 }//Dbdih::initialiseFragstore()
7822 
7823 /*
7824   3.9   V E R I F I C A T I O N
7825   ****************************=
7826   */
7827 /****************************************************************************/
7828 /* **********     VERIFICATION SUB-MODULE                       *************/
7829 /****************************************************************************/
7830 /*
7831   3.9.1     R E C E I V I N G  O F  V E R I F I C A T I O N   R E Q U E S T
7832   *************************************************************************
7833   */
execDIVERIFYREQ(Signal * signal)7834 void Dbdih::execDIVERIFYREQ(Signal* signal)
7835 {
7836 
7837   jamEntry();
7838   if ((getBlockCommit() == false) &&
7839       (cfirstVerifyQueue == RNIL)) {
7840     jam();
7841     /*-----------------------------------------------------------------------*/
7842     // We are not blocked and the verify queue was empty currently so we can
7843     // simply reply back to TC immediately. The method was called with
7844     // EXECUTE_DIRECT so we reply back by setting signal data and returning.
7845     // theData[0] already contains the correct information so
7846     // we need not touch it.
7847     /*-----------------------------------------------------------------------*/
7848     signal->theData[1] = currentgcp;
7849     signal->theData[2] = 0;
7850     return;
7851   }//if
7852   /*-------------------------------------------------------------------------*/
7853   // Since we are blocked we need to put this operation last in the verify
7854   // queue to ensure that operation starts up in the correct order.
7855   /*-------------------------------------------------------------------------*/
7856   ApiConnectRecordPtr tmpApiConnectptr;
7857   ApiConnectRecordPtr localApiConnectptr;
7858 
7859   cverifyQueueCounter++;
7860   localApiConnectptr.i = signal->theData[0];
7861   tmpApiConnectptr.i = clastVerifyQueue;
7862   ptrCheckGuard(localApiConnectptr, capiConnectFileSize, apiConnectRecord);
7863   localApiConnectptr.p->apiGci = cnewgcp;
7864   localApiConnectptr.p->nextApi = RNIL;
7865   clastVerifyQueue = localApiConnectptr.i;
7866   if (tmpApiConnectptr.i == RNIL) {
7867     jam();
7868     cfirstVerifyQueue = localApiConnectptr.i;
7869   } else {
7870     jam();
7871     ptrCheckGuard(tmpApiConnectptr, capiConnectFileSize, apiConnectRecord);
7872     tmpApiConnectptr.p->nextApi = localApiConnectptr.i;
7873   }//if
7874   emptyverificbuffer(signal, false);
7875   signal->theData[2] = 1; // Indicate no immediate return
7876   return;
7877 }//Dbdih::execDIVERIFYREQ()
7878 
execDI_FCOUNTREQ(Signal * signal)7879 void Dbdih::execDI_FCOUNTREQ(Signal* signal)
7880 {
7881   DihFragCountReq * const req = (DihFragCountReq*)signal->getDataPtr();
7882   ConnectRecordPtr connectPtr;
7883   TabRecordPtr tabPtr;
7884   const BlockReference senderRef = signal->senderBlockRef();
7885   const Uint32 senderData = req->m_senderData;
7886   jamEntry();
7887   connectPtr.i = req->m_connectionData;
7888   tabPtr.i = req->m_tableRef;
7889   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7890 
7891   if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
7892   {
7893     DihFragCountRef* ref = (DihFragCountRef*)signal->getDataPtrSend();
7894     //connectPtr.i == RNIL -> question without connect record
7895     if(connectPtr.i == RNIL)
7896       ref->m_connectionData = RNIL;
7897     else
7898     {
7899       jam();
7900       ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7901       ref->m_connectionData = connectPtr.p->userpointer;
7902     }
7903     ref->m_tableRef = tabPtr.i;
7904     ref->m_senderData = senderData;
7905     ref->m_error = DihFragCountRef::ErroneousTableState;
7906     ref->m_tableStatus = tabPtr.p->tabStatus;
7907     sendSignal(senderRef, GSN_DI_FCOUNTREF, signal,
7908                DihFragCountRef::SignalLength, JBB);
7909     return;
7910   }
7911 
7912   if(connectPtr.i != RNIL){
7913     ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7914     if (connectPtr.p->connectState == ConnectRecord::INUSE) {
7915       jam();
7916       DihFragCountConf* conf = (DihFragCountConf*)signal->getDataPtrSend();
7917       conf->m_connectionData = connectPtr.p->userpointer;
7918       conf->m_tableRef = tabPtr.i;
7919       conf->m_senderData = senderData;
7920       conf->m_fragmentCount = tabPtr.p->totalfragments;
7921       conf->m_noOfBackups = tabPtr.p->noOfBackups;
7922       sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTCONF, signal,
7923                  DihFragCountConf::SignalLength, JBB);
7924       return;
7925     }//if
7926     DihFragCountRef* ref = (DihFragCountRef*)signal->getDataPtrSend();
7927     ref->m_connectionData = connectPtr.p->userpointer;
7928     ref->m_tableRef = tabPtr.i;
7929     ref->m_senderData = senderData;
7930     ref->m_error = DihFragCountRef::ErroneousTableState;
7931     ref->m_tableStatus = tabPtr.p->tabStatus;
7932     sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTREF, signal,
7933                DihFragCountRef::SignalLength, JBB);
7934     return;
7935   }//if
7936   DihFragCountConf* conf = (DihFragCountConf*)signal->getDataPtrSend();
7937   //connectPtr.i == RNIL -> question without connect record
7938   conf->m_connectionData = RNIL;
7939   conf->m_tableRef = tabPtr.i;
7940   conf->m_senderData = senderData;
7941   conf->m_fragmentCount = tabPtr.p->totalfragments;
7942   conf->m_noOfBackups = tabPtr.p->noOfBackups;
7943   sendSignal(senderRef, GSN_DI_FCOUNTCONF, signal,
7944              DihFragCountConf::SignalLength, JBB);
7945 }//Dbdih::execDI_FCOUNTREQ()
7946 
execDIGETPRIMREQ(Signal * signal)7947 void Dbdih::execDIGETPRIMREQ(Signal* signal)
7948 {
7949   FragmentstorePtr fragPtr;
7950   ConnectRecordPtr connectPtr;
7951   TabRecordPtr tabPtr;
7952   jamEntry();
7953   Uint32 passThrough = signal->theData[1];
7954   tabPtr.i = signal->theData[2];
7955   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7956   if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType)) {
7957     jam();
7958     tabPtr.i = tabPtr.p->primaryTableId;
7959     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7960   }
7961   Uint32 fragId = signal->theData[3];
7962 
7963   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
7964   connectPtr.i = signal->theData[0];
7965   if(connectPtr.i != RNIL)
7966   {
7967     jam();
7968     ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7969     signal->theData[0] = connectPtr.p->userpointer;
7970   }
7971   else
7972   {
7973     jam();
7974     signal->theData[0] = RNIL;
7975   }
7976 
7977   Uint32 nodes[MAX_REPLICAS];
7978   getFragstore(tabPtr.p, fragId, fragPtr);
7979   Uint32 count = extractNodeInfo(fragPtr.p, nodes);
7980 
7981   signal->theData[1] = passThrough;
7982   signal->theData[2] = nodes[0];
7983   signal->theData[3] = nodes[1];
7984   signal->theData[4] = nodes[2];
7985   signal->theData[5] = nodes[3];
7986   signal->theData[6] = count;
7987   signal->theData[7] = tabPtr.i;
7988   signal->theData[8] = fragId;
7989 
7990   const BlockReference senderRef = signal->senderBlockRef();
7991   sendSignal(senderRef, GSN_DIGETPRIMCONF, signal, 9, JBB);
7992 }//Dbdih::execDIGETPRIMREQ()
7993 
7994 /****************************************************************************/
7995 /* **********     GLOBAL-CHECK-POINT HANDLING  MODULE           *************/
7996 /****************************************************************************/
7997 /*
7998   3.10   G L O B A L  C H E C K P O I N T ( IN  M A S T E R  R O L E)
7999   *******************************************************************
8000   */
checkGcpStopLab(Signal * signal)8001 void Dbdih::checkGcpStopLab(Signal* signal)
8002 {
8003   Uint32 tgcpStatus;
8004 
8005   tgcpStatus = cgcpStatus;
8006   if (tgcpStatus == coldGcpStatus) {
8007     jam();
8008     if (coldGcpId == cnewgcp) {
8009       jam();
8010       if (cgcpStatus != GCP_READY) {
8011         jam();
8012         cgcpSameCounter++;
8013         if (cgcpSameCounter == 1200) {
8014           jam();
8015 #ifdef VM_TRACE
8016           g_eventLogger.error("System crash due to GCP Stop in state = %u",
8017                               (Uint32) cgcpStatus);
8018 #endif
8019           crashSystemAtGcpStop(signal, false);
8020           return;
8021         }//if
8022       } else {
8023         jam();
8024         if (cgcpOrderBlocked == 0) {
8025           jam();
8026           cgcpSameCounter++;
8027           if (cgcpSameCounter == 1200) {
8028             jam();
8029 #ifdef VM_TRACE
8030             g_eventLogger.error("System crash due to GCP Stop in state = %u",
8031                                 (Uint32) cgcpStatus);
8032 #endif
8033 	    crashSystemAtGcpStop(signal, false);
8034             return;
8035           }//if
8036         } else {
8037           jam();
8038           cgcpSameCounter = 0;
8039         }//if
8040       }//if
8041     } else {
8042       jam();
8043       cgcpSameCounter = 0;
8044     }//if
8045   } else {
8046     jam();
8047     cgcpSameCounter = 0;
8048   }//if
8049   signal->theData[0] = DihContinueB::ZCHECK_GCP_STOP;
8050   signal->theData[1] = coldGcpStatus;
8051   signal->theData[2] = cgcpStatus;
8052   signal->theData[3] = coldGcpId;
8053   signal->theData[4] = cnewgcp;
8054   signal->theData[5] = cgcpSameCounter;
8055   sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 6);
8056   coldGcpStatus = cgcpStatus;
8057   coldGcpId = cnewgcp;
8058   return;
8059 }//Dbdih::checkGcpStopLab()
8060 
startGcpLab(Signal * signal,Uint32 aWaitTime)8061 void Dbdih::startGcpLab(Signal* signal, Uint32 aWaitTime)
8062 {
8063   if ((cgcpOrderBlocked == 1) ||
8064       (c_nodeStartMaster.blockGcp == true) ||
8065       (cfirstVerifyQueue != RNIL)) {
8066     /*************************************************************************/
8067     // 1: Global Checkpoint has been stopped by management command
8068     // 2: Global Checkpoint is blocked by node recovery activity
8069     // 3: Previous global checkpoint is not yet completed.
8070     // All this means that global checkpoint cannot start now.
8071     /*************************************************************************/
8072     jam();
8073     cgcpStartCounter++;
8074     signal->theData[0] = DihContinueB::ZSTART_GCP;
8075     signal->theData[1] = aWaitTime > 100 ? (aWaitTime - 100) : 0;
8076     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
8077     return;
8078   }//if
8079   if (cstartGcpNow == false && aWaitTime > 100){
8080     /*************************************************************************/
8081     // We still have more than 100 milliseconds before we start the next and
8082     // nobody has ordered immediate start of a global checkpoint.
8083     // During initial start we will use continuos global checkpoints to
8084     // speed it up since we need to complete a global checkpoint after
8085     // inserting a lot of records.
8086     /*************************************************************************/
8087     jam();
8088     cgcpStartCounter++;
8089     signal->theData[0] = DihContinueB::ZSTART_GCP;
8090     signal->theData[1] = (aWaitTime - 100);
8091     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
8092     return;
8093   }//if
8094   cgcpStartCounter = 0;
8095   cstartGcpNow = false;
8096   /***************************************************************************/
8097   // Report the event that a global checkpoint has started.
8098   /***************************************************************************/
8099   signal->theData[0] = NDB_LE_GlobalCheckpointStarted; //Event type
8100   signal->theData[1] = cnewgcp;
8101   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
8102 
8103   CRASH_INSERTION(7000);
8104   cnewgcp++;
8105   signal->setTrace(TestOrd::TraceGlobalCheckpoint);
8106   sendLoopMacro(GCP_PREPARE, sendGCP_PREPARE);
8107   cgcpStatus = GCP_PREPARE_SENT;
8108 }//Dbdih::startGcpLab()
8109 
execGCP_PREPARECONF(Signal * signal)8110 void Dbdih::execGCP_PREPARECONF(Signal* signal)
8111 {
8112   jamEntry();
8113   Uint32 senderNodeId = signal->theData[0];
8114   Uint32 gci = signal->theData[1];
8115   ndbrequire(gci == cnewgcp);
8116   receiveLoopMacro(GCP_PREPARE, senderNodeId);
8117   //-------------------------------------------------------------
8118   // We have now received all replies. We are ready to continue
8119   // with committing the global checkpoint.
8120   //-------------------------------------------------------------
8121   gcpcommitreqLab(signal);
8122 }//Dbdih::execGCP_PREPARECONF()
8123 
gcpcommitreqLab(Signal * signal)8124 void Dbdih::gcpcommitreqLab(Signal* signal)
8125 {
8126   CRASH_INSERTION(7001);
8127   sendLoopMacro(GCP_COMMIT, sendGCP_COMMIT);
8128   cgcpStatus = GCP_COMMIT_SENT;
8129   return;
8130 }//Dbdih::gcpcommitreqLab()
8131 
execGCP_NODEFINISH(Signal * signal)8132 void Dbdih::execGCP_NODEFINISH(Signal* signal)
8133 {
8134   jamEntry();
8135   const Uint32 senderNodeId = signal->theData[0];
8136   const Uint32 gci = signal->theData[1];
8137   const Uint32 failureNr = signal->theData[2];
8138   if (!isMaster()) {
8139     jam();
8140     ndbrequire(failureNr > cfailurenr);
8141     //-------------------------------------------------------------
8142     // Another node thinks we are master. This could happen when he
8143     // has heard of a node failure which I have not heard of. Ignore
8144     // signal in this case since we will discover it by sending
8145     // MASTER_GCPREQ to the node.
8146     //-------------------------------------------------------------
8147     return;
8148   } else if (cmasterState == MASTER_TAKE_OVER_GCP) {
8149     jam();
8150     //-------------------------------------------------------------
8151     // We are currently taking over as master. Ignore
8152     // signal in this case since we will discover it in reception of
8153     // MASTER_GCPCONF.
8154     //-------------------------------------------------------------
8155     return;
8156   } else {
8157     ndbrequire(cmasterState == MASTER_ACTIVE);
8158   }//if
8159   ndbrequire(gci == coldgcp);
8160   receiveLoopMacro(GCP_COMMIT, senderNodeId);
8161   //-------------------------------------------------------------
8162   // We have now received all replies. We are ready to continue
8163   // with saving the global checkpoint to disk.
8164   //-------------------------------------------------------------
8165   CRASH_INSERTION(7002);
8166   gcpsavereqLab(signal);
8167   return;
8168 }//Dbdih::execGCP_NODEFINISH()
8169 
gcpsavereqLab(Signal * signal)8170 void Dbdih::gcpsavereqLab(Signal* signal)
8171 {
8172   sendLoopMacro(GCP_SAVEREQ, sendGCP_SAVEREQ);
8173   cgcpStatus = GCP_NODE_FINISHED;
8174 }//Dbdih::gcpsavereqLab()
8175 
execGCP_SAVECONF(Signal * signal)8176 void Dbdih::execGCP_SAVECONF(Signal* signal)
8177 {
8178   jamEntry();
8179   const GCPSaveConf * const saveConf = (GCPSaveConf*)&signal->theData[0];
8180   ndbrequire(saveConf->gci == coldgcp);
8181   ndbrequire(saveConf->nodeId == saveConf->dihPtr);
8182   SYSFILE->lastCompletedGCI[saveConf->nodeId] = saveConf->gci;
8183   GCP_SAVEhandling(signal, saveConf->nodeId);
8184 }//Dbdih::execGCP_SAVECONF()
8185 
execGCP_SAVEREF(Signal * signal)8186 void Dbdih::execGCP_SAVEREF(Signal* signal)
8187 {
8188   jamEntry();
8189   const GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
8190   ndbrequire(saveRef->gci == coldgcp);
8191   ndbrequire(saveRef->nodeId == saveRef->dihPtr);
8192   /**
8193    * Only allow reason not to save
8194    */
8195   ndbrequire(saveRef->errorCode == GCPSaveRef::NodeShutdownInProgress ||
8196 	     saveRef->errorCode == GCPSaveRef::FakedSignalDueToNodeFailure ||
8197 	     saveRef->errorCode == GCPSaveRef::NodeRestartInProgress);
8198   GCP_SAVEhandling(signal, saveRef->nodeId);
8199 }//Dbdih::execGCP_SAVEREF()
8200 
GCP_SAVEhandling(Signal * signal,Uint32 nodeId)8201 void Dbdih::GCP_SAVEhandling(Signal* signal, Uint32 nodeId)
8202 {
8203   receiveLoopMacro(GCP_SAVEREQ, nodeId);
8204   /*-------------------------------------------------------------------------*/
8205   // All nodes have replied. We are ready to update the system file.
8206   /*-------------------------------------------------------------------------*/
8207   cgcpStatus = GCP_SAVE_LQH_FINISHED;
8208   CRASH_INSERTION(7003);
8209   checkToCopy();
8210   /**------------------------------------------------------------------------
8211    * SET NEW RECOVERABLE GCI. ALSO RESET RESTART COUNTER TO ZERO.
8212    * THIS INDICATES THAT THE SYSTEM HAS BEEN RECOVERED AND SURVIVED AT
8213    * LEAST ONE GLOBAL CHECKPOINT PERIOD. WE WILL USE THIS PARAMETER TO
8214    * SET BACK THE RESTART GCI IF WE ENCOUNTER MORE THAN ONE UNSUCCESSFUL
8215    * RESTART.
8216    *------------------------------------------------------------------------*/
8217   SYSFILE->newestRestorableGCI = coldgcp;
8218   if(Sysfile::getInitialStartOngoing(SYSFILE->systemRestartBits) &&
8219      getNodeState().startLevel == NodeState::SL_STARTED){
8220     jam();
8221 #if 0
8222     g_eventLogger.info("Dbdih: Clearing initial start ongoing");
8223 #endif
8224     Sysfile::clearInitialStartOngoing(SYSFILE->systemRestartBits);
8225   }
8226   copyGciLab(signal, CopyGCIReq::GLOBAL_CHECKPOINT);
8227 }//Dbdih::GCP_SAVEhandling()
8228 
8229 /*
8230   3.11   G L O B A L  C H E C K P O I N T (N O T - M A S T E R)
8231   *************************************************************
8232   */
execGCP_PREPARE(Signal * signal)8233 void Dbdih::execGCP_PREPARE(Signal* signal)
8234 {
8235   jamEntry();
8236   CRASH_INSERTION(7005);
8237 
8238   if (ERROR_INSERTED(7030))
8239   {
8240     cgckptflag = true;
8241     g_eventLogger.info("Delayed GCP_PREPARE 5s");
8242     sendSignalWithDelay(reference(), GSN_GCP_PREPARE, signal, 5000,
8243 			signal->getLength());
8244     return;
8245   }
8246 
8247   Uint32 masterNodeId = signal->theData[0];
8248   Uint32 gci = signal->theData[1];
8249   BlockReference retRef = calcDihBlockRef(masterNodeId);
8250 
8251   ndbrequire (cmasterdihref == retRef);
8252   ndbrequire (cgcpParticipantState == GCP_PARTICIPANT_READY);
8253   ndbrequire (gci == (currentgcp + 1));
8254 
8255   cgckptflag = true;
8256   cgcpParticipantState = GCP_PARTICIPANT_PREPARE_RECEIVED;
8257   cnewgcp = gci;
8258 
8259   if (ERROR_INSERTED(7031))
8260   {
8261     g_eventLogger.info("Crashing delayed in GCP_PREPARE 3s");
8262     signal->theData[0] = 9999;
8263     sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 3000, 1);
8264     return;
8265   }
8266 
8267   signal->theData[0] = cownNodeId;
8268   signal->theData[1] = gci;
8269   sendSignal(retRef, GSN_GCP_PREPARECONF, signal, 2, JBA);
8270   return;
8271 }//Dbdih::execGCP_PREPARE()
8272 
execGCP_COMMIT(Signal * signal)8273 void Dbdih::execGCP_COMMIT(Signal* signal)
8274 {
8275   jamEntry();
8276   CRASH_INSERTION(7006);
8277   Uint32 masterNodeId = signal->theData[0];
8278   Uint32 gci = signal->theData[1];
8279 
8280   ndbrequire(gci == (currentgcp + 1));
8281   ndbrequire(masterNodeId = cmasterNodeId);
8282   ndbrequire(cgcpParticipantState == GCP_PARTICIPANT_PREPARE_RECEIVED);
8283 
8284   coldgcp = currentgcp;
8285   currentgcp = cnewgcp;
8286   cgckptflag = false;
8287   emptyverificbuffer(signal, true);
8288   cgcpParticipantState = GCP_PARTICIPANT_COMMIT_RECEIVED;
8289   signal->theData[0] = calcDihBlockRef(masterNodeId);
8290   signal->theData[1] = coldgcp;
8291   sendSignal(clocaltcblockref, GSN_GCP_NOMORETRANS, signal, 2, JBB);
8292   return;
8293 }//Dbdih::execGCP_COMMIT()
8294 
execGCP_TCFINISHED(Signal * signal)8295 void Dbdih::execGCP_TCFINISHED(Signal* signal)
8296 {
8297   jamEntry();
8298   CRASH_INSERTION(7007);
8299   Uint32 retRef = signal->theData[0];
8300   Uint32 gci = signal->theData[1];
8301   ndbrequire(gci == coldgcp);
8302 
8303   if (ERROR_INSERTED(7181) || ERROR_INSERTED(7182))
8304   {
8305     c_error_7181_ref = retRef; // Save ref
8306     ndbout_c("killing %d", refToNode(cmasterdihref));
8307     signal->theData[0] = 9999;
8308     sendSignal(numberToRef(CMVMI, refToNode(cmasterdihref)),
8309 	       GSN_NDB_TAMPER, signal, 1, JBB);
8310     return;
8311   }
8312 
8313   cgcpParticipantState = GCP_PARTICIPANT_TC_FINISHED;
8314   signal->theData[0] = cownNodeId;
8315   signal->theData[1] = coldgcp;
8316   signal->theData[2] = cfailurenr;
8317   sendSignal(retRef, GSN_GCP_NODEFINISH, signal, 3, JBB);
8318 }//Dbdih::execGCP_TCFINISHED()
8319 
8320 /*****************************************************************************/
8321 //******     RECEIVING   TAMPER   REQUEST   FROM    NDBAPI             ******
8322 /*****************************************************************************/
execDIHNDBTAMPER(Signal * signal)8323 void Dbdih::execDIHNDBTAMPER(Signal* signal)
8324 {
8325   jamEntry();
8326   Uint32 tcgcpblocked = signal->theData[0];
8327   /* ACTION TO BE TAKEN BY DIH */
8328   Uint32 tuserpointer = signal->theData[1];
8329   BlockReference tuserblockref = signal->theData[2];
8330   switch (tcgcpblocked) {
8331   case 1:
8332     jam();
8333     if (isMaster()) {
8334       jam();
8335       cgcpOrderBlocked = 1;
8336     } else {
8337       jam();
8338       /* TRANSFER THE REQUEST */
8339       /* TO MASTER*/
8340       signal->theData[0] = tcgcpblocked;
8341       signal->theData[1] = tuserpointer;
8342       signal->theData[2] = tuserblockref;
8343       sendSignal(cmasterdihref, GSN_DIHNDBTAMPER, signal, 3, JBB);
8344     }//if
8345     break;
8346   case 2:
8347     jam();
8348     if (isMaster()) {
8349       jam();
8350       cgcpOrderBlocked = 0;
8351     } else {
8352       jam();
8353       /* TRANSFER THE REQUEST */
8354       /* TO MASTER*/
8355       signal->theData[0] = tcgcpblocked;
8356       signal->theData[1] = tuserpointer;
8357       signal->theData[2] = tuserblockref;
8358       sendSignal(cmasterdihref, GSN_DIHNDBTAMPER, signal, 3, JBB);
8359     }//if
8360     break;
8361   case 3:
8362     ndbrequire(false);
8363     return;
8364     break;
8365   case 4:
8366     jam();
8367     signal->theData[0] = tuserpointer;
8368     signal->theData[1] = crestartGci;
8369     sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 2, JBB);
8370     break;
8371 #ifdef ERROR_INSERT
8372   case 5:
8373     jam();
8374     if(tuserpointer == 0)
8375     {
8376       jam();
8377       signal->theData[0] = 0;
8378       sendSignal(QMGR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8379       sendSignal(NDBCNTR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8380       sendSignal(NDBFS_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8381       sendSignal(DBACC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8382       sendSignal(DBTUP_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8383       sendSignal(DBLQH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8384       sendSignal(DBDICT_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8385       sendSignal(DBDIH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8386       sendSignal(DBTC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8387       sendSignal(CMVMI_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8388       return;
8389     }
8390     /*----------------------------------------------------------------------*/
8391     // Insert errors.
8392     /*----------------------------------------------------------------------*/
8393     if (tuserpointer < 1000) {
8394       /*--------------------------------------------------------------------*/
8395       // Insert errors into QMGR.
8396       /*--------------------------------------------------------------------*/
8397       jam();
8398       tuserblockref = QMGR_REF;
8399     } else if (tuserpointer < 2000) {
8400       /*--------------------------------------------------------------------*/
8401       // Insert errors into NDBCNTR.
8402       /*--------------------------------------------------------------------*/
8403       jam();
8404       tuserblockref = NDBCNTR_REF;
8405     } else if (tuserpointer < 3000) {
8406       /*--------------------------------------------------------------------*/
8407       // Insert errors into NDBFS.
8408       /*--------------------------------------------------------------------*/
8409       jam();
8410       tuserblockref = NDBFS_REF;
8411     } else if (tuserpointer < 4000) {
8412       /*--------------------------------------------------------------------*/
8413       // Insert errors into DBACC.
8414       /*--------------------------------------------------------------------*/
8415       jam();
8416       tuserblockref = DBACC_REF;
8417     } else if (tuserpointer < 5000) {
8418       /*--------------------------------------------------------------------*/
8419       // Insert errors into DBTUP.
8420       /*--------------------------------------------------------------------*/
8421       jam();
8422       tuserblockref = DBTUP_REF;
8423     } else if (tuserpointer < 6000) {
8424       /*---------------------------------------------------------------------*/
8425       // Insert errors into DBLQH.
8426       /*---------------------------------------------------------------------*/
8427       jam();
8428       tuserblockref = DBLQH_REF;
8429     } else if (tuserpointer < 7000) {
8430       /*---------------------------------------------------------------------*/
8431       // Insert errors into DBDICT.
8432       /*---------------------------------------------------------------------*/
8433       jam();
8434       tuserblockref = DBDICT_REF;
8435     } else if (tuserpointer < 8000) {
8436       /*---------------------------------------------------------------------*/
8437       // Insert errors into DBDIH.
8438       /*--------------------------------------------------------------------*/
8439       jam();
8440       tuserblockref = DBDIH_REF;
8441     } else if (tuserpointer < 9000) {
8442       /*--------------------------------------------------------------------*/
8443       // Insert errors into DBTC.
8444       /*--------------------------------------------------------------------*/
8445       jam();
8446       tuserblockref = DBTC_REF;
8447     } else if (tuserpointer < 10000) {
8448       /*--------------------------------------------------------------------*/
8449       // Insert errors into CMVMI.
8450       /*--------------------------------------------------------------------*/
8451       jam();
8452       tuserblockref = CMVMI_REF;
8453     } else if (tuserpointer < 11000) {
8454       jam();
8455       tuserblockref = BACKUP_REF;
8456     } else if (tuserpointer < 12000) {
8457       // DBUTIL_REF ?
8458       jam();
8459     } else if (tuserpointer < 13000) {
8460       jam();
8461       tuserblockref = DBTUX_REF;
8462     } else if (tuserpointer < 14000) {
8463       jam();
8464       tuserblockref = SUMA_REF;
8465     } else if (tuserpointer < 15000) {
8466       jam();
8467       tuserblockref = DBDICT_REF;
8468     } else if (tuserpointer < 16000) {
8469       jam();
8470       tuserblockref = LGMAN_REF;
8471     } else if (tuserpointer < 17000) {
8472       jam();
8473       tuserblockref = TSMAN_REF;
8474     } else if (tuserpointer < 30000) {
8475       /*--------------------------------------------------------------------*/
8476       // Ignore errors in the 20000-range.
8477       /*--------------------------------------------------------------------*/
8478       jam();
8479       return;
8480     } else if (tuserpointer < 40000) {
8481       jam();
8482       /*--------------------------------------------------------------------*/
8483       // Redirect errors to master DIH in the 30000-range.
8484       /*--------------------------------------------------------------------*/
8485       tuserblockref = cmasterdihref;
8486       tuserpointer -= 30000;
8487       signal->theData[0] = 5;
8488       signal->theData[1] = tuserpointer;
8489       signal->theData[2] = tuserblockref;
8490       sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 3, JBB);
8491       return;
8492     } else if (tuserpointer < 50000) {
8493       NodeRecordPtr localNodeptr;
8494       Uint32 Tfound = 0;
8495       jam();
8496       /*--------------------------------------------------------------------*/
8497       // Redirect errors to non-master DIH in the 40000-range.
8498       /*--------------------------------------------------------------------*/
8499       tuserpointer -= 40000;
8500       for (localNodeptr.i = 1;
8501            localNodeptr.i < MAX_NDB_NODES;
8502            localNodeptr.i++) {
8503         jam();
8504         ptrAss(localNodeptr, nodeRecord);
8505         if ((localNodeptr.p->nodeStatus == NodeRecord::ALIVE) &&
8506             (localNodeptr.i != cmasterNodeId)) {
8507           jam();
8508           tuserblockref = calcDihBlockRef(localNodeptr.i);
8509           Tfound = 1;
8510           break;
8511         }//if
8512       }//for
8513       if (Tfound == 0) {
8514         jam();
8515 	/*-------------------------------------------------------------------*/
8516 	// Ignore since no non-master node existed.
8517 	/*-------------------------------------------------------------------*/
8518         return;
8519       }//if
8520       signal->theData[0] = 5;
8521       signal->theData[1] = tuserpointer;
8522       signal->theData[2] = tuserblockref;
8523       sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 3, JBB);
8524       return;
8525     } else {
8526       jam();
8527       return;
8528     }//if
8529     signal->theData[0] = tuserpointer;
8530     if (tuserpointer != 0) {
8531       sendSignal(tuserblockref, GSN_NDB_TAMPER, signal, 1, JBB);
8532     } else {
8533       sendSignal(QMGR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8534       sendSignal(NDBCNTR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8535       sendSignal(NDBFS_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8536       sendSignal(DBACC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8537       sendSignal(DBTUP_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8538       sendSignal(DBLQH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8539       sendSignal(DBDICT_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8540       sendSignal(DBDIH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8541       sendSignal(DBTC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8542       sendSignal(CMVMI_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8543     }//if
8544     break;
8545 #endif
8546   default:
8547     ndbrequire(false);
8548     break;
8549   }//switch
8550   return;
8551 }//Dbdih::execDIHNDBTAMPER()
8552 
8553 /*****************************************************************************/
8554 /* **********     FILE HANDLING MODULE                           *************/
8555 /*****************************************************************************/
copyGciLab(Signal * signal,CopyGCIReq::CopyReason reason)8556 void Dbdih::copyGciLab(Signal* signal, CopyGCIReq::CopyReason reason)
8557 {
8558   if(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE){
8559     /**
8560      * There can currently only be one waiting
8561      */
8562     ndbrequire(c_copyGCIMaster.m_waiting == CopyGCIReq::IDLE);
8563     c_copyGCIMaster.m_waiting = reason;
8564     return;
8565   }
8566   c_copyGCIMaster.m_copyReason = reason;
8567   sendLoopMacro(COPY_GCIREQ, sendCOPY_GCIREQ);
8568 
8569 }//Dbdih::copyGciLab()
8570 
8571 /* ------------------------------------------------------------------------- */
8572 /* COPY_GCICONF                           RESPONSE TO COPY_GCIREQ            */
8573 /* ------------------------------------------------------------------------- */
execCOPY_GCICONF(Signal * signal)8574 void Dbdih::execCOPY_GCICONF(Signal* signal)
8575 {
8576   jamEntry();
8577   NodeRecordPtr senderNodePtr;
8578   senderNodePtr.i = signal->theData[0];
8579   receiveLoopMacro(COPY_GCIREQ, senderNodePtr.i);
8580 
8581   CopyGCIReq::CopyReason waiting = c_copyGCIMaster.m_waiting;
8582   CopyGCIReq::CopyReason current = c_copyGCIMaster.m_copyReason;
8583 
8584   c_copyGCIMaster.m_copyReason = CopyGCIReq::IDLE;
8585   c_copyGCIMaster.m_waiting = CopyGCIReq::IDLE;
8586 
8587   bool ok = false;
8588   switch(current){
8589   case CopyGCIReq::RESTART:{
8590     ok = true;
8591     jam();
8592     DictStartReq * req = (DictStartReq*)&signal->theData[0];
8593     req->restartGci = SYSFILE->newestRestorableGCI;
8594     req->senderRef = reference();
8595     sendSignal(cdictblockref, GSN_DICTSTARTREQ,
8596                signal, DictStartReq::SignalLength, JBB);
8597     break;
8598   }
8599   case CopyGCIReq::LOCAL_CHECKPOINT:{
8600     ok = true;
8601     jam();
8602     startLcpRoundLab(signal);
8603     break;
8604   }
8605   case CopyGCIReq::GLOBAL_CHECKPOINT:
8606     ok = true;
8607     jam();
8608     checkToCopyCompleted(signal);
8609 
8610     /************************************************************************/
8611     // Report the event that a global checkpoint has completed.
8612     /************************************************************************/
8613     signal->setTrace(0);
8614     signal->theData[0] = NDB_LE_GlobalCheckpointCompleted; //Event type
8615     signal->theData[1] = coldgcp;
8616     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
8617 
8618     c_newest_restorable_gci = coldgcp;
8619 
8620     CRASH_INSERTION(7004);
8621     emptyWaitGCPMasterQueue(signal);
8622     cgcpStatus = GCP_READY;
8623     signal->theData[0] = DihContinueB::ZSTART_GCP;
8624     signal->theData[1] = cgcpDelay;
8625     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
8626     if (c_nodeStartMaster.blockGcp == true) {
8627       jam();
8628       /* ------------------------------------------------------------------ */
8629       /*  A NEW NODE WANTS IN AND WE MUST ALLOW IT TO COME IN NOW SINCE THE */
8630       /*       GCP IS COMPLETED.                                            */
8631       /* ------------------------------------------------------------------ */
8632       gcpBlockedLab(signal);
8633     }//if
8634     break;
8635   case CopyGCIReq::INITIAL_START_COMPLETED:
8636     ok = true;
8637     jam();
8638     initialStartCompletedLab(signal);
8639     break;
8640   case CopyGCIReq::IDLE:
8641     ok = false;
8642     jam();
8643   }
8644   ndbrequire(ok);
8645 
8646   /**
8647    * Pop queue
8648    */
8649   if(waiting != CopyGCIReq::IDLE){
8650     c_copyGCIMaster.m_copyReason = waiting;
8651     signal->theData[0] = DihContinueB::ZCOPY_GCI;
8652     signal->theData[1] = waiting;
8653     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
8654   }
8655 }//Dbdih::execCOPY_GCICONF()
8656 
invalidateLcpInfoAfterSr()8657 void Dbdih::invalidateLcpInfoAfterSr()
8658 {
8659   NodeRecordPtr nodePtr;
8660   SYSFILE->latestLCP_ID--;
8661   Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
8662   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
8663     jam();
8664     ptrAss(nodePtr, nodeRecord);
8665     if (!NdbNodeBitmask::get(SYSFILE->lcpActive, nodePtr.i)){
8666       jam();
8667       /* ------------------------------------------------------------------- */
8668       // The node was not active in the local checkpoint.
8669       // To avoid that we step the active status too fast to not
8670       // active we step back one step from Sysfile::NS_ActiveMissed_x.
8671       /* ------------------------------------------------------------------- */
8672       switch (nodePtr.p->activeStatus) {
8673       case Sysfile::NS_Active:
8674 	/* ----------------------------------------------------------------- */
8675 	// When not active in ongoing LCP and still active is a contradiction.
8676 	/* ----------------------------------------------------------------- */
8677         ndbrequire(false);
8678       case Sysfile::NS_ActiveMissed_1:
8679         jam();
8680         nodePtr.p->activeStatus = Sysfile::NS_Active;
8681         break;
8682       case Sysfile::NS_ActiveMissed_2:
8683         jam();
8684         nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
8685         break;
8686       default:
8687         jam();
8688         break;
8689       }//switch
8690     }//if
8691   }//for
8692   setNodeRestartInfoBits();
8693 }//Dbdih::invalidateLcpInfoAfterSr()
8694 
8695 /* ------------------------------------------------------------------------- */
8696 /*       THE NEXT STEP IS TO WRITE THE FILE.                                 */
8697 /* ------------------------------------------------------------------------- */
openingCopyGciSkipInitLab(Signal * signal,FileRecordPtr filePtr)8698 void Dbdih::openingCopyGciSkipInitLab(Signal* signal, FileRecordPtr filePtr)
8699 {
8700   writeRestorableGci(signal, filePtr);
8701   filePtr.p->reqStatus = FileRecord::WRITING_COPY_GCI;
8702   return;
8703 }//Dbdih::openingCopyGciSkipInitLab()
8704 
writingCopyGciLab(Signal * signal,FileRecordPtr filePtr)8705 void Dbdih::writingCopyGciLab(Signal* signal, FileRecordPtr filePtr)
8706 {
8707   /* ----------------------------------------------------------------------- */
8708   /*     WE HAVE NOW WRITTEN THIS FILE. WRITE ALSO NEXT FILE IF THIS IS NOT  */
8709   /*     ALREADY THE LAST.                                                   */
8710   /* ----------------------------------------------------------------------- */
8711   filePtr.p->reqStatus = FileRecord::IDLE;
8712   if (filePtr.i == crestartInfoFile[0]) {
8713     jam();
8714     filePtr.i = crestartInfoFile[1];
8715     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
8716     if (filePtr.p->fileStatus == FileRecord::OPEN) {
8717       jam();
8718       openingCopyGciSkipInitLab(signal, filePtr);
8719       return;
8720     }//if
8721     openFileRw(signal, filePtr);
8722     filePtr.p->reqStatus = FileRecord::OPENING_COPY_GCI;
8723     return;
8724   }//if
8725   /* ----------------------------------------------------------------------- */
8726   /*     WE HAVE COMPLETED WRITING BOTH FILES SUCCESSFULLY. NOW REPORT OUR   */
8727   /*     SUCCESS TO THE MASTER DIH. BUT FIRST WE NEED TO RESET A NUMBER OF   */
8728   /*     VARIABLES USED BY THE LOCAL CHECKPOINT PROCESS (ONLY IF TRIGGERED   */
8729   /*     BY LOCAL CHECKPOINT PROCESS.                                        */
8730   /* ----------------------------------------------------------------------- */
8731   CopyGCIReq::CopyReason reason = c_copyGCISlave.m_copyReason;
8732 
8733   if (reason == CopyGCIReq::GLOBAL_CHECKPOINT) {
8734     jam();
8735     cgcpParticipantState = GCP_PARTICIPANT_READY;
8736 
8737     SubGcpCompleteRep * const rep = (SubGcpCompleteRep*)signal->getDataPtr();
8738     rep->gci = coldgcp;
8739     sendSignal(SUMA_REF, GSN_SUB_GCP_COMPLETE_REP, signal,
8740 	       SubGcpCompleteRep::SignalLength, JBB);
8741 
8742     EXECUTE_DIRECT(LGMAN, GSN_SUB_GCP_COMPLETE_REP, signal,
8743 		   SubGcpCompleteRep::SignalLength);
8744     jamEntry();
8745   }
8746 
8747   jam();
8748   c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
8749 
8750   if(c_copyGCISlave.m_senderRef == cmasterdihref){
8751     jam();
8752     /**
8753      * Only if same master
8754      */
8755     signal->theData[0] = c_copyGCISlave.m_senderData;
8756     sendSignal(c_copyGCISlave.m_senderRef, GSN_COPY_GCICONF, signal, 1, JBB);
8757 
8758   }
8759   return;
8760 }//Dbdih::writingCopyGciLab()
8761 
execSTART_LCP_REQ(Signal * signal)8762 void Dbdih::execSTART_LCP_REQ(Signal* signal){
8763   StartLcpReq * req = (StartLcpReq*)signal->getDataPtr();
8764 
8765   CRASH_INSERTION2(7021, isMaster());
8766   CRASH_INSERTION2(7022, !isMaster());
8767 
8768   ndbrequire(c_lcpState.m_masterLcpDihRef = req->senderRef);
8769   c_lcpState.m_participatingDIH = req->participatingDIH;
8770   c_lcpState.m_participatingLQH = req->participatingLQH;
8771 
8772   c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH = req->participatingLQH;
8773   if(isMaster()){
8774     jam();
8775     ndbrequire(isActiveMaster());
8776     c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH = req->participatingDIH;
8777 
8778   } else {
8779     c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.clearWaitingFor();
8780   }
8781 
8782   c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received = false;
8783 
8784   c_lcpState.setLcpStatus(LCP_INIT_TABLES, __LINE__);
8785 
8786   signal->theData[0] = DihContinueB::ZINIT_LCP;
8787   signal->theData[1] = c_lcpState.m_masterLcpDihRef;
8788   signal->theData[2] = 0;
8789   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
8790 }
8791 
initLcpLab(Signal * signal,Uint32 senderRef,Uint32 tableId)8792 void Dbdih::initLcpLab(Signal* signal, Uint32 senderRef, Uint32 tableId)
8793 {
8794   TabRecordPtr tabPtr;
8795   tabPtr.i = tableId;
8796 
8797   if(c_lcpState.m_masterLcpDihRef != senderRef){
8798     jam();
8799     /**
8800      * This is LCP master takeover
8801      */
8802 #ifdef VM_TRACE
8803     g_eventLogger.info("initLcpLab aborted due to LCP master takeover - 1");
8804 #endif
8805     c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
8806     sendMASTER_LCPCONF(signal);
8807     return;
8808   }
8809 
8810   if(c_lcpState.m_masterLcpDihRef != cmasterdihref){
8811     jam();
8812     /**
8813      * Master take over but has not yet received MASTER_LCPREQ
8814      */
8815 #ifdef VM_TRACE
8816     g_eventLogger.info("initLcpLab aborted due to LCP master takeover - 2");
8817 #endif
8818     return;
8819   }
8820 
8821   //const Uint32 lcpId = SYSFILE->latestLCP_ID;
8822 
8823   for(; tabPtr.i < ctabFileSize; tabPtr.i++){
8824 
8825     ptrAss(tabPtr, tabRecord);
8826 
8827     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
8828       jam();
8829       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
8830       continue;
8831     }
8832 
8833     if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
8834       /**
8835        * Table is not logged
8836        */
8837       jam();
8838       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
8839       continue;
8840     }
8841 
8842     if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
8843       /* ----------------------------------------------------------------- */
8844       // We protect the updates of table data structures by this variable.
8845       /* ----------------------------------------------------------------- */
8846       jam();
8847       signal->theData[0] = DihContinueB::ZINIT_LCP;
8848       signal->theData[1] = senderRef;
8849       signal->theData[2] = tabPtr.i;
8850       sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
8851       return;
8852     }//if
8853 
8854     /**
8855      * Found a table
8856      */
8857     tabPtr.p->tabLcpStatus = TabRecord::TLS_ACTIVE;
8858 
8859     /**
8860      * For each fragment
8861      */
8862     for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
8863       jam();
8864       FragmentstorePtr fragPtr;
8865       getFragstore(tabPtr.p, fragId, fragPtr);
8866 
8867       /**
8868        * For each of replica record
8869        */
8870       Uint32 replicaCount = 0;
8871       ReplicaRecordPtr replicaPtr;
8872       for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL;
8873 	  replicaPtr.i = replicaPtr.p->nextReplica) {
8874 	jam();
8875 
8876 	ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
8877 	Uint32 nodeId = replicaPtr.p->procNode;
8878 	if(c_lcpState.m_participatingLQH.get(nodeId)){
8879 	  jam();
8880 	  replicaCount++;
8881 	  replicaPtr.p->lcpOngoingFlag = true;
8882 	}
8883       }
8884 
8885       fragPtr.p->noLcpReplicas = replicaCount;
8886     }//for
8887 
8888     signal->theData[0] = DihContinueB::ZINIT_LCP;
8889     signal->theData[1] = senderRef;
8890     signal->theData[2] = tabPtr.i + 1;
8891     sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
8892     return;
8893   }
8894 
8895   /**
8896    * No more tables
8897    */
8898   jam();
8899 
8900   if (c_lcpState.m_masterLcpDihRef != reference()){
8901     jam();
8902     ndbrequire(!isMaster());
8903     c_lcpState.setLcpStatus(LCP_STATUS_ACTIVE, __LINE__);
8904   } else {
8905     jam();
8906     ndbrequire(isMaster());
8907   }
8908 
8909   CRASH_INSERTION2(7023, isMaster());
8910   CRASH_INSERTION2(7024, !isMaster());
8911 
8912   jam();
8913   StartLcpConf * conf = (StartLcpConf*)signal->getDataPtrSend();
8914   conf->senderRef = reference();
8915   sendSignal(c_lcpState.m_masterLcpDihRef, GSN_START_LCP_CONF, signal,
8916 	     StartLcpConf::SignalLength, JBB);
8917   return;
8918 }//Dbdih::initLcpLab()
8919 
8920 /* ------------------------------------------------------------------------- */
8921 /*       ERROR HANDLING FOR COPY RESTORABLE GCI FILE.                        */
8922 /* ------------------------------------------------------------------------- */
openingCopyGciErrorLab(Signal * signal,FileRecordPtr filePtr)8923 void Dbdih::openingCopyGciErrorLab(Signal* signal, FileRecordPtr filePtr)
8924 {
8925   createFileRw(signal, filePtr);
8926   /* ------------------------------------------------------------------------- */
8927   /*       ERROR IN OPENING FILE. WE WILL TRY BY CREATING FILE INSTEAD.        */
8928   /* ------------------------------------------------------------------------- */
8929   filePtr.p->reqStatus = FileRecord::CREATING_COPY_GCI;
8930   return;
8931 }//Dbdih::openingCopyGciErrorLab()
8932 
8933 /* ------------------------------------------------------------------------- */
8934 /*       ENTER DICTSTARTCONF WITH                                            */
8935 /*         TBLOCKREF                                                         */
8936 /* ------------------------------------------------------------------------- */
dictStartConfLab(Signal * signal)8937 void Dbdih::dictStartConfLab(Signal* signal)
8938 {
8939   /* ----------------------------------------------------------------------- */
8940   /*     WE HAVE NOW RECEIVED ALL THE TABLES TO RESTART.                     */
8941   /* ----------------------------------------------------------------------- */
8942   signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
8943   signal->theData[1] = 0;  /* START WITH TABLE 0    */
8944   signal->theData[2] = 0;  /* AND FRAGMENT 0        */
8945   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
8946   return;
8947 }//Dbdih::dictStartConfLab()
8948 
8949 
openingTableLab(Signal * signal,FileRecordPtr filePtr)8950 void Dbdih::openingTableLab(Signal* signal, FileRecordPtr filePtr)
8951 {
8952   /* ---------------------------------------------------------------------- */
8953   /*    SUCCESSFULLY OPENED A FILE. READ THE FIRST PAGE OF THIS FILE.       */
8954   /* ---------------------------------------------------------------------- */
8955   TabRecordPtr tabPtr;
8956   PageRecordPtr pagePtr;
8957 
8958   tabPtr.i = filePtr.p->tabRef;
8959   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8960   tabPtr.p->noPages = 1;
8961   allocpage(pagePtr);
8962   tabPtr.p->pageRef[0] = pagePtr.i;
8963   readTabfile(signal, tabPtr.p, filePtr);
8964   filePtr.p->reqStatus = FileRecord::READING_TABLE;
8965   return;
8966 }//Dbdih::openingTableLab()
8967 
openingTableErrorLab(Signal * signal,FileRecordPtr filePtr)8968 void Dbdih::openingTableErrorLab(Signal* signal, FileRecordPtr filePtr)
8969 {
8970   TabRecordPtr tabPtr;
8971   tabPtr.i = filePtr.p->tabRef;
8972   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8973   /* ---------------------------------------------------------------------- */
8974   /*    WE FAILED IN OPENING A FILE. IF THE FIRST FILE THEN TRY WITH THE    */
8975   /*    DUPLICATE FILE, OTHERWISE WE REPORT AN ERROR IN THE SYSTEM RESTART. */
8976   /* ---------------------------------------------------------------------- */
8977   if (filePtr.i == tabPtr.p->tabFile[0])
8978   {
8979     filePtr.i = tabPtr.p->tabFile[1];
8980     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
8981     openFileRw(signal, filePtr);
8982     filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
8983   }
8984   else
8985   {
8986     char buf[256];
8987     BaseString::snprintf(buf, sizeof(buf),
8988 			 "Error opening DIH schema files for table: %d",
8989 			 tabPtr.i);
8990     progError(__LINE__, NDBD_EXIT_AFS_NO_SUCH_FILE, buf);
8991   }
8992 }//Dbdih::openingTableErrorLab()
8993 
readingTableLab(Signal * signal,FileRecordPtr filePtr)8994 void Dbdih::readingTableLab(Signal* signal, FileRecordPtr filePtr)
8995 {
8996   TabRecordPtr tabPtr;
8997   PageRecordPtr pagePtr;
8998   /* ---------------------------------------------------------------------- */
8999   /*    WE HAVE SUCCESSFULLY READ A NUMBER OF PAGES IN THE TABLE FILE. IF   */
9000   /*    MORE PAGES EXIST IN THE FILE THEN READ ALL PAGES IN THE FILE.       */
9001   /* ---------------------------------------------------------------------- */
9002   filePtr.p->reqStatus = FileRecord::IDLE;
9003   tabPtr.i = filePtr.p->tabRef;
9004   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9005   pagePtr.i = tabPtr.p->pageRef[0];
9006   ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
9007   Uint32 noOfStoredPages = pagePtr.p->word[33];
9008   if (tabPtr.p->noPages < noOfStoredPages) {
9009     jam();
9010     ndbrequire(noOfStoredPages <= 8);
9011     for (Uint32 i = tabPtr.p->noPages; i < noOfStoredPages; i++) {
9012       jam();
9013       allocpage(pagePtr);
9014       tabPtr.p->pageRef[i] = pagePtr.i;
9015     }//for
9016     tabPtr.p->noPages = noOfStoredPages;
9017     readTabfile(signal, tabPtr.p, filePtr);
9018     filePtr.p->reqStatus = FileRecord::READING_TABLE;
9019   } else {
9020     ndbrequire(tabPtr.p->noPages == pagePtr.p->word[33]);
9021     ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
9022     jam();
9023     /* --------------------------------------------------------------------- */
9024     /*   WE HAVE READ ALL PAGES. NOW READ FROM PAGES INTO TABLE AND FRAGMENT */
9025     /*   DATA STRUCTURES.                                                    */
9026     /* --------------------------------------------------------------------- */
9027     tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE1_READ_PAGES;
9028     signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_TABLE;
9029     signal->theData[1] = tabPtr.i;
9030     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9031     return;
9032   }//if
9033   return;
9034 }//Dbdih::readingTableLab()
9035 
readTableFromPagesLab(Signal * signal,TabRecordPtr tabPtr)9036 void Dbdih::readTableFromPagesLab(Signal* signal, TabRecordPtr tabPtr)
9037 {
9038   FileRecordPtr filePtr;
9039   filePtr.i = tabPtr.p->tabFile[0];
9040   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
9041   /* ---------------------------------------------------------------------- */
9042   /*    WE HAVE NOW COPIED TO OUR NODE. WE HAVE NOW COMPLETED RESTORING     */
9043   /*    THIS TABLE. CONTINUE WITH THE NEXT TABLE.                           */
9044   /*    WE ALSO NEED TO CLOSE THE TABLE FILE.                               */
9045   /* ---------------------------------------------------------------------- */
9046   if (filePtr.p->fileStatus != FileRecord::OPEN) {
9047     jam();
9048     filePtr.i = tabPtr.p->tabFile[1];
9049     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
9050   }//if
9051   closeFile(signal, filePtr);
9052   filePtr.p->reqStatus = FileRecord::CLOSING_TABLE_SR;
9053   return;
9054 }//Dbdih::readTableFromPagesLab()
9055 
closingTableSrLab(Signal * signal,FileRecordPtr filePtr)9056 void Dbdih::closingTableSrLab(Signal* signal, FileRecordPtr filePtr)
9057 {
9058   /**
9059    * Update table/fragment info
9060    */
9061   TabRecordPtr tabPtr;
9062   tabPtr.i = filePtr.p->tabRef;
9063   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9064   resetReplicaSr(tabPtr);
9065 
9066   signal->theData[0] = DihContinueB::ZCOPY_TABLE;
9067   signal->theData[1] = filePtr.p->tabRef;
9068   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9069 
9070   return;
9071 }//Dbdih::closingTableSrLab()
9072 
9073 void
resetReplicaSr(TabRecordPtr tabPtr)9074 Dbdih::resetReplicaSr(TabRecordPtr tabPtr){
9075 
9076   const Uint32 newestRestorableGCI = SYSFILE->newestRestorableGCI;
9077 
9078   for(Uint32 i = 0; i<tabPtr.p->totalfragments; i++){
9079     FragmentstorePtr fragPtr;
9080     getFragstore(tabPtr.p, i, fragPtr);
9081 
9082     /**
9083      * 1) Start by moving all replicas into oldStoredReplicas
9084      */
9085     prepareReplicas(fragPtr);
9086 
9087     /**
9088      * 2) Move all "alive" replicas into storedReplicas
9089      *    + update noCrashedReplicas...
9090      */
9091     ReplicaRecordPtr replicaPtr;
9092     replicaPtr.i = fragPtr.p->oldStoredReplicas;
9093     while (replicaPtr.i != RNIL) {
9094       jam();
9095       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
9096       const Uint32 nextReplicaPtrI = replicaPtr.p->nextReplica;
9097 
9098       NodeRecordPtr nodePtr;
9099       nodePtr.i = replicaPtr.p->procNode;
9100       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
9101 
9102       const Uint32 noCrashedReplicas = replicaPtr.p->noCrashedReplicas;
9103       if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
9104 	jam();
9105 	switch (nodePtr.p->activeStatus) {
9106 	case Sysfile::NS_Active:
9107 	case Sysfile::NS_ActiveMissed_1:
9108 	case Sysfile::NS_ActiveMissed_2:{
9109 	  jam();
9110 	  /* --------------------------------------------------------------- */
9111 	  /* THE NODE IS ALIVE AND KICKING AND ACTIVE, LET'S USE IT.         */
9112 	  /* --------------------------------------------------------------- */
9113 	  arrGuardErr(noCrashedReplicas, 8, NDBD_EXIT_MAX_CRASHED_REPLICAS);
9114 	  Uint32 lastGci = replicaPtr.p->replicaLastGci[noCrashedReplicas];
9115 	  if(lastGci >= newestRestorableGCI){
9116 	    jam();
9117 	    /** -------------------------------------------------------------
9118 	     * THE REPLICA WAS ALIVE AT THE SYSTEM FAILURE. WE WILL SET THE
9119 	     * LAST REPLICA GCI TO MINUS ONE SINCE IT HASN'T FAILED YET IN THE
9120 	     * NEW SYSTEM.
9121 	     *-------------------------------------------------------------- */
9122 	    replicaPtr.p->replicaLastGci[noCrashedReplicas] = (Uint32)-1;
9123 	  } else {
9124 	    jam();
9125 	    /*--------------------------------------------------------------
9126 	     * SINCE IT WAS NOT ALIVE AT THE TIME OF THE SYSTEM CRASH THIS IS
9127 	     * A COMPLETELY NEW REPLICA. WE WILL SET THE CREATE GCI TO BE THE
9128 	     * NEXT GCI TO BE EXECUTED.
9129 	     *--------_----------------------------------------------------- */
9130 	    const Uint32 nextCrashed = noCrashedReplicas + 1;
9131 	    replicaPtr.p->noCrashedReplicas = nextCrashed;
9132 	    arrGuardErr(nextCrashed, 8, NDBD_EXIT_MAX_CRASHED_REPLICAS);
9133 	    replicaPtr.p->createGci[nextCrashed] = newestRestorableGCI + 1;
9134 	    ndbrequire(newestRestorableGCI + 1 != 0xF1F1F1F1);
9135 	    replicaPtr.p->replicaLastGci[nextCrashed] = (Uint32)-1;
9136 	  }//if
9137 
9138 	  resetReplicaLcp(replicaPtr.p, newestRestorableGCI);
9139 
9140 	  /**
9141 	   * Make sure we can also find REDO for restoring replica...
9142 	   */
9143 	  {
9144 	    CreateReplicaRecord createReplica;
9145 	    ConstPtr<ReplicaRecord> constReplicaPtr;
9146 	    constReplicaPtr.i = replicaPtr.i;
9147 	    constReplicaPtr.p = replicaPtr.p;
9148 	    if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL ||
9149 		setup_create_replica(fragPtr,
9150 				     &createReplica, constReplicaPtr))
9151 	    {
9152 	      jam();
9153 	      removeOldStoredReplica(fragPtr, replicaPtr);
9154 	      linkStoredReplica(fragPtr, replicaPtr);
9155 	    }
9156 	    else
9157 	    {
9158 	      jam();
9159 	      infoEvent("Forcing take-over of node %d due to unsufficient REDO"
9160 			" for table %d fragment: %d",
9161 			nodePtr.i, tabPtr.i, i);
9162 
9163 	      setNodeActiveStatus(nodePtr.i,
9164 				  Sysfile::NS_NotActive_NotTakenOver);
9165 	    }
9166 	  }
9167 	}
9168         default:
9169 	  jam();
9170 	  /*empty*/;
9171 	  break;
9172 	}
9173       }
9174       replicaPtr.i = nextReplicaPtrI;
9175     }//while
9176     updateNodeInfo(fragPtr);
9177   }
9178 }
9179 
9180 void
resetReplicaLcp(ReplicaRecord * replicaP,Uint32 stopGci)9181 Dbdih::resetReplicaLcp(ReplicaRecord * replicaP, Uint32 stopGci){
9182 
9183   Uint32 lcpNo = replicaP->nextLcp;
9184   const Uint32 startLcpNo = lcpNo;
9185   do {
9186     lcpNo = prevLcpNo(lcpNo);
9187     ndbrequire(lcpNo < MAX_LCP_STORED);
9188     if (replicaP->lcpStatus[lcpNo] == ZVALID) {
9189       if (replicaP->maxGciStarted[lcpNo] < stopGci) {
9190         jam();
9191 	/* ----------------------------------------------------------------- */
9192 	/*   WE HAVE FOUND A USEFUL LOCAL CHECKPOINT THAT CAN BE USED FOR    */
9193 	/*   RESTARTING THIS FRAGMENT REPLICA.                               */
9194 	/* ----------------------------------------------------------------- */
9195         return ;
9196       }//if
9197     }//if
9198 
9199     /**
9200      * WE COULD  NOT USE THIS LOCAL CHECKPOINT. IT WAS TOO
9201      * RECENT OR SIMPLY NOT A VALID CHECKPOINT.
9202      * WE SHOULD THUS REMOVE THIS LOCAL CHECKPOINT SINCE IT WILL NEVER
9203      * AGAIN BE USED. SET LCP_STATUS TO INVALID.
9204      */
9205     replicaP->nextLcp = lcpNo;
9206     replicaP->lcpId[lcpNo] = 0;
9207     replicaP->lcpStatus[lcpNo] = ZINVALID;
9208   } while (lcpNo != startLcpNo);
9209 
9210   replicaP->nextLcp = 0;
9211 }
9212 
readingTableErrorLab(Signal * signal,FileRecordPtr filePtr)9213 void Dbdih::readingTableErrorLab(Signal* signal, FileRecordPtr filePtr)
9214 {
9215   TabRecordPtr tabPtr;
9216   tabPtr.i = filePtr.p->tabRef;
9217   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9218   /* ---------------------------------------------------------------------- */
9219   /*    READING THIS FILE FAILED. CLOSE IT AFTER RELEASING ALL PAGES.       */
9220   /* ---------------------------------------------------------------------- */
9221   ndbrequire(tabPtr.p->noPages <= 8);
9222   for (Uint32 i = 0; i < tabPtr.p->noPages; i++) {
9223     jam();
9224     releasePage(tabPtr.p->pageRef[i]);
9225   }//for
9226   closeFile(signal, filePtr);
9227   filePtr.p->reqStatus = FileRecord::CLOSING_TABLE_CRASH;
9228   return;
9229 }//Dbdih::readingTableErrorLab()
9230 
closingTableCrashLab(Signal * signal,FileRecordPtr filePtr)9231 void Dbdih::closingTableCrashLab(Signal* signal, FileRecordPtr filePtr)
9232 {
9233   TabRecordPtr tabPtr;
9234   /* ---------------------------------------------------------------------- */
9235   /*    WE HAVE NOW CLOSED A FILE WHICH WE HAD A READ ERROR WITH. PROCEED   */
9236   /*    WITH NEXT FILE IF NOT THE LAST OTHERWISE REPORT ERROR.              */
9237   /* ---------------------------------------------------------------------- */
9238   tabPtr.i = filePtr.p->tabRef;
9239   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9240   ndbrequire(filePtr.i == tabPtr.p->tabFile[0]);
9241   filePtr.i = tabPtr.p->tabFile[1];
9242   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
9243   openFileRw(signal, filePtr);
9244   filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
9245 }//Dbdih::closingTableCrashLab()
9246 
9247 /*****************************************************************************/
9248 /* **********     COPY TABLE MODULE                              *************/
9249 /*****************************************************************************/
execCOPY_TABREQ(Signal * signal)9250 void Dbdih::execCOPY_TABREQ(Signal* signal)
9251 {
9252   CRASH_INSERTION(7172);
9253 
9254   TabRecordPtr tabPtr;
9255   PageRecordPtr pagePtr;
9256   jamEntry();
9257   BlockReference ref = signal->theData[0];
9258   Uint32 reqinfo = signal->theData[1];
9259   tabPtr.i = signal->theData[2];
9260   Uint32 schemaVersion = signal->theData[3];
9261   Uint32 noOfWords = signal->theData[4];
9262   ndbrequire(ref == cmasterdihref);
9263   ndbrequire(!isMaster());
9264   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9265   if (reqinfo == 1) {
9266     jam();
9267     tabPtr.p->schemaVersion = schemaVersion;
9268     initTableFile(tabPtr);
9269   }//if
9270   ndbrequire(tabPtr.p->noPages < 8);
9271   if (tabPtr.p->noOfWords == 0) {
9272     jam();
9273     allocpage(pagePtr);
9274     tabPtr.p->pageRef[tabPtr.p->noPages] = pagePtr.i;
9275     tabPtr.p->noPages++;
9276   } else {
9277     jam();
9278     pagePtr.i = tabPtr.p->pageRef[tabPtr.p->noPages - 1];
9279     ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
9280   }//if
9281   ndbrequire(tabPtr.p->noOfWords + 15 < 2048);
9282   ndbrequire(tabPtr.p->noOfWords < 2048);
9283   MEMCOPY_NO_WORDS(&pagePtr.p->word[tabPtr.p->noOfWords], &signal->theData[5], 16);
9284   tabPtr.p->noOfWords += 16;
9285   if (tabPtr.p->noOfWords == 2048) {
9286     jam();
9287     tabPtr.p->noOfWords = 0;
9288   }//if
9289   if (noOfWords > 16) {
9290     jam();
9291     return;
9292   }//if
9293   tabPtr.p->noOfWords = 0;
9294   ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
9295   tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_TAB_REQ;
9296   signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_TABLE;
9297   signal->theData[1] = tabPtr.i;
9298   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9299 }//Dbdih::execCOPY_TABREQ()
9300 
9301 void
copyTabReq_complete(Signal * signal,TabRecordPtr tabPtr)9302 Dbdih::copyTabReq_complete(Signal* signal, TabRecordPtr tabPtr){
9303   if (!isMaster()) {
9304     jam();
9305     //----------------------------------------------------------------------------
9306     // In this particular case we do not release table pages if we are master. The
9307     // reason is that the master could still be sending the table info to another
9308     // node.
9309     //----------------------------------------------------------------------------
9310     releaseTabPages(tabPtr.i);
9311     tabPtr.p->tabStatus = TabRecord::TS_ACTIVE;
9312     for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
9313       jam();
9314       FragmentstorePtr fragPtr;
9315       getFragstore(tabPtr.p, fragId, fragPtr);
9316       updateNodeInfo(fragPtr);
9317     }//for
9318   }//if
9319   signal->theData[0] = cownNodeId;
9320   signal->theData[1] = tabPtr.i;
9321   sendSignal(cmasterdihref, GSN_COPY_TABCONF, signal, 2, JBB);
9322 }
9323 
9324 /*****************************************************************************/
9325 /* ******  READ FROM A NUMBER OF PAGES INTO THE TABLE DATA STRUCTURES ********/
9326 /*****************************************************************************/
readPagesIntoTableLab(Signal * signal,Uint32 tableId)9327 void Dbdih::readPagesIntoTableLab(Signal* signal, Uint32 tableId)
9328 {
9329   RWFragment rf;
9330   rf.wordIndex = 35;
9331   rf.pageIndex = 0;
9332   rf.rwfTabPtr.i = tableId;
9333   ptrCheckGuard(rf.rwfTabPtr, ctabFileSize, tabRecord);
9334   rf.rwfPageptr.i = rf.rwfTabPtr.p->pageRef[0];
9335   ptrCheckGuard(rf.rwfPageptr, cpageFileSize, pageRecord);
9336   rf.rwfTabPtr.p->totalfragments = readPageWord(&rf);
9337   rf.rwfTabPtr.p->noOfBackups = readPageWord(&rf);
9338   rf.rwfTabPtr.p->hashpointer = readPageWord(&rf);
9339   rf.rwfTabPtr.p->kvalue = readPageWord(&rf);
9340   rf.rwfTabPtr.p->mask = readPageWord(&rf);
9341   rf.rwfTabPtr.p->method = (TabRecord::Method)readPageWord(&rf);
9342   /* ------------- */
9343   /* Type of table */
9344   /* ------------- */
9345   rf.rwfTabPtr.p->tabStorage = (TabRecord::Storage)(readPageWord(&rf));
9346 
9347   Uint32 noOfFrags = rf.rwfTabPtr.p->totalfragments;
9348   ndbrequire(noOfFrags > 0);
9349   ndbrequire((noOfFrags * (rf.rwfTabPtr.p->noOfBackups + 1)) <= cnoFreeReplicaRec);
9350   allocFragments(noOfFrags, rf.rwfTabPtr);
9351 
9352   signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_FRAG;
9353   signal->theData[1] = rf.rwfTabPtr.i;
9354   signal->theData[2] = 0;
9355   signal->theData[3] = rf.pageIndex;
9356   signal->theData[4] = rf.wordIndex;
9357   sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
9358   return;
9359 }//Dbdih::readPagesIntoTableLab()
9360 
readPagesIntoFragLab(Signal * signal,RWFragment * rf)9361 void Dbdih::readPagesIntoFragLab(Signal* signal, RWFragment* rf)
9362 {
9363   ndbrequire(rf->pageIndex < 8);
9364   rf->rwfPageptr.i = rf->rwfTabPtr.p->pageRef[rf->pageIndex];
9365   ptrCheckGuard(rf->rwfPageptr, cpageFileSize, pageRecord);
9366   FragmentstorePtr fragPtr;
9367   getFragstore(rf->rwfTabPtr.p, rf->fragId, fragPtr);
9368   readFragment(rf, fragPtr);
9369   readReplicas(rf, fragPtr);
9370   rf->fragId++;
9371   if (rf->fragId == rf->rwfTabPtr.p->totalfragments) {
9372     jam();
9373     switch (rf->rwfTabPtr.p->tabCopyStatus) {
9374     case TabRecord::CS_SR_PHASE1_READ_PAGES:
9375       jam();
9376       releaseTabPages(rf->rwfTabPtr.i);
9377       rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9378       signal->theData[0] = DihContinueB::ZREAD_TABLE_FROM_PAGES;
9379       signal->theData[1] = rf->rwfTabPtr.i;
9380       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9381       return;
9382       break;
9383     case TabRecord::CS_COPY_TAB_REQ:
9384       jam();
9385       rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9386       if(getNodeState().getSystemRestartInProgress()){
9387 	jam();
9388 	copyTabReq_complete(signal, rf->rwfTabPtr);
9389 	return;
9390       }
9391       rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9392       rf->rwfTabPtr.p->tabUpdateState = TabRecord::US_COPY_TAB_REQ;
9393       signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
9394       signal->theData[1] = rf->rwfTabPtr.i;
9395       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9396       return;
9397       break;
9398     default:
9399       ndbrequire(false);
9400       return;
9401       break;
9402     }//switch
9403   } else {
9404     jam();
9405     signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_FRAG;
9406     signal->theData[1] = rf->rwfTabPtr.i;
9407     signal->theData[2] = rf->fragId;
9408     signal->theData[3] = rf->pageIndex;
9409     signal->theData[4] = rf->wordIndex;
9410     sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
9411   }//if
9412   return;
9413 }//Dbdih::readPagesIntoFragLab()
9414 
9415 /*****************************************************************************/
9416 /*****   WRITING FROM TABLE DATA STRUCTURES INTO A SET OF PAGES         ******/
9417 // execCONTINUEB(ZPACK_TABLE_INTO_PAGES)
9418 /*****************************************************************************/
packTableIntoPagesLab(Signal * signal,Uint32 tableId)9419 void Dbdih::packTableIntoPagesLab(Signal* signal, Uint32 tableId)
9420 {
9421   RWFragment wf;
9422   TabRecordPtr tabPtr;
9423   allocpage(wf.rwfPageptr);
9424   tabPtr.i = tableId;
9425   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9426   tabPtr.p->pageRef[0] = wf.rwfPageptr.i;
9427   tabPtr.p->noPages = 1;
9428   wf.wordIndex = 35;
9429   wf.pageIndex = 0;
9430   writePageWord(&wf, tabPtr.p->totalfragments);
9431   writePageWord(&wf, tabPtr.p->noOfBackups);
9432   writePageWord(&wf, tabPtr.p->hashpointer);
9433   writePageWord(&wf, tabPtr.p->kvalue);
9434   writePageWord(&wf, tabPtr.p->mask);
9435   writePageWord(&wf, tabPtr.p->method);
9436   writePageWord(&wf, tabPtr.p->tabStorage);
9437 
9438   signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
9439   signal->theData[1] = tabPtr.i;
9440   signal->theData[2] = 0;
9441   signal->theData[3] = wf.pageIndex;
9442   signal->theData[4] = wf.wordIndex;
9443   sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
9444 }//Dbdih::packTableIntoPagesLab()
9445 
9446 /*****************************************************************************/
9447 // execCONTINUEB(ZPACK_FRAG_INTO_PAGES)
9448 /*****************************************************************************/
packFragIntoPagesLab(Signal * signal,RWFragment * wf)9449 void Dbdih::packFragIntoPagesLab(Signal* signal, RWFragment* wf)
9450 {
9451   ndbrequire(wf->pageIndex < 8);
9452   wf->rwfPageptr.i = wf->rwfTabPtr.p->pageRef[wf->pageIndex];
9453   ptrCheckGuard(wf->rwfPageptr, cpageFileSize, pageRecord);
9454   FragmentstorePtr fragPtr;
9455   getFragstore(wf->rwfTabPtr.p, wf->fragId, fragPtr);
9456   writeFragment(wf, fragPtr);
9457   writeReplicas(wf, fragPtr.p->storedReplicas);
9458   writeReplicas(wf, fragPtr.p->oldStoredReplicas);
9459   wf->fragId++;
9460   if (wf->fragId == wf->rwfTabPtr.p->totalfragments) {
9461     jam();
9462     PageRecordPtr pagePtr;
9463     pagePtr.i = wf->rwfTabPtr.p->pageRef[0];
9464     ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
9465     pagePtr.p->word[33] = wf->rwfTabPtr.p->noPages;
9466     pagePtr.p->word[34] = ((wf->rwfTabPtr.p->noPages - 1) * 2048) + wf->wordIndex;
9467     switch (wf->rwfTabPtr.p->tabCopyStatus) {
9468     case TabRecord::CS_SR_PHASE2_READ_TABLE:
9469       /* -------------------------------------------------------------------*/
9470       // We are performing a system restart and we are now ready to copy the
9471       // table from this node (the master) to all other nodes.
9472       /* -------------------------------------------------------------------*/
9473       jam();
9474       wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9475       signal->theData[0] = DihContinueB::ZSR_PHASE2_READ_TABLE;
9476       signal->theData[1] = wf->rwfTabPtr.i;
9477       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9478       return;
9479       break;
9480     case TabRecord::CS_COPY_NODE_STATE:
9481       jam();
9482       tableCopyNodeLab(signal, wf->rwfTabPtr);
9483       return;
9484       break;
9485     case TabRecord::CS_LCP_READ_TABLE:
9486       jam();
9487       signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
9488       signal->theData[1] = wf->rwfTabPtr.i;
9489       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9490       return;
9491       break;
9492     case TabRecord::CS_REMOVE_NODE:
9493     case TabRecord::CS_INVALIDATE_NODE_LCP:
9494       jam();
9495       signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
9496       signal->theData[1] = wf->rwfTabPtr.i;
9497       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9498       return;
9499       break;
9500     case TabRecord::CS_ADD_TABLE_MASTER:
9501       jam();
9502       wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9503       signal->theData[0] = DihContinueB::ZADD_TABLE_MASTER_PAGES;
9504       signal->theData[1] = wf->rwfTabPtr.i;
9505       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9506       return;
9507       break;
9508     case TabRecord::CS_ADD_TABLE_SLAVE:
9509       jam();
9510       wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9511       signal->theData[0] = DihContinueB::ZADD_TABLE_SLAVE_PAGES;
9512       signal->theData[1] = wf->rwfTabPtr.i;
9513       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9514       return;
9515       break;
9516     default:
9517       ndbrequire(false);
9518       return;
9519       break;
9520     }//switch
9521   } else {
9522     jam();
9523     signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
9524     signal->theData[1] = wf->rwfTabPtr.i;
9525     signal->theData[2] = wf->fragId;
9526     signal->theData[3] = wf->pageIndex;
9527     signal->theData[4] = wf->wordIndex;
9528     sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
9529   }//if
9530   return;
9531 }//Dbdih::packFragIntoPagesLab()
9532 
9533 /*****************************************************************************/
9534 /* **********     START FRAGMENT MODULE                          *************/
9535 /*****************************************************************************/
9536 void
dump_replica_info()9537 Dbdih::dump_replica_info()
9538 {
9539   TabRecordPtr tabPtr;
9540   FragmentstorePtr fragPtr;
9541 
9542   for(tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++)
9543   {
9544     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9545     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
9546       continue;
9547 
9548     for(Uint32 fid = 0; fid<tabPtr.p->totalfragments; fid++)
9549     {
9550       getFragstore(tabPtr.p, fid, fragPtr);
9551       ndbout_c("tab: %d frag: %d gci: %d\n  -- storedReplicas:",
9552 	       tabPtr.i, fid, SYSFILE->newestRestorableGCI);
9553 
9554       Uint32 i;
9555       ReplicaRecordPtr replicaPtr;
9556       replicaPtr.i = fragPtr.p->storedReplicas;
9557       for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
9558       {
9559 	ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
9560 	ndbout_c("  node: %d initialGci: %d nextLcp: %d noCrashedReplicas: %d",
9561 		 replicaPtr.p->procNode,
9562 		 replicaPtr.p->initialGci,
9563 		 replicaPtr.p->nextLcp,
9564 		 replicaPtr.p->noCrashedReplicas);
9565 	for(i = 0; i<MAX_LCP_STORED; i++)
9566 	{
9567 	  ndbout_c("    i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
9568 		   i,
9569 		   (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
9570 		   replicaPtr.p->lcpId[i],
9571 		   replicaPtr.p->maxGciCompleted[i],
9572 		   replicaPtr.p->maxGciStarted[i]);
9573 	}
9574 
9575 	for (i = 0; i < 8; i++)
9576 	{
9577 	  ndbout_c("    crashed replica: %d replicaLastGci: %d createGci: %d",
9578 		   i,
9579 		   replicaPtr.p->replicaLastGci[i],
9580 		   replicaPtr.p->createGci[i]);
9581 	}
9582       }
9583       ndbout_c("  -- oldStoredReplicas");
9584       replicaPtr.i = fragPtr.p->oldStoredReplicas;
9585       for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
9586       {
9587 	ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
9588 	for(i = 0; i<MAX_LCP_STORED; i++)
9589 	{
9590 	  ndbout_c("    i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
9591 		   i,
9592 		   (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
9593 		   replicaPtr.p->lcpId[i],
9594 		   replicaPtr.p->maxGciCompleted[i],
9595 		   replicaPtr.p->maxGciStarted[i]);
9596 	}
9597 
9598 	for (i = 0; i < 8; i++)
9599 	{
9600 	  ndbout_c("    crashed replica: %d replicaLastGci: %d createGci: %d",
9601 		   i,
9602 		   replicaPtr.p->replicaLastGci[i],
9603 		   replicaPtr.p->createGci[i]);
9604 	}
9605       }
9606     }
9607   }
9608 }
9609 
startFragment(Signal * signal,Uint32 tableId,Uint32 fragId)9610 void Dbdih::startFragment(Signal* signal, Uint32 tableId, Uint32 fragId)
9611 {
9612   Uint32 TloopCount = 0;
9613   TabRecordPtr tabPtr;
9614   while (true) {
9615     if (TloopCount > 100) {
9616       jam();
9617       signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
9618       signal->theData[1] = tableId;
9619       signal->theData[2] = 0;
9620       sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
9621       return;
9622     }
9623 
9624     if (tableId >= ctabFileSize) {
9625       jam();
9626       signal->theData[0] = DihContinueB::ZCOMPLETE_RESTART;
9627       sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
9628       return;
9629     }//if
9630 
9631     tabPtr.i = tableId;
9632     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9633     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
9634       jam();
9635       TloopCount++;
9636       tableId++;
9637       fragId = 0;
9638       continue;
9639     }
9640 
9641     if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
9642       jam();
9643       TloopCount++;
9644       tableId++;
9645       fragId = 0;
9646       continue;
9647     }
9648 
9649     jam();
9650     break;
9651   }//while
9652 
9653   FragmentstorePtr fragPtr;
9654   getFragstore(tabPtr.p, fragId, fragPtr);
9655   /* ----------------------------------------------------------------------- */
9656   /*     WE NEED TO RESET THE REPLICA DATA STRUCTURES. THIS MEANS THAT WE    */
9657   /*     MUST REMOVE REPLICAS THAT WAS NOT STARTED AT THE GCI TO RESTORE. WE */
9658   /*     NEED TO PUT ALL STORED REPLICAS ON THE LIST OF OLD STORED REPLICAS  */
9659   /*     RESET THE NUMBER OF REPLICAS TO CREATE.                             */
9660   /* ----------------------------------------------------------------------- */
9661   cnoOfCreateReplicas = 0;
9662   /* ----------------------------------------------------------------------- */
9663   /*     WE WILL NEVER START MORE THAN FOUR FRAGMENT REPLICAS WHATEVER THE   */
9664   /*     DESIRED REPLICATION IS.                                             */
9665   /* ----------------------------------------------------------------------- */
9666   ndbrequire(tabPtr.p->noOfBackups < 4);
9667   /* ----------------------------------------------------------------------- */
9668   /*     SEARCH FOR STORED REPLICAS THAT CAN BE USED TO RESTART THE SYSTEM.  */
9669   /* ----------------------------------------------------------------------- */
9670   searchStoredReplicas(fragPtr);
9671 
9672   if (cnoOfCreateReplicas == 0) {
9673     /* --------------------------------------------------------------------- */
9674     /*   THERE WERE NO STORED REPLICAS AVAILABLE THAT CAN SERVE AS REPLICA TO*/
9675     /*   RESTART THE SYSTEM FROM. IN A LATER RELEASE WE WILL ADD             */
9676     /*   FUNCTIONALITY TO CHECK IF THERE ARE ANY STANDBY NODES THAT COULD DO */
9677     /*   THIS TASK INSTEAD IN THIS IMPLEMENTATION WE SIMPLY CRASH THE SYSTEM.*/
9678     /*   THIS WILL DECREASE THE GCI TO RESTORE WHICH HOPEFULLY WILL MAKE IT  */
9679     /*   POSSIBLE TO RESTORE THE SYSTEM.                                     */
9680     /* --------------------------------------------------------------------- */
9681     char buf[64];
9682     BaseString::snprintf(buf, sizeof(buf), "table: %d fragment: %d gci: %d",
9683 			 tableId, fragId, SYSFILE->newestRestorableGCI);
9684 
9685     ndbout_c(buf);
9686     dump_replica_info();
9687 
9688     progError(__LINE__, NDBD_EXIT_NO_RESTORABLE_REPLICA, buf);
9689     ndbrequire(false);
9690     return;
9691   }//if
9692 
9693   /* ----------------------------------------------------------------------- */
9694   /*     WE HAVE CHANGED THE NODE TO BE PRIMARY REPLICA AND THE NODES TO BE  */
9695   /*     BACKUP NODES. WE MUST UPDATE THIS NODES DATA STRUCTURE SINCE WE     */
9696   /*     WILL NOT COPY THE TABLE DATA TO OURSELF.                            */
9697   /* ----------------------------------------------------------------------- */
9698   updateNodeInfo(fragPtr);
9699   /* ----------------------------------------------------------------------- */
9700   /*     NOW WE HAVE COLLECTED ALL THE REPLICAS WE COULD GET. WE WILL NOW    */
9701   /*     RESTART THE FRAGMENT REPLICAS WE HAVE FOUND IRRESPECTIVE OF IF THERE*/
9702   /*     ARE ENOUGH ACCORDING TO THE DESIRED REPLICATION.                    */
9703   /* ----------------------------------------------------------------------- */
9704   /*     WE START BY SENDING ADD_FRAGREQ FOR THOSE REPLICAS THAT NEED IT.    */
9705   /* ----------------------------------------------------------------------- */
9706   CreateReplicaRecordPtr createReplicaPtr;
9707   for (createReplicaPtr.i = 0;
9708        createReplicaPtr.i < cnoOfCreateReplicas;
9709        createReplicaPtr.i++) {
9710     jam();
9711     ptrCheckGuard(createReplicaPtr, 4, createReplicaRecord);
9712     createReplicaPtr.p->hotSpareUse = false;
9713   }//for
9714 
9715   sendStartFragreq(signal, tabPtr, fragId);
9716 
9717   /**
9718    * Don't wait for START_FRAGCONF
9719    */
9720   fragId++;
9721   if (fragId >= tabPtr.p->totalfragments) {
9722     jam();
9723     tabPtr.i++;
9724     fragId = 0;
9725   }//if
9726   signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
9727   signal->theData[1] = tabPtr.i;
9728   signal->theData[2] = fragId;
9729   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
9730 
9731   return;
9732 }//Dbdih::startFragmentLab()
9733 
9734 
9735 /*****************************************************************************/
9736 /* **********     COMPLETE RESTART MODULE                        *************/
9737 /*****************************************************************************/
completeRestartLab(Signal * signal)9738 void Dbdih::completeRestartLab(Signal* signal)
9739 {
9740   sendLoopMacro(START_RECREQ, sendSTART_RECREQ);
9741 }//completeRestartLab()
9742 
9743 /* ------------------------------------------------------------------------- */
9744 //       SYSTEM RESTART:
9745 /*         A NODE HAS COMPLETED RESTORING ALL DATABASE FRAGMENTS.            */
9746 //       NODE RESTART:
9747 //         THE STARTING NODE HAS PREPARED ITS LOG FILES TO ENABLE EXECUTION
9748 //         OF TRANSACTIONS.
9749 // Precondition:
9750 //   This signal must be received by the master node.
9751 /* ------------------------------------------------------------------------- */
execSTART_RECCONF(Signal * signal)9752 void Dbdih::execSTART_RECCONF(Signal* signal)
9753 {
9754   jamEntry();
9755   Uint32 senderNodeId = signal->theData[0];
9756   ndbrequire(isMaster());
9757   if (getNodeState().startLevel >= NodeState::SL_STARTED){
9758     /* --------------------------------------------------------------------- */
9759     // Since our node is already up and running this must be a node restart.
9760     // This means that we should be the master node,
9761     // otherwise we have a problem.
9762     /* --------------------------------------------------------------------- */
9763     jam();
9764     ndbout_c("startNextCopyFragment");
9765     startNextCopyFragment(signal, findTakeOver(senderNodeId));
9766     return;
9767   } else {
9768     /* --------------------------------------------------------------------- */
9769     // This was the system restart case. We set the state indicating that the
9770     // node has completed restoration of all fragments.
9771     /* --------------------------------------------------------------------- */
9772     receiveLoopMacro(START_RECREQ, senderNodeId);
9773 
9774     signal->theData[0] = reference();
9775     sendSignal(cntrlblockref, GSN_NDB_STARTCONF, signal, 1, JBB);
9776     return;
9777   }//if
9778 }//Dbdih::execSTART_RECCONF()
9779 
copyNodeLab(Signal * signal,Uint32 tableId)9780 void Dbdih::copyNodeLab(Signal* signal, Uint32 tableId)
9781 {
9782   /* ----------------------------------------------------------------------- */
9783   // This code is executed by the master to assist a node restart in receiving
9784   // the data in the master.
9785   /* ----------------------------------------------------------------------- */
9786   Uint32 TloopCount = 0;
9787 
9788   if (!c_nodeStartMaster.activeState) {
9789     jam();
9790     /* --------------------------------------------------------------------- */
9791     // Obviously the node crashed in the middle of its node restart. We will
9792     // stop this process simply by returning after resetting the wait indicator.
9793     /* ---------------------------------------------------------------------- */
9794     c_nodeStartMaster.wait = ZFALSE;
9795     return;
9796   }//if
9797   TabRecordPtr tabPtr;
9798   tabPtr.i = tableId;
9799   while (tabPtr.i < ctabFileSize) {
9800     ptrAss(tabPtr, tabRecord);
9801     if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
9802       /* -------------------------------------------------------------------- */
9803       // The table is defined. We will start by packing the table into pages.
9804       // The tabCopyStatus indicates to the CONTINUEB(ZPACK_TABLE_INTO_PAGES)
9805       // who called it. After packing the table into page(s) it will be sent to
9806       // the starting node by COPY_TABREQ signals. After returning from the
9807       // starting node we will return to this subroutine and continue
9808       // with the next table.
9809       /* -------------------------------------------------------------------- */
9810       ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
9811       tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_NODE_STATE;
9812       signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
9813       signal->theData[1] = tabPtr.i;
9814       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9815       return;
9816     } else {
9817       jam();
9818       if (TloopCount > 100) {
9819 	/* ------------------------------------------------------------------ */
9820 	// Introduce real-time break after looping through 100 not copied tables
9821 	/* ----------------------------------------------------------------- */
9822         jam();
9823         signal->theData[0] = DihContinueB::ZCOPY_NODE;
9824         signal->theData[1] = tabPtr.i + 1;
9825         sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9826         return;
9827       } else {
9828         jam();
9829         TloopCount++;
9830         tabPtr.i++;
9831       }//if
9832     }//if
9833   }//while
9834   dihCopyCompletedLab(signal);
9835   return;
9836 }//Dbdih::copyNodeLab()
9837 
tableCopyNodeLab(Signal * signal,TabRecordPtr tabPtr)9838 void Dbdih::tableCopyNodeLab(Signal* signal, TabRecordPtr tabPtr)
9839 {
9840   /* ----------------------------------------------------------------------- */
9841   /*       COPY PAGES READ TO STARTING NODE.                                 */
9842   /* ----------------------------------------------------------------------- */
9843   if (!c_nodeStartMaster.activeState) {
9844     jam();
9845     releaseTabPages(tabPtr.i);
9846     c_nodeStartMaster.wait = ZFALSE;
9847     return;
9848   }//if
9849   NodeRecordPtr copyNodePtr;
9850   PageRecordPtr pagePtr;
9851   copyNodePtr.i = c_nodeStartMaster.startNode;
9852   ptrCheckGuard(copyNodePtr, MAX_NDB_NODES, nodeRecord);
9853 
9854   copyNodePtr.p->activeTabptr = tabPtr.i;
9855   pagePtr.i = tabPtr.p->pageRef[0];
9856   ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
9857 
9858   signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
9859   signal->theData[1] = tabPtr.i;
9860   signal->theData[2] = copyNodePtr.i;
9861   signal->theData[3] = 0;
9862   signal->theData[4] = 0;
9863   signal->theData[5] = pagePtr.p->word[34];
9864   sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
9865 }//Dbdih::tableCopyNodeLab()
9866 
9867 /* ------------------------------------------------------------------------- */
9868 // execCONTINUEB(ZCOPY_TABLE)
9869 // This routine is used to copy the table descriptions from the master to
9870 // other nodes. It is used in the system restart to copy from master to all
9871 // starting nodes.
9872 /* ------------------------------------------------------------------------- */
copyTableLab(Signal * signal,Uint32 tableId)9873 void Dbdih::copyTableLab(Signal* signal, Uint32 tableId)
9874 {
9875   TabRecordPtr tabPtr;
9876   tabPtr.i = tableId;
9877   ptrAss(tabPtr, tabRecord);
9878 
9879   ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
9880   tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE2_READ_TABLE;
9881   signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
9882   signal->theData[1] = tabPtr.i;
9883   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9884   return;
9885 }//Dbdih::copyTableLab()
9886 
9887 /* ------------------------------------------------------------------------- */
9888 // execCONTINUEB(ZSR_PHASE2_READ_TABLE)
9889 /* ------------------------------------------------------------------------- */
srPhase2ReadTableLab(Signal * signal,TabRecordPtr tabPtr)9890 void Dbdih::srPhase2ReadTableLab(Signal* signal, TabRecordPtr tabPtr)
9891 {
9892   /* ----------------------------------------------------------------------- */
9893   // We set the sendCOPY_TABREQState to ZACTIVE for all nodes since it is a long
9894   // process to send off all table descriptions. Thus we ensure that we do
9895   // not encounter race conditions where one node is completed before the
9896   // sending process is completed. This could lead to that we start off the
9897   // system before we actually finished all copying of table descriptions
9898   // and could lead to strange errors.
9899   /* ----------------------------------------------------------------------- */
9900 
9901   //sendLoopMacro(COPY_TABREQ, nullRoutine);
9902 
9903   breakCopyTableLab(signal, tabPtr, cfirstAliveNode);
9904   return;
9905 }//Dbdih::srPhase2ReadTableLab()
9906 
9907 /* ------------------------------------------------------------------------- */
9908 /*       COPY PAGES READ TO ALL NODES.                                       */
9909 /* ------------------------------------------------------------------------- */
breakCopyTableLab(Signal * signal,TabRecordPtr tabPtr,Uint32 nodeId)9910 void Dbdih::breakCopyTableLab(Signal* signal, TabRecordPtr tabPtr, Uint32 nodeId)
9911 {
9912   NodeRecordPtr nodePtr;
9913   nodePtr.i = nodeId;
9914   while (nodePtr.i != RNIL) {
9915     jam();
9916     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
9917     if (nodePtr.i == getOwnNodeId()){
9918       jam();
9919       /* ------------------------------------------------------------------- */
9920       /* NOT NECESSARY TO COPY TO MY OWN NODE. I ALREADY HAVE THE PAGES.     */
9921       /* I DO HOWEVER NEED TO STORE THE TABLE DESCRIPTION ONTO DISK.         */
9922       /* ------------------------------------------------------------------- */
9923       /* IF WE ARE MASTER WE ONLY NEED TO SAVE THE TABLE ON DISK. WE ALREADY */
9924       /* HAVE THE TABLE DESCRIPTION IN THE DATA STRUCTURES.                  */
9925       // AFTER COMPLETING THE WRITE TO DISK THE MASTER WILL ALSO SEND
9926       // COPY_TABCONF AS ALL THE OTHER NODES.
9927       /* ------------------------------------------------------------------- */
9928       c_COPY_TABREQ_Counter.setWaitingFor(nodePtr.i);
9929       tabPtr.p->tabUpdateState = TabRecord::US_COPY_TAB_REQ;
9930       signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
9931       signal->theData[1] = tabPtr.i;
9932       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9933       nodePtr.i = nodePtr.p->nextNode;
9934     } else {
9935       PageRecordPtr pagePtr;
9936       /* -------------------------------------------------------------------- */
9937       // RATHER THAN SENDING ALL COPY_TABREQ IN PARALLEL WE WILL SERIALISE THIS
9938       // ACTIVITY AND WILL THUS CALL breakCopyTableLab AGAIN WHEN COMPLETED THE
9939       // SENDING OF COPY_TABREQ'S.
9940       /* -------------------------------------------------------------------- */
9941       jam();
9942       tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE3_COPY_TABLE;
9943       pagePtr.i = tabPtr.p->pageRef[0];
9944       ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
9945       signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
9946       signal->theData[1] = tabPtr.i;
9947       signal->theData[2] = nodePtr.i;
9948       signal->theData[3] = 0;
9949       signal->theData[4] = 0;
9950       signal->theData[5] = pagePtr.p->word[34];
9951       sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
9952       return;
9953     }//if
9954   }//while
9955   /* ----------------------------------------------------------------------- */
9956   /*    WE HAVE NOW SENT THE TABLE PAGES TO ALL NODES. EXIT AND WAIT FOR ALL */
9957   /*    REPLIES.                                                             */
9958   /* ----------------------------------------------------------------------- */
9959   return;
9960 }//Dbdih::breakCopyTableLab()
9961 
9962 /* ------------------------------------------------------------------------- */
9963 // execCONTINUEB(ZCOPY_TABLE_NODE)
9964 /* ------------------------------------------------------------------------- */
copyTableNode(Signal * signal,CopyTableNode * ctn,NodeRecordPtr nodePtr)9965 void Dbdih::copyTableNode(Signal* signal,
9966 			  CopyTableNode* ctn, NodeRecordPtr nodePtr)
9967 {
9968   if (getNodeState().startLevel >= NodeState::SL_STARTED){
9969     /* --------------------------------------------------------------------- */
9970     // We are in the process of performing a node restart and are copying a
9971     // table description to a starting node. We will check that no nodes have
9972     // crashed in this process.
9973     /* --------------------------------------------------------------------- */
9974     if (!c_nodeStartMaster.activeState) {
9975       jam();
9976       /** ------------------------------------------------------------------
9977        * The starting node crashed. We will release table pages and stop this
9978        * copy process and allow new node restarts to start.
9979        * ------------------------------------------------------------------ */
9980       releaseTabPages(ctn->ctnTabPtr.i);
9981       c_nodeStartMaster.wait = ZFALSE;
9982       return;
9983     }//if
9984   }//if
9985   ndbrequire(ctn->pageIndex < 8);
9986   ctn->ctnPageptr.i = ctn->ctnTabPtr.p->pageRef[ctn->pageIndex];
9987   ptrCheckGuard(ctn->ctnPageptr, cpageFileSize, pageRecord);
9988   /**
9989    * If first page & firstWord reqinfo = 1 (first signal)
9990    */
9991   Uint32 reqinfo = (ctn->pageIndex == 0) && (ctn->wordIndex == 0);
9992   if(reqinfo == 1){
9993     c_COPY_TABREQ_Counter.setWaitingFor(nodePtr.i);
9994   }
9995 
9996   for (Uint32 i = 0; i < 16; i++) {
9997     jam();
9998     sendCopyTable(signal, ctn, calcDihBlockRef(nodePtr.i), reqinfo);
9999     reqinfo = 0;
10000     if (ctn->noOfWords <= 16) {
10001       jam();
10002       switch (ctn->ctnTabPtr.p->tabCopyStatus) {
10003       case TabRecord::CS_SR_PHASE3_COPY_TABLE:
10004 	/* ------------------------------------------------------------------ */
10005 	// We have copied the table description to this node.
10006 	// We will now proceed
10007 	// with sending the table description to the next node in the node list.
10008 	/* ------------------------------------------------------------------ */
10009         jam();
10010         ctn->ctnTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
10011         breakCopyTableLab(signal, ctn->ctnTabPtr, nodePtr.p->nextNode);
10012         return;
10013         break;
10014       case TabRecord::CS_COPY_NODE_STATE:
10015         jam();
10016         ctn->ctnTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
10017         return;
10018         break;
10019       default:
10020         ndbrequire(false);
10021         break;
10022       }//switch
10023     } else {
10024       jam();
10025       ctn->wordIndex += 16;
10026       if (ctn->wordIndex == 2048) {
10027         jam();
10028         ctn->wordIndex = 0;
10029         ctn->pageIndex++;
10030         ndbrequire(ctn->pageIndex < 8);
10031         ctn->ctnPageptr.i = ctn->ctnTabPtr.p->pageRef[ctn->pageIndex];
10032         ptrCheckGuard(ctn->ctnPageptr, cpageFileSize, pageRecord);
10033       }//if
10034       ctn->noOfWords -= 16;
10035     }//if
10036   }//for
10037   signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
10038   signal->theData[1] = ctn->ctnTabPtr.i;
10039   signal->theData[2] = nodePtr.i;
10040   signal->theData[3] = ctn->pageIndex;
10041   signal->theData[4] = ctn->wordIndex;
10042   signal->theData[5] = ctn->noOfWords;
10043   sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
10044 }//Dbdih::copyTableNodeLab()
10045 
sendCopyTable(Signal * signal,CopyTableNode * ctn,BlockReference ref,Uint32 reqinfo)10046 void Dbdih::sendCopyTable(Signal* signal, CopyTableNode* ctn,
10047                           BlockReference ref, Uint32 reqinfo)
10048 {
10049   signal->theData[0] = reference();
10050   signal->theData[1] = reqinfo;
10051   signal->theData[2] = ctn->ctnTabPtr.i;
10052   signal->theData[3] = ctn->ctnTabPtr.p->schemaVersion;
10053   signal->theData[4] = ctn->noOfWords;
10054   ndbrequire(ctn->wordIndex + 15 < 2048);
10055   MEMCOPY_NO_WORDS(&signal->theData[5], &ctn->ctnPageptr.p->word[ctn->wordIndex], 16);
10056   sendSignal(ref, GSN_COPY_TABREQ, signal, 21, JBB);
10057 }//Dbdih::sendCopyTable()
10058 
execCOPY_TABCONF(Signal * signal)10059 void Dbdih::execCOPY_TABCONF(Signal* signal)
10060 {
10061   NodeRecordPtr nodePtr;
10062   jamEntry();
10063   nodePtr.i = signal->theData[0];
10064   Uint32 tableId = signal->theData[1];
10065   if (getNodeState().startLevel >= NodeState::SL_STARTED){
10066     /* --------------------------------------------------------------------- */
10067     // We are in the process of performing a node restart. Continue by copying
10068     // the next table to the starting node.
10069     /* --------------------------------------------------------------------- */
10070     jam();
10071     NodeRecordPtr nodePtr;
10072     nodePtr.i = signal->theData[0];
10073     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
10074     c_COPY_TABREQ_Counter.clearWaitingFor(nodePtr.i);
10075 
10076     releaseTabPages(tableId);
10077     signal->theData[0] = DihContinueB::ZCOPY_NODE;
10078     signal->theData[1] = tableId + 1;
10079     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
10080     return;
10081   } else {
10082     /* --------------------------------------------------------------------- */
10083     // We are in the process of performing a system restart. Check if all nodes
10084     // have saved the new table description to file and then continue with the
10085     // next table.
10086     /* --------------------------------------------------------------------- */
10087     receiveLoopMacro(COPY_TABREQ, nodePtr.i);
10088     /* --------------------------------------------------------------------- */
10089     /*   WE HAVE NOW COPIED TO ALL NODES. WE HAVE NOW COMPLETED RESTORING    */
10090     /*   THIS TABLE. CONTINUE WITH THE NEXT TABLE.                           */
10091     /*   WE NEED TO RELEASE THE PAGES IN THE TABLE IN THIS NODE HERE.        */
10092     /*   WE ALSO NEED TO CLOSE THE TABLE FILE.                               */
10093     /* --------------------------------------------------------------------- */
10094     releaseTabPages(tableId);
10095 
10096     TabRecordPtr tabPtr;
10097     tabPtr.i = tableId;
10098     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
10099 
10100     ConnectRecordPtr connectPtr;
10101     connectPtr.i = tabPtr.p->connectrec;
10102     ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
10103 
10104     sendAddFragreq(signal, connectPtr, tabPtr, 0);
10105     return;
10106   }//if
10107 }//Dbdih::execCOPY_TABCONF()
10108 
10109 /*
10110   3.13   L O C A L   C H E C K P O I N T  (M A S T E R)
10111   ****************************************************
10112   */
10113 /*****************************************************************************/
10114 /* **********     LOCAL-CHECK-POINT-HANDLING MODULE              *************/
10115 /*****************************************************************************/
10116 /* ------------------------------------------------------------------------- */
10117 /*       IT IS TIME TO CHECK IF IT IS TIME TO START A LOCAL CHECKPOINT.      */
10118 /*       WE WILL EITHER START AFTER 1 MILLION WORDS HAVE ARRIVED OR WE WILL  */
10119 /*       EXECUTE AFTER ABOUT 16 MINUTES HAVE PASSED BY.                      */
10120 /* ------------------------------------------------------------------------- */
checkTcCounterLab(Signal * signal)10121 void Dbdih::checkTcCounterLab(Signal* signal)
10122 {
10123   CRASH_INSERTION(7009);
10124   if (c_lcpState.lcpStatus != LCP_STATUS_IDLE) {
10125     g_eventLogger.error("lcpStatus = %u"
10126                         "lcpStatusUpdatedPlace = %d",
10127                         (Uint32) c_lcpState.lcpStatus,
10128                         c_lcpState.lcpStatusUpdatedPlace);
10129     ndbrequire(false);
10130     return;
10131   }//if
10132   c_lcpState.ctimer += 32;
10133   if ((c_nodeStartMaster.blockLcp == true) ||
10134       (c_lcpState.lcpStopGcp >= c_newest_restorable_gci)) {
10135     jam();
10136     /* --------------------------------------------------------------------- */
10137     // No reason to start juggling the states and checking for start of LCP if
10138     // we are blocked to start an LCP anyway.
10139     // We also block LCP start if we have not completed one global checkpoints
10140     // before starting another local checkpoint.
10141     /* --------------------------------------------------------------------- */
10142     signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
10143     signal->theData[1] = __LINE__;
10144     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1 * 100, 2);
10145     return;
10146   }//if
10147   c_lcpState.setLcpStatus(LCP_TCGET, __LINE__);
10148 
10149   c_lcpState.ctcCounter = c_lcpState.ctimer;
10150   sendLoopMacro(TCGETOPSIZEREQ, sendTCGETOPSIZEREQ);
10151 }//Dbdih::checkTcCounterLab()
10152 
checkLcpStart(Signal * signal,Uint32 lineNo)10153 void Dbdih::checkLcpStart(Signal* signal, Uint32 lineNo)
10154 {
10155   /* ----------------------------------------------------------------------- */
10156   // Verify that we are not attempting to start another instance of the LCP
10157   // when it is not alright to do so.
10158   /* ----------------------------------------------------------------------- */
10159   ndbrequire(c_lcpState.lcpStart == ZIDLE);
10160   c_lcpState.lcpStart = ZACTIVE;
10161   signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
10162   signal->theData[1] = lineNo;
10163   sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
10164 }//Dbdih::checkLcpStart()
10165 
10166 /* ------------------------------------------------------------------------- */
10167 /*TCGETOPSIZECONF          HOW MUCH OPERATION SIZE HAVE BEEN EXECUTED BY TC  */
10168 /* ------------------------------------------------------------------------- */
execTCGETOPSIZECONF(Signal * signal)10169 void Dbdih::execTCGETOPSIZECONF(Signal* signal)
10170 {
10171   jamEntry();
10172   Uint32 senderNodeId = signal->theData[0];
10173   c_lcpState.ctcCounter += signal->theData[1];
10174 
10175   receiveLoopMacro(TCGETOPSIZEREQ, senderNodeId);
10176 
10177   ndbrequire(c_lcpState.lcpStatus == LCP_TCGET);
10178   ndbrequire(c_lcpState.lcpStart == ZACTIVE);
10179   /* ----------------------------------------------------------------------- */
10180   // We are not actively starting another LCP, still we receive this signal.
10181   // This is not ok.
10182   /* ---------------------------------------------------------------------- */
10183   /*    ALL TC'S HAVE RESPONDED NOW. NOW WE WILL CHECK IF ENOUGH OPERATIONS */
10184   /*    HAVE EXECUTED TO ENABLE US TO START A NEW LOCAL CHECKPOINT.         */
10185   /*    WHILE COPYING DICTIONARY AND DISTRIBUTION INFO TO A STARTING NODE   */
10186   /*    WE WILL ALSO NOT ALLOW THE LOCAL CHECKPOINT TO PROCEED.             */
10187   /*----------------------------------------------------------------------- */
10188   if (c_lcpState.immediateLcpStart == false) {
10189     if ((c_lcpState.ctcCounter <
10190 	 ((Uint32)1 << c_lcpState.clcpDelay)) ||
10191         (c_nodeStartMaster.blockLcp == true)) {
10192       jam();
10193       c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
10194 
10195       signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
10196       signal->theData[1] = __LINE__;
10197       sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1 * 100, 2);
10198       return;
10199     }//if
10200   }//if
10201   c_lcpState.lcpStart = ZIDLE;
10202   c_lcpState.immediateLcpStart = false;
10203   /* -----------------------------------------------------------------------
10204    * Now the initial lcp is started,
10205    * we can reset the delay to its orginal value
10206    * --------------------------------------------------------------------- */
10207   CRASH_INSERTION(7010);
10208   /* ----------------------------------------------------------------------- */
10209   /*     IF MORE THAN 1 MILLION WORDS PASSED THROUGH THE TC'S THEN WE WILL   */
10210   /*     START A NEW LOCAL CHECKPOINT. CLEAR CTIMER. START CHECKPOINT        */
10211   /*     ACTIVITY BY CALCULATING THE KEEP GLOBAL CHECKPOINT.                 */
10212   // Also remember the current global checkpoint to ensure that we run at least
10213   // one global checkpoints between each local checkpoint that we start up.
10214   /* ----------------------------------------------------------------------- */
10215   c_lcpState.ctimer = 0;
10216   c_lcpState.keepGci = coldgcp;
10217   /* ----------------------------------------------------------------------- */
10218   /*       UPDATE THE NEW LATEST LOCAL CHECKPOINT ID.                        */
10219   /* ----------------------------------------------------------------------- */
10220   cnoOfActiveTables = 0;
10221   c_lcpState.setLcpStatus(LCP_CALCULATE_KEEP_GCI, __LINE__);
10222   c_lcpState.oldestRestorableGci = SYSFILE->oldestRestorableGCI;
10223   ndbrequire(((int)c_lcpState.oldestRestorableGci) > 0);
10224 
10225   if (ERROR_INSERTED(7011)) {
10226     signal->theData[0] = NDB_LE_LCPStoppedInCalcKeepGci;
10227     signal->theData[1] = 0;
10228     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
10229     return;
10230   }//if
10231   signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
10232   signal->theData[1] = 0;  /* TABLE ID = 0          */
10233   signal->theData[2] = 0;  /* FRAGMENT ID = 0       */
10234   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
10235   return;
10236 }//Dbdih::execTCGETOPSIZECONF()
10237 
10238 /* ------------------------------------------------------------------------- */
10239 /*       WE NEED TO CALCULATE THE OLDEST GLOBAL CHECKPOINT THAT WILL BE      */
10240 /*       COMPLETELY RESTORABLE AFTER EXECUTING THIS LOCAL CHECKPOINT.        */
10241 /* ------------------------------------------------------------------------- */
calculateKeepGciLab(Signal * signal,Uint32 tableId,Uint32 fragId)10242 void Dbdih::calculateKeepGciLab(Signal* signal, Uint32 tableId, Uint32 fragId)
10243 {
10244   TabRecordPtr tabPtr;
10245   Uint32 TloopCount = 1;
10246   tabPtr.i = tableId;
10247   do {
10248     if (tabPtr.i >= ctabFileSize) {
10249       if (cnoOfActiveTables > 0) {
10250         jam();
10251         signal->theData[0] = DihContinueB::ZSTORE_NEW_LCP_ID;
10252         sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
10253         return;
10254       } else {
10255         jam();
10256 	/* ------------------------------------------------------------------ */
10257 	/* THERE ARE NO TABLES TO CHECKPOINT. WE STOP THE CHECKPOINT ALREADY  */
10258 	/* HERE TO AVOID STRANGE PROBLEMS LATER.                              */
10259 	/* ------------------------------------------------------------------ */
10260         c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
10261         checkLcpStart(signal, __LINE__);
10262         return;
10263       }//if
10264     }//if
10265     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
10266     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE ||
10267 	tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
10268       if (TloopCount > 100) {
10269         jam();
10270         signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
10271         signal->theData[1] = tabPtr.i + 1;
10272         signal->theData[2] = 0;
10273         sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
10274         return;
10275       } else {
10276         jam();
10277         TloopCount++;
10278         tabPtr.i++;
10279       }//if
10280     } else {
10281       jam();
10282       TloopCount = 0;
10283     }//if
10284   } while (TloopCount != 0);
10285   cnoOfActiveTables++;
10286   FragmentstorePtr fragPtr;
10287   getFragstore(tabPtr.p, fragId, fragPtr);
10288   checkKeepGci(tabPtr, fragId, fragPtr.p, fragPtr.p->storedReplicas);
10289   checkKeepGci(tabPtr, fragId, fragPtr.p, fragPtr.p->oldStoredReplicas);
10290   fragId++;
10291   if (fragId >= tabPtr.p->totalfragments) {
10292     jam();
10293     tabPtr.i++;
10294     fragId = 0;
10295   }//if
10296   signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
10297   signal->theData[1] = tabPtr.i;
10298   signal->theData[2] = fragId;
10299   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
10300   return;
10301 }//Dbdih::calculateKeepGciLab()
10302 
10303 /* ------------------------------------------------------------------------- */
10304 /*       WE NEED TO STORE ON DISK THE FACT THAT WE ARE STARTING THIS LOCAL   */
10305 /*       CHECKPOINT ROUND. THIS WILL INVALIDATE ALL THE LOCAL CHECKPOINTS    */
10306 /*       THAT WILL EVENTUALLY BE OVERWRITTEN AS PART OF THIS LOCAL CHECKPOINT*/
10307 /* ------------------------------------------------------------------------- */
storeNewLcpIdLab(Signal * signal)10308 void Dbdih::storeNewLcpIdLab(Signal* signal)
10309 {
10310   /***************************************************************************/
10311   // Report the event that a local checkpoint has started.
10312   /***************************************************************************/
10313   signal->theData[0] = NDB_LE_LocalCheckpointStarted; //Event type
10314   signal->theData[1] = SYSFILE->latestLCP_ID + 1;
10315   signal->theData[2] = c_lcpState.keepGci;
10316   signal->theData[3] = c_lcpState.oldestRestorableGci;
10317   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
10318 
10319   signal->setTrace(TestOrd::TraceLocalCheckpoint);
10320 
10321   CRASH_INSERTION(7013);
10322   SYSFILE->keepGCI = c_lcpState.keepGci;
10323   //Uint32 lcpId = SYSFILE->latestLCP_ID;
10324   SYSFILE->latestLCP_ID++;
10325   SYSFILE->oldestRestorableGCI = c_lcpState.oldestRestorableGci;
10326 
10327   const Uint32 oldestRestorableGCI = SYSFILE->oldestRestorableGCI;
10328   //const Uint32 newestRestorableGCI = SYSFILE->newestRestorableGCI;
10329   //ndbrequire(newestRestorableGCI >= oldestRestorableGCI);
10330 
10331   Int32 val = oldestRestorableGCI;
10332   ndbrequire(val > 0);
10333 
10334   /* ----------------------------------------------------------------------- */
10335   /* SET BIT INDICATING THAT LOCAL CHECKPOINT IS ONGOING. THIS IS CLEARED    */
10336   /* AT THE END OF A LOCAL CHECKPOINT.                                       */
10337   /* ----------------------------------------------------------------------- */
10338   SYSFILE->setLCPOngoing(SYSFILE->systemRestartBits);
10339   /* ---------------------------------------------------------------------- */
10340   /*    CHECK IF ANY NODE MUST BE TAKEN OUT OF SERVICE AND REFILLED WITH    */
10341   /*    NEW FRESH DATA FROM AN ACTIVE NODE.                                 */
10342   /* ---------------------------------------------------------------------- */
10343   setLcpActiveStatusStart(signal);
10344   c_lcpState.setLcpStatus(LCP_COPY_GCI, __LINE__);
10345   //#ifdef VM_TRACE
10346   //  infoEvent("LocalCheckpoint %d started", SYSFILE->latestLCP_ID);
10347   //  signal->theData[0] = 7012;
10348   //  execDUMP_STATE_ORD(signal);
10349   //#endif
10350 
10351   copyGciLab(signal, CopyGCIReq::LOCAL_CHECKPOINT);
10352 }//Dbdih::storeNewLcpIdLab()
10353 
startLcpRoundLab(Signal * signal)10354 void Dbdih::startLcpRoundLab(Signal* signal) {
10355   jam();
10356 
10357   Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
10358   Callback c = { safe_cast(&Dbdih::startLcpMutex_locked), 0 };
10359   ndbrequire(mutex.lock(c));
10360 }
10361 
10362 void
startLcpMutex_locked(Signal * signal,Uint32 senderData,Uint32 retVal)10363 Dbdih::startLcpMutex_locked(Signal* signal, Uint32 senderData, Uint32 retVal){
10364   jamEntry();
10365   ndbrequire(retVal == 0);
10366 
10367   StartLcpReq* req = (StartLcpReq*)signal->getDataPtrSend();
10368   req->senderRef = reference();
10369   req->lcpId = SYSFILE->latestLCP_ID;
10370   req->participatingLQH = c_lcpState.m_participatingLQH;
10371   req->participatingDIH = c_lcpState.m_participatingDIH;
10372   sendLoopMacro(START_LCP_REQ, sendSTART_LCP_REQ);
10373 }
10374 void
sendSTART_LCP_REQ(Signal * signal,Uint32 nodeId)10375 Dbdih::sendSTART_LCP_REQ(Signal* signal, Uint32 nodeId){
10376   BlockReference ref = calcDihBlockRef(nodeId);
10377   sendSignal(ref, GSN_START_LCP_REQ, signal, StartLcpReq::SignalLength, JBB);
10378 }
10379 
10380 void
execSTART_LCP_CONF(Signal * signal)10381 Dbdih::execSTART_LCP_CONF(Signal* signal){
10382   StartLcpConf * conf = (StartLcpConf*)signal->getDataPtr();
10383 
10384   Uint32 nodeId = refToNode(conf->senderRef);
10385   receiveLoopMacro(START_LCP_REQ, nodeId);
10386 
10387   Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
10388   Callback c = { safe_cast(&Dbdih::startLcpMutex_unlocked), 0 };
10389   mutex.unlock(c);
10390 }
10391 
10392 void
startLcpMutex_unlocked(Signal * signal,Uint32 data,Uint32 retVal)10393 Dbdih::startLcpMutex_unlocked(Signal* signal, Uint32 data, Uint32 retVal){
10394   jamEntry();
10395   ndbrequire(retVal == 0);
10396 
10397   Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
10398   mutex.release();
10399 
10400   CRASH_INSERTION(7014);
10401   c_lcpState.setLcpStatus(LCP_TC_CLOPSIZE, __LINE__);
10402   sendLoopMacro(TC_CLOPSIZEREQ, sendTC_CLOPSIZEREQ);
10403 }
10404 
execTC_CLOPSIZECONF(Signal * signal)10405 void Dbdih::execTC_CLOPSIZECONF(Signal* signal) {
10406   jamEntry();
10407   Uint32 senderNodeId = signal->theData[0];
10408   receiveLoopMacro(TC_CLOPSIZEREQ, senderNodeId);
10409 
10410   ndbrequire(c_lcpState.lcpStatus == LCP_TC_CLOPSIZE);
10411   /* ----------------------------------------------------------------------- */
10412   /*     ALL TC'S HAVE CLEARED THEIR OPERATION SIZE COUNTERS. NOW PROCEED BY */
10413   /*     STARTING THE LOCAL CHECKPOINT IN EACH LQH.                          */
10414   /* ----------------------------------------------------------------------- */
10415   c_lcpState.m_LAST_LCP_FRAG_ORD = c_lcpState.m_participatingLQH;
10416 
10417   CRASH_INSERTION(7015);
10418   c_lcpState.setLcpStatus(LCP_START_LCP_ROUND, __LINE__);
10419   startLcpRoundLoopLab(signal, 0, 0);
10420 }//Dbdih::execTC_CLOPSIZECONF()
10421 
startLcpRoundLoopLab(Signal * signal,Uint32 startTableId,Uint32 startFragId)10422 void Dbdih::startLcpRoundLoopLab(Signal* signal,
10423 				 Uint32 startTableId, Uint32 startFragId)
10424 {
10425   NodeRecordPtr nodePtr;
10426   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
10427     ptrAss(nodePtr, nodeRecord);
10428     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
10429       ndbrequire(nodePtr.p->noOfStartedChkpt == 0);
10430       ndbrequire(nodePtr.p->noOfQueuedChkpt == 0);
10431     }//if
10432   }//if
10433   c_lcpState.currentFragment.tableId = startTableId;
10434   c_lcpState.currentFragment.fragmentId = startFragId;
10435   startNextChkpt(signal);
10436 }//Dbdih::startLcpRoundLoopLab()
10437 
startNextChkpt(Signal * signal)10438 void Dbdih::startNextChkpt(Signal* signal)
10439 {
10440   Uint32 lcpId = SYSFILE->latestLCP_ID;
10441 
10442   NdbNodeBitmask busyNodes;
10443   busyNodes.clear();
10444   const Uint32 lcpNodes = c_lcpState.m_participatingLQH.count();
10445 
10446   bool save = true;
10447   LcpState::CurrentFragment curr = c_lcpState.currentFragment;
10448 
10449   while (curr.tableId < ctabFileSize) {
10450     TabRecordPtr tabPtr;
10451     tabPtr.i = curr.tableId;
10452     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
10453     if ((tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) ||
10454         (tabPtr.p->tabLcpStatus != TabRecord::TLS_ACTIVE)) {
10455       curr.tableId++;
10456       curr.fragmentId = 0;
10457       continue;
10458     }//if
10459 
10460     FragmentstorePtr fragPtr;
10461     getFragstore(tabPtr.p, curr.fragmentId, fragPtr);
10462 
10463     ReplicaRecordPtr replicaPtr;
10464     for(replicaPtr.i = fragPtr.p->storedReplicas;
10465 	replicaPtr.i != RNIL ;
10466 	replicaPtr.i = replicaPtr.p->nextReplica){
10467 
10468       jam();
10469       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
10470 
10471       NodeRecordPtr nodePtr;
10472       nodePtr.i = replicaPtr.p->procNode;
10473       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
10474 
10475       if (c_lcpState.m_participatingLQH.get(nodePtr.i))
10476       {
10477 	if (replicaPtr.p->lcpOngoingFlag &&
10478 	    replicaPtr.p->lcpIdStarted < lcpId)
10479 	{
10480 	  jam();
10481 	  //-------------------------------------------------------------------
10482 	  // We have found a replica on a node that performs local checkpoint
10483 	  // that is alive and that have not yet been started.
10484 	  //-------------------------------------------------------------------
10485 
10486 	  if (nodePtr.p->noOfStartedChkpt < 2)
10487 	  {
10488 	    jam();
10489 	    /**
10490 	     * Send LCP_FRAG_ORD to LQH
10491 	     */
10492 
10493 	    /**
10494 	     * Mark the replica so with lcpIdStarted == true
10495 	     */
10496 	    replicaPtr.p->lcpIdStarted = lcpId;
10497 
10498 	    Uint32 i = nodePtr.p->noOfStartedChkpt;
10499 	    nodePtr.p->startedChkpt[i].tableId = tabPtr.i;
10500 	    nodePtr.p->startedChkpt[i].fragId = curr.fragmentId;
10501 	    nodePtr.p->startedChkpt[i].replicaPtr = replicaPtr.i;
10502 	    nodePtr.p->noOfStartedChkpt = i + 1;
10503 
10504 	    sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
10505 	  }
10506 	  else if (nodePtr.p->noOfQueuedChkpt < 2)
10507 	  {
10508 	    jam();
10509 	    /**
10510 	     * Put LCP_FRAG_ORD "in queue"
10511 	     */
10512 
10513 	    /**
10514 	     * Mark the replica so with lcpIdStarted == true
10515 	     */
10516 	    replicaPtr.p->lcpIdStarted = lcpId;
10517 
10518 	    Uint32 i = nodePtr.p->noOfQueuedChkpt;
10519 	    nodePtr.p->queuedChkpt[i].tableId = tabPtr.i;
10520 	    nodePtr.p->queuedChkpt[i].fragId = curr.fragmentId;
10521 	    nodePtr.p->queuedChkpt[i].replicaPtr = replicaPtr.i;
10522 	    nodePtr.p->noOfQueuedChkpt = i + 1;
10523 	  }
10524 	  else
10525 	  {
10526 	    jam();
10527 
10528 	    if(save)
10529 	    {
10530 	      /**
10531 	       * Stop increasing value on first that was "full"
10532 	       */
10533 	      c_lcpState.currentFragment = curr;
10534 	      save = false;
10535 	    }
10536 
10537 	    busyNodes.set(nodePtr.i);
10538 	    if(busyNodes.count() == lcpNodes)
10539 	    {
10540 	      /**
10541 	       * There were no possibility to start the local checkpoint
10542 	       * and it was not possible to queue it up. In this case we
10543 	       * stop the start of local checkpoints until the nodes with a
10544 	       * backlog have performed more checkpoints. We will return and
10545 	       * will not continue the process of starting any more checkpoints.
10546 	       */
10547 	      return;
10548 	    }//if
10549 	  }//if
10550 	}
10551       }//while
10552     }
10553     curr.fragmentId++;
10554     if (curr.fragmentId >= tabPtr.p->totalfragments) {
10555       jam();
10556       curr.fragmentId = 0;
10557       curr.tableId++;
10558     }//if
10559   }//while
10560 
10561   sendLastLCP_FRAG_ORD(signal);
10562 }//Dbdih::startNextChkpt()
10563 
sendLastLCP_FRAG_ORD(Signal * signal)10564 void Dbdih::sendLastLCP_FRAG_ORD(Signal* signal)
10565 {
10566   LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
10567   lcpFragOrd->tableId = RNIL;
10568   lcpFragOrd->fragmentId = 0;
10569   lcpFragOrd->lcpId = SYSFILE->latestLCP_ID;
10570   lcpFragOrd->lcpNo = 0;
10571   lcpFragOrd->keepGci = c_lcpState.keepGci;
10572   lcpFragOrd->lastFragmentFlag = true;
10573 
10574   NodeRecordPtr nodePtr;
10575   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
10576     jam();
10577     ptrAss(nodePtr, nodeRecord);
10578 
10579     if(nodePtr.p->noOfQueuedChkpt == 0 &&
10580        nodePtr.p->noOfStartedChkpt == 0 &&
10581        c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodePtr.i)){
10582       jam();
10583 
10584       CRASH_INSERTION(7028);
10585 
10586       /**
10587        * Nothing queued or started <=> Complete on that node
10588        *
10589        */
10590       c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor(nodePtr.i);
10591       if(ERROR_INSERTED(7075)){
10592 	continue;
10593       }
10594 
10595       CRASH_INSERTION(7193);
10596       BlockReference ref = calcLqhBlockRef(nodePtr.i);
10597       sendSignal(ref, GSN_LCP_FRAG_ORD, signal,LcpFragOrd::SignalLength, JBB);
10598     }
10599   }
10600   if(ERROR_INSERTED(7075)){
10601     if(c_lcpState.m_LAST_LCP_FRAG_ORD.done())
10602       CRASH_INSERTION(7075);
10603   }
10604 }//Dbdih::sendLastLCP_FRAGORD()
10605 
10606 /* ------------------------------------------------------------------------- */
10607 /*       A FRAGMENT REPLICA HAS COMPLETED EXECUTING ITS LOCAL CHECKPOINT.    */
10608 /*       CHECK IF ALL REPLICAS IN THE TABLE HAVE COMPLETED. IF SO STORE THE  */
10609 /*       THE TABLE DISTRIBUTION ON DISK. ALSO SEND LCP_REPORT TO ALL OTHER   */
10610 /*       NODES SO THAT THEY CAN STORE THE TABLE ONTO DISK AS WELL.           */
10611 /* ------------------------------------------------------------------------- */
execLCP_FRAG_REP(Signal * signal)10612 void Dbdih::execLCP_FRAG_REP(Signal* signal)
10613 {
10614   jamEntry();
10615   ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
10616 
10617 #if 0
10618   printLCP_FRAG_REP(stdout,
10619 		    signal->getDataPtr(),
10620 		    signal->length(), number());
10621 #endif
10622 
10623   LcpFragRep * const lcpReport = (LcpFragRep *)&signal->theData[0];
10624   Uint32 nodeId = lcpReport->nodeId;
10625   Uint32 tableId = lcpReport->tableId;
10626   Uint32 fragId = lcpReport->fragId;
10627 
10628   jamEntry();
10629 
10630   if (ERROR_INSERTED(7178) && nodeId != getOwnNodeId())
10631   {
10632     jam();
10633     Uint32 owng =Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
10634     Uint32 nodeg = Sysfile::getNodeGroup(nodeId, SYSFILE->nodeGroups);
10635     if (owng == nodeg)
10636     {
10637       jam();
10638       ndbout_c("throwing away LCP_FRAG_REP from  (and killing) %d", nodeId);
10639       SET_ERROR_INSERT_VALUE(7179);
10640       signal->theData[0] = 9999;
10641       sendSignal(numberToRef(CMVMI, nodeId),
10642 		 GSN_NDB_TAMPER, signal, 1, JBA);
10643       return;
10644     }
10645   }
10646 
10647   if (ERROR_INSERTED(7179) && nodeId != getOwnNodeId())
10648   {
10649     jam();
10650     Uint32 owng =Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
10651     Uint32 nodeg = Sysfile::getNodeGroup(nodeId, SYSFILE->nodeGroups);
10652     if (owng == nodeg)
10653     {
10654       jam();
10655       ndbout_c("throwing away LCP_FRAG_REP from %d", nodeId);
10656       return;
10657     }
10658   }
10659 
10660   CRASH_INSERTION2(7025, isMaster());
10661   CRASH_INSERTION2(7016, !isMaster());
10662 
10663   bool fromTimeQueue = (signal->senderBlockRef() == reference());
10664 
10665   TabRecordPtr tabPtr;
10666   tabPtr.i = tableId;
10667   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
10668   if(tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
10669     jam();
10670     /*-----------------------------------------------------------------------*/
10671     // If the table is currently copied to disk we also
10672     // stop already here to avoid strange half-way updates
10673     // of the table data structures.
10674     /*-----------------------------------------------------------------------*/
10675     /*
10676       We need to send this signal without a delay since we have discovered
10677       that we have run out of space in the short time queue. This problem
10678       is very erunlikely to happen but it has and it results in a node crash.
10679       This should be considered a "quick fix" and not a permanent solution.
10680       A cleaner/better way would be to check the time queue if it is full or
10681       not before sending this signal.
10682     */
10683     sendSignal(reference(), GSN_LCP_FRAG_REP, signal, signal->length(), JBB);
10684     /* Kept here for reference
10685        sendSignalWithDelay(reference(), GSN_LCP_FRAG_REP,
10686        signal, 20, signal->length());
10687     */
10688 
10689     if(!fromTimeQueue){
10690       c_lcpState.noOfLcpFragRepOutstanding++;
10691     }
10692 
10693     return;
10694   }//if
10695 
10696   if(fromTimeQueue){
10697     jam();
10698 
10699     ndbrequire(c_lcpState.noOfLcpFragRepOutstanding > 0);
10700     c_lcpState.noOfLcpFragRepOutstanding--;
10701   }
10702 
10703   bool tableDone = reportLcpCompletion(lcpReport);
10704 
10705   Uint32 started = lcpReport->maxGciStarted;
10706   Uint32 completed = lcpReport->maxGciCompleted;
10707 
10708   if (started > c_lcpState.lcpStopGcp)
10709   {
10710     jam();
10711     c_lcpState.lcpStopGcp = started;
10712   }
10713 
10714   if(tableDone){
10715     jam();
10716 
10717     if(tabPtr.p->tabStatus == TabRecord::TS_DROPPING){
10718       jam();
10719       g_eventLogger.info("TS_DROPPING - Neglecting to save Table: %d Frag: %d - ",
10720                          tableId, fragId);
10721     } else {
10722       jam();
10723       /**
10724        * Write table description to file
10725        */
10726       tabPtr.p->tabLcpStatus = TabRecord::TLS_WRITING_TO_FILE;
10727       tabPtr.p->tabCopyStatus = TabRecord::CS_LCP_READ_TABLE;
10728       tabPtr.p->tabUpdateState = TabRecord::US_LOCAL_CHECKPOINT;
10729       signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
10730       signal->theData[1] = tabPtr.i;
10731       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
10732 
10733       checkLcpAllTablesDoneInLqh();
10734     }
10735   }
10736 
10737 #ifdef VM_TRACE
10738   /* --------------------------------------------------------------------- */
10739   // REPORT that local checkpoint have completed this fragment.
10740   /* --------------------------------------------------------------------- */
10741   signal->theData[0] = NDB_LE_LCPFragmentCompleted;
10742   signal->theData[1] = nodeId;
10743   signal->theData[2] = tableId;
10744   signal->theData[3] = fragId;
10745   signal->theData[4] = started;
10746   signal->theData[5] = completed;
10747   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB);
10748 #endif
10749 
10750   bool ok = false;
10751   switch(c_lcpMasterTakeOverState.state){
10752   case LMTOS_IDLE:
10753     ok = true;
10754     jam();
10755     /**
10756      * Fall through
10757      */
10758     break;
10759   case LMTOS_WAIT_EMPTY_LCP: // LCP Take over waiting for EMPTY_LCPCONF
10760     jam();
10761     return;
10762   case LMTOS_WAIT_LCP_FRAG_REP:
10763     jam();
10764     checkEmptyLcpComplete(signal);
10765     return;
10766   case LMTOS_INITIAL:
10767   case LMTOS_ALL_IDLE:
10768   case LMTOS_ALL_ACTIVE:
10769   case LMTOS_LCP_CONCLUDING:
10770   case LMTOS_COPY_ONGOING:
10771     ndbrequire(false);
10772   }
10773   ndbrequire(ok);
10774 
10775   /* ----------------------------------------------------------------------- */
10776   // Check if there are more LCP's to start up.
10777   /* ----------------------------------------------------------------------- */
10778   if(isMaster()){
10779     jam();
10780 
10781     /**
10782      * Remove from "running" array
10783      */
10784     NodeRecordPtr nodePtr;
10785     nodePtr.i = nodeId;
10786     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
10787 
10788     const Uint32 outstanding = nodePtr.p->noOfStartedChkpt;
10789     ndbrequire(outstanding > 0);
10790     if(nodePtr.p->startedChkpt[0].tableId != tableId ||
10791        nodePtr.p->startedChkpt[0].fragId != fragId){
10792       jam();
10793       ndbrequire(outstanding > 1);
10794       ndbrequire(nodePtr.p->startedChkpt[1].tableId == tableId);
10795       ndbrequire(nodePtr.p->startedChkpt[1].fragId == fragId);
10796     } else {
10797       jam();
10798       nodePtr.p->startedChkpt[0] = nodePtr.p->startedChkpt[1];
10799     }
10800     nodePtr.p->noOfStartedChkpt--;
10801     checkStartMoreLcp(signal, nodeId);
10802   }
10803 }
10804 
10805 bool
checkLcpAllTablesDoneInLqh()10806 Dbdih::checkLcpAllTablesDoneInLqh(){
10807   TabRecordPtr tabPtr;
10808 
10809   /**
10810    * Check if finished with all tables
10811    */
10812   for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
10813     jam();
10814     ptrAss(tabPtr, tabRecord);
10815     if ((tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) &&
10816         (tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE)) {
10817       jam();
10818       /**
10819        * Nope, not finished with all tables
10820        */
10821       return false;
10822     }//if
10823   }//for
10824 
10825   CRASH_INSERTION2(7026, isMaster());
10826   CRASH_INSERTION2(7017, !isMaster());
10827 
10828   c_lcpState.setLcpStatus(LCP_TAB_COMPLETED, __LINE__);
10829 
10830   if (ERROR_INSERTED(7194))
10831   {
10832     ndbout_c("CLEARING 7194");
10833     CLEAR_ERROR_INSERT_VALUE;
10834   }
10835 
10836   return true;
10837 }
10838 
findReplica(ReplicaRecordPtr & replicaPtr,Fragmentstore * fragPtrP,Uint32 nodeId,bool old)10839 void Dbdih::findReplica(ReplicaRecordPtr& replicaPtr,
10840 			Fragmentstore* fragPtrP,
10841 			Uint32 nodeId,
10842 			bool old)
10843 {
10844   replicaPtr.i = old ? fragPtrP->oldStoredReplicas : fragPtrP->storedReplicas;
10845   while(replicaPtr.i != RNIL){
10846     ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
10847     if (replicaPtr.p->procNode == nodeId) {
10848       jam();
10849       return;
10850     } else {
10851       jam();
10852       replicaPtr.i = replicaPtr.p->nextReplica;
10853     }//if
10854   };
10855 
10856 #ifdef VM_TRACE
10857   g_eventLogger.info("Fragment Replica(node=%d) not found", nodeId);
10858   replicaPtr.i = fragPtrP->oldStoredReplicas;
10859   while(replicaPtr.i != RNIL){
10860     ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
10861     if (replicaPtr.p->procNode == nodeId) {
10862       jam();
10863       break;
10864     } else {
10865       jam();
10866       replicaPtr.i = replicaPtr.p->nextReplica;
10867     }//if
10868   };
10869   if(replicaPtr.i != RNIL){
10870     g_eventLogger.info("...But was found in oldStoredReplicas");
10871   } else {
10872     g_eventLogger.info("...And wasn't found in oldStoredReplicas");
10873   }
10874 #endif
10875   ndbrequire(false);
10876 }//Dbdih::findReplica()
10877 
10878 
10879 int
handle_invalid_lcp_no(const LcpFragRep * rep,ReplicaRecordPtr replicaPtr)10880 Dbdih::handle_invalid_lcp_no(const LcpFragRep* rep,
10881 			     ReplicaRecordPtr replicaPtr)
10882 {
10883   ndbrequire(!isMaster());
10884   Uint32 lcpNo = rep->lcpNo;
10885   Uint32 lcpId = rep->lcpId;
10886 
10887   warningEvent("Detected previous node failure of %d during lcp",
10888 	       rep->nodeId);
10889   replicaPtr.p->nextLcp = lcpNo;
10890   replicaPtr.p->lcpId[lcpNo] = 0;
10891   replicaPtr.p->lcpStatus[lcpNo] = ZINVALID;
10892 
10893   for (Uint32 i = lcpNo; i != lcpNo; i = nextLcpNo(i))
10894   {
10895     jam();
10896     if (replicaPtr.p->lcpStatus[i] == ZVALID &&
10897 	replicaPtr.p->lcpId[i] >= lcpId)
10898     {
10899       ndbout_c("i: %d lcpId: %d", i, replicaPtr.p->lcpId[i]);
10900       ndbrequire(false);
10901     }
10902   }
10903 
10904   return 0;
10905 }
10906 
10907 /**
10908  * Return true  if table is all fragment replicas have been checkpointed
10909  *                 to disk (in all LQHs)
10910  *        false otherwise
10911  */
10912 bool
reportLcpCompletion(const LcpFragRep * lcpReport)10913 Dbdih::reportLcpCompletion(const LcpFragRep* lcpReport)
10914 {
10915   Uint32 lcpNo = lcpReport->lcpNo;
10916   Uint32 lcpId = lcpReport->lcpId;
10917   Uint32 maxGciStarted = lcpReport->maxGciStarted;
10918   Uint32 maxGciCompleted = lcpReport->maxGciCompleted;
10919   Uint32 tableId = lcpReport->tableId;
10920   Uint32 fragId = lcpReport->fragId;
10921   Uint32 nodeId = lcpReport->nodeId;
10922 
10923   TabRecordPtr tabPtr;
10924   tabPtr.i = tableId;
10925   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
10926 
10927   FragmentstorePtr fragPtr;
10928   getFragstore(tabPtr.p, fragId, fragPtr);
10929 
10930   ReplicaRecordPtr replicaPtr;
10931   findReplica(replicaPtr, fragPtr.p, nodeId);
10932 
10933   ndbrequire(replicaPtr.p->lcpOngoingFlag == true);
10934   if(lcpNo != replicaPtr.p->nextLcp){
10935     if (handle_invalid_lcp_no(lcpReport, replicaPtr))
10936     {
10937       g_eventLogger.error("lcpNo = %d replicaPtr.p->nextLcp = %d",
10938                           lcpNo, replicaPtr.p->nextLcp);
10939       ndbrequire(false);
10940     }
10941   }
10942   ndbrequire(lcpNo == replicaPtr.p->nextLcp);
10943   ndbrequire(lcpNo < MAX_LCP_STORED);
10944   ndbrequire(replicaPtr.p->lcpId[lcpNo] != lcpId);
10945 
10946   replicaPtr.p->lcpIdStarted = lcpId;
10947   replicaPtr.p->lcpOngoingFlag = false;
10948 
10949   removeOldCrashedReplicas(replicaPtr);
10950   replicaPtr.p->lcpId[lcpNo] = lcpId;
10951   replicaPtr.p->lcpStatus[lcpNo] = ZVALID;
10952   replicaPtr.p->maxGciStarted[lcpNo] = maxGciStarted;
10953   gth(maxGciStarted + 1, 0);
10954   replicaPtr.p->maxGciCompleted[lcpNo] = maxGciCompleted;
10955   replicaPtr.p->nextLcp = nextLcpNo(replicaPtr.p->nextLcp);
10956 
10957   ndbrequire(fragPtr.p->noLcpReplicas > 0);
10958   fragPtr.p->noLcpReplicas --;
10959 
10960   if(fragPtr.p->noLcpReplicas > 0){
10961     jam();
10962     return false;
10963   }
10964 
10965   for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
10966     jam();
10967     getFragstore(tabPtr.p, fid, fragPtr);
10968     if (fragPtr.p->noLcpReplicas > 0){
10969       jam();
10970       /* ----------------------------------------------------------------- */
10971       // Not all fragments in table have been checkpointed.
10972       /* ----------------------------------------------------------------- */
10973       if(0)
10974 	g_eventLogger.info("reportLcpCompletion: fragment %d not ready", fid);
10975       return false;
10976     }//if
10977   }//for
10978   return true;
10979 }//Dbdih::reportLcpCompletion()
10980 
checkStartMoreLcp(Signal * signal,Uint32 nodeId)10981 void Dbdih::checkStartMoreLcp(Signal* signal, Uint32 nodeId)
10982 {
10983   ndbrequire(isMaster());
10984 
10985   NodeRecordPtr nodePtr;
10986   nodePtr.i = nodeId;
10987   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
10988 
10989   ndbrequire(nodePtr.p->noOfStartedChkpt < 2);
10990 
10991   if (nodePtr.p->noOfQueuedChkpt > 0) {
10992     jam();
10993     nodePtr.p->noOfQueuedChkpt--;
10994     Uint32 i = nodePtr.p->noOfStartedChkpt;
10995     nodePtr.p->startedChkpt[i] = nodePtr.p->queuedChkpt[0];
10996     nodePtr.p->queuedChkpt[0] = nodePtr.p->queuedChkpt[1];
10997     //-------------------------------------------------------------------
10998     // We can send a LCP_FRAGORD to the node ordering it to perform a
10999     // local checkpoint on this fragment replica.
11000     //-------------------------------------------------------------------
11001     nodePtr.p->noOfStartedChkpt = i + 1;
11002 
11003     sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
11004   }
11005 
11006   /* ----------------------------------------------------------------------- */
11007   // When there are no more outstanding LCP reports and there are no one queued
11008   // in at least one node, then we are ready to make sure all nodes have at
11009   // least two outstanding LCP requests per node and at least two queued for
11010   // sending.
11011   /* ----------------------------------------------------------------------- */
11012   startNextChkpt(signal);
11013 }//Dbdih::checkStartMoreLcp()
11014 
11015 void
sendLCP_FRAG_ORD(Signal * signal,NodeRecord::FragmentCheckpointInfo info)11016 Dbdih::sendLCP_FRAG_ORD(Signal* signal,
11017 			NodeRecord::FragmentCheckpointInfo info){
11018 
11019   ReplicaRecordPtr replicaPtr;
11020   replicaPtr.i = info.replicaPtr;
11021   ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
11022 
11023   BlockReference ref = calcLqhBlockRef(replicaPtr.p->procNode);
11024 
11025   if (ERROR_INSERTED(7193) && replicaPtr.p->procNode == getOwnNodeId())
11026   {
11027     return;
11028   }
11029 
11030   LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
11031   lcpFragOrd->tableId    = info.tableId;
11032   lcpFragOrd->fragmentId = info.fragId;
11033   lcpFragOrd->lcpId      = SYSFILE->latestLCP_ID;
11034   lcpFragOrd->lcpNo      = replicaPtr.p->nextLcp;
11035   lcpFragOrd->keepGci    = c_lcpState.keepGci;
11036   lcpFragOrd->lastFragmentFlag = false;
11037   sendSignal(ref, GSN_LCP_FRAG_ORD, signal, LcpFragOrd::SignalLength, JBB);
11038 }
11039 
checkLcpCompletedLab(Signal * signal)11040 void Dbdih::checkLcpCompletedLab(Signal* signal)
11041 {
11042   if(c_lcpState.lcpStatus < LCP_TAB_COMPLETED){
11043     jam();
11044     return;
11045   }
11046 
11047   TabRecordPtr tabPtr;
11048   for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
11049     jam();
11050     ptrAss(tabPtr, tabRecord);
11051     if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
11052       if (tabPtr.p->tabLcpStatus != TabRecord::TLS_COMPLETED) {
11053         jam();
11054         return;
11055       }//if
11056     }//if
11057   }//for
11058 
11059   CRASH_INSERTION2(7027, isMaster());
11060   CRASH_INSERTION2(7018, !isMaster());
11061 
11062   if(c_lcpState.lcpStatus == LCP_TAB_COMPLETED){
11063     /**
11064      * We'r done
11065      */
11066     c_lcpState.setLcpStatus(LCP_TAB_SAVED, __LINE__);
11067     sendLCP_COMPLETE_REP(signal);
11068     return;
11069   }
11070 
11071   ndbrequire(c_lcpState.lcpStatus == LCP_TAB_SAVED);
11072   allNodesLcpCompletedLab(signal);
11073   return;
11074 }//Dbdih::checkLcpCompletedLab()
11075 
11076 void
sendLCP_COMPLETE_REP(Signal * signal)11077 Dbdih::sendLCP_COMPLETE_REP(Signal* signal){
11078   jam();
11079   LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
11080   rep->nodeId = getOwnNodeId();
11081   rep->lcpId = SYSFILE->latestLCP_ID;
11082   rep->blockNo = DBDIH;
11083 
11084   sendSignal(c_lcpState.m_masterLcpDihRef, GSN_LCP_COMPLETE_REP, signal,
11085 	     LcpCompleteRep::SignalLength, JBB);
11086 
11087   /**
11088    * Say that an initial node restart does not need to be redone
11089    *   once node has been part of first LCP
11090    */
11091   if (c_set_initial_start_flag &&
11092       c_lcpState.m_participatingLQH.get(getOwnNodeId()))
11093   {
11094     jam();
11095     c_set_initial_start_flag = FALSE;
11096   }
11097 }
11098 
11099 /*-------------------------------------------------------------------------- */
11100 /* COMP_LCP_ROUND                   A LQH HAS COMPLETED A LOCAL CHECKPOINT  */
11101 /*------------------------------------------------------------------------- */
execLCP_COMPLETE_REP(Signal * signal)11102 void Dbdih::execLCP_COMPLETE_REP(Signal* signal)
11103 {
11104   jamEntry();
11105 
11106   CRASH_INSERTION(7191);
11107 
11108 #if 0
11109   g_eventLogger.info("LCP_COMPLETE_REP");
11110   printLCP_COMPLETE_REP(stdout,
11111 			signal->getDataPtr(),
11112 			signal->length(), number());
11113 #endif
11114 
11115   LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtr();
11116   Uint32 lcpId = rep->lcpId;
11117   Uint32 nodeId = rep->nodeId;
11118   Uint32 blockNo = rep->blockNo;
11119 
11120   if(c_lcpMasterTakeOverState.state > LMTOS_WAIT_LCP_FRAG_REP){
11121     jam();
11122     /**
11123      * Don't allow LCP_COMPLETE_REP to arrive during
11124      * LCP master take over
11125      */
11126     ndbrequire(isMaster());
11127     ndbrequire(blockNo == DBDIH);
11128     sendSignalWithDelay(reference(), GSN_LCP_COMPLETE_REP, signal, 100,
11129 			signal->length());
11130     return;
11131   }
11132 
11133   ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
11134 
11135   switch(blockNo){
11136   case DBLQH:
11137     jam();
11138     c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.clearWaitingFor(nodeId);
11139     ndbrequire(!c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodeId));
11140     break;
11141   case DBDIH:
11142     jam();
11143     ndbrequire(isMaster());
11144     c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.clearWaitingFor(nodeId);
11145     break;
11146   case 0:
11147     jam();
11148     ndbrequire(!isMaster());
11149     ndbrequire(c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received == false);
11150     c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received = true;
11151     break;
11152   default:
11153     ndbrequire(false);
11154   }
11155   ndbrequire(lcpId == SYSFILE->latestLCP_ID);
11156 
11157   allNodesLcpCompletedLab(signal);
11158   return;
11159 }
11160 
allNodesLcpCompletedLab(Signal * signal)11161 void Dbdih::allNodesLcpCompletedLab(Signal* signal)
11162 {
11163   jam();
11164 
11165   if (c_lcpState.lcpStatus != LCP_TAB_SAVED) {
11166     jam();
11167     /**
11168      * We have not sent LCP_COMPLETE_REP to master DIH yet
11169      */
11170     return;
11171   }//if
11172 
11173   if (!c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.done()){
11174     jam();
11175     return;
11176   }
11177 
11178   if (!c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.done()){
11179     jam();
11180     return;
11181   }
11182 
11183   if (!isMaster() &&
11184       c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received == false){
11185     jam();
11186     /**
11187      * Wait until master DIH has signaled lcp is complete
11188      */
11189     return;
11190   }
11191 
11192   if(c_lcpMasterTakeOverState.state != LMTOS_IDLE){
11193     jam();
11194 #ifdef VM_TRACE
11195     g_eventLogger.info("Exiting from allNodesLcpCompletedLab");
11196 #endif
11197     return;
11198   }
11199 
11200 
11201   /*------------------------------------------------------------------------ */
11202   /*     WE HAVE NOW COMPLETED A LOCAL CHECKPOINT. WE ARE NOW READY TO WAIT  */
11203   /*     FOR THE NEXT LOCAL CHECKPOINT. SEND WITHOUT TIME-OUT SINCE IT MIGHT */
11204   /*     BE TIME TO START THE NEXT LOCAL CHECKPOINT IMMEDIATELY.             */
11205   /*     CLEAR BIT 3 OF SYSTEM RESTART BITS TO INDICATE THAT THERE IS NO     */
11206   /*     LOCAL CHECKPOINT ONGOING. THIS WILL BE WRITTEN AT SOME LATER TIME   */
11207   /*     DURING A GLOBAL CHECKPOINT. IT IS NOT NECESSARY TO WRITE IT         */
11208   /*     IMMEDIATELY. WE WILL ALSO CLEAR BIT 2 OF SYSTEM RESTART BITS IF ALL */
11209   /*     CURRENTLY ACTIVE NODES COMPLETED THE LOCAL CHECKPOINT.              */
11210   /*------------------------------------------------------------------------ */
11211   CRASH_INSERTION(7019);
11212   signal->setTrace(0);
11213 
11214   c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
11215   setLcpActiveStatusEnd();
11216   Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
11217 
11218   if(!isMaster()){
11219     jam();
11220     /**
11221      * We're not master, be content
11222      */
11223     return;
11224   }
11225 
11226   // Send LCP_COMPLETE_REP to all other nodes
11227   // allowing them to set their lcpStatus to LCP_STATUS_IDLE
11228   LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
11229   rep->nodeId = getOwnNodeId();
11230   rep->lcpId = SYSFILE->latestLCP_ID;
11231   rep->blockNo = 0; // 0 = Sent from master
11232 
11233   NodeRecordPtr nodePtr;
11234   nodePtr.i = cfirstAliveNode;
11235   do {
11236     jam();
11237     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
11238     if (nodePtr.i != cownNodeId){
11239       BlockReference ref = calcDihBlockRef(nodePtr.i);
11240       sendSignal(ref, GSN_LCP_COMPLETE_REP, signal,
11241 		 LcpCompleteRep::SignalLength, JBB);
11242     }
11243     nodePtr.i = nodePtr.p->nextNode;
11244   } while (nodePtr.i != RNIL);
11245 
11246 
11247   jam();
11248   /***************************************************************************/
11249   // Report the event that a local checkpoint has completed.
11250   /***************************************************************************/
11251   signal->theData[0] = NDB_LE_LocalCheckpointCompleted; //Event type
11252   signal->theData[1] = SYSFILE->latestLCP_ID;
11253   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
11254 
11255   if (c_newest_restorable_gci > c_lcpState.lcpStopGcp)
11256   {
11257     jam();
11258     c_lcpState.lcpStopGcp = c_newest_restorable_gci;
11259   }
11260 
11261   /**
11262    * Start checking for next LCP
11263    */
11264   checkLcpStart(signal, __LINE__);
11265 
11266   if (cwaitLcpSr == true) {
11267     jam();
11268     cwaitLcpSr = false;
11269     ndbsttorry10Lab(signal, __LINE__);
11270     return;
11271   }//if
11272 
11273   if (c_nodeStartMaster.blockLcp == true) {
11274     jam();
11275     lcpBlockedLab(signal);
11276     return;
11277   }//if
11278   return;
11279 }//Dbdih::allNodesLcpCompletedLab()
11280 
11281 /******************************************************************************/
11282 /* **********     TABLE UPDATE MODULE                             *************/
11283 /* ****************************************************************************/
11284 /* ------------------------------------------------------------------------- */
11285 /*       THIS MODULE IS USED TO UPDATE THE TABLE DESCRIPTION. IT STARTS BY   */
11286 /*       CREATING THE FIRST TABLE FILE, THEN UPDATES THIS FILE AND CLOSES IT.*/
11287 /*       AFTER THAT THE SAME HAPPENS WITH THE SECOND FILE. AFTER THAT THE    */
11288 /*       TABLE DISTRIBUTION HAS BEEN UPDATED.                                */
11289 /*                                                                           */
11290 /*       THE REASON FOR CREATING THE FILE AND NOT OPENING IT IS TO ENSURE    */
11291 /*       THAT WE DO NOT GET A MIX OF OLD AND NEW INFORMATION IN THE FILE IN  */
11292 /*       ERROR SITUATIONS.                                                   */
11293 /* ------------------------------------------------------------------------- */
tableUpdateLab(Signal * signal,TabRecordPtr tabPtr)11294 void Dbdih::tableUpdateLab(Signal* signal, TabRecordPtr tabPtr) {
11295   FileRecordPtr filePtr;
11296   if(tabPtr.p->tabStorage == TabRecord::ST_TEMPORARY) {
11297     // For temporary tables we do not write to disk. Mark both copies 0 and 1
11298     // as done, and go straight to the after-close code.
11299     filePtr.i = tabPtr.p->tabFile[1];
11300     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
11301     tableCloseLab(signal, filePtr);
11302     return;
11303   }
11304   filePtr.i = tabPtr.p->tabFile[0];
11305   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
11306   createFileRw(signal, filePtr);
11307   filePtr.p->reqStatus = FileRecord::TABLE_CREATE;
11308   return;
11309 }//Dbdih::tableUpdateLab()
11310 
tableCreateLab(Signal * signal,FileRecordPtr filePtr)11311 void Dbdih::tableCreateLab(Signal* signal, FileRecordPtr filePtr)
11312 {
11313   TabRecordPtr tabPtr;
11314   tabPtr.i = filePtr.p->tabRef;
11315   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11316   writeTabfile(signal, tabPtr.p, filePtr);
11317   filePtr.p->reqStatus = FileRecord::TABLE_WRITE;
11318   return;
11319 }//Dbdih::tableCreateLab()
11320 
tableWriteLab(Signal * signal,FileRecordPtr filePtr)11321 void Dbdih::tableWriteLab(Signal* signal, FileRecordPtr filePtr)
11322 {
11323   closeFile(signal, filePtr);
11324   filePtr.p->reqStatus = FileRecord::TABLE_CLOSE;
11325   return;
11326 }//Dbdih::tableWriteLab()
11327 
tableCloseLab(Signal * signal,FileRecordPtr filePtr)11328 void Dbdih::tableCloseLab(Signal* signal, FileRecordPtr filePtr)
11329 {
11330   TabRecordPtr tabPtr;
11331   tabPtr.i = filePtr.p->tabRef;
11332   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11333   if (filePtr.i == tabPtr.p->tabFile[0]) {
11334     jam();
11335     filePtr.i = tabPtr.p->tabFile[1];
11336     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
11337     createFileRw(signal, filePtr);
11338     filePtr.p->reqStatus = FileRecord::TABLE_CREATE;
11339     return;
11340   }//if
11341   switch (tabPtr.p->tabUpdateState) {
11342   case TabRecord::US_LOCAL_CHECKPOINT:
11343     jam();
11344     releaseTabPages(tabPtr.i);
11345     signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
11346     sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
11347 
11348     tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11349     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11350     tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
11351     return;
11352     break;
11353   case TabRecord::US_REMOVE_NODE:
11354     jam();
11355     releaseTabPages(tabPtr.i);
11356     for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
11357       jam();
11358       FragmentstorePtr fragPtr;
11359       getFragstore(tabPtr.p, fragId, fragPtr);
11360       updateNodeInfo(fragPtr);
11361     }//for
11362     tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11363     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11364     if (tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE) {
11365       jam();
11366       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
11367       signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
11368       sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
11369     }//if
11370     signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
11371     signal->theData[1] = tabPtr.p->tabRemoveNode;
11372     signal->theData[2] = tabPtr.i + 1;
11373     sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
11374     return;
11375     break;
11376   case TabRecord::US_INVALIDATE_NODE_LCP:
11377     jam();
11378     releaseTabPages(tabPtr.i);
11379     tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11380     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11381 
11382     signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
11383     signal->theData[1] = tabPtr.p->tabRemoveNode;
11384     signal->theData[2] = tabPtr.i + 1;
11385     sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
11386     return;
11387   case TabRecord::US_COPY_TAB_REQ:
11388     jam();
11389     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11390     copyTabReq_complete(signal, tabPtr);
11391     return;
11392     break;
11393   case TabRecord::US_ADD_TABLE_MASTER:
11394     jam();
11395     releaseTabPages(tabPtr.i);
11396     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11397     signal->theData[0] = DihContinueB::ZDIH_ADD_TABLE_MASTER;
11398     signal->theData[1] = tabPtr.i;
11399     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11400     return;
11401     break;
11402   case TabRecord::US_ADD_TABLE_SLAVE:
11403     jam();
11404     releaseTabPages(tabPtr.i);
11405     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11406     signal->theData[0] = DihContinueB::ZDIH_ADD_TABLE_SLAVE;
11407     signal->theData[1] = tabPtr.i;
11408     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11409     return;
11410     break;
11411   default:
11412     ndbrequire(false);
11413     return;
11414     break;
11415   }//switch
11416 }//Dbdih::tableCloseLab()
11417 
11418 /**
11419  * GCP stop detected,
11420  * send SYSTEM_ERROR to all other alive nodes
11421  */
crashSystemAtGcpStop(Signal * signal,bool local)11422 void Dbdih::crashSystemAtGcpStop(Signal* signal, bool local)
11423 {
11424   if (local)
11425     goto dolocal;
11426 
11427   switch(cgcpStatus){
11428   case GCP_PREPARE_SENT:
11429   {
11430     jam();
11431     /**
11432      * We're waiting for a GCP PREPARE CONF
11433      */
11434     infoEvent("Detected GCP stop(%d)...sending kill to %s",
11435               cgcpStatus, c_GCP_PREPARE_Counter.getText());
11436     ndbout_c("Detected GCP stop(%d)...sending kill to %s",
11437              cgcpStatus, c_GCP_PREPARE_Counter.getText());
11438 
11439     {
11440       NodeReceiverGroup rg(DBDIH, c_GCP_PREPARE_Counter);
11441       signal->theData[0] = 7022;
11442       sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
11443     }
11444 
11445     {
11446       NodeReceiverGroup rg(NDBCNTR, c_GCP_PREPARE_Counter);
11447       SystemError * const sysErr = (SystemError*)&signal->theData[0];
11448       sysErr->errorCode = SystemError::GCPStopDetected;
11449       sysErr->errorRef = reference();
11450       sysErr->data1 = cgcpStatus;
11451       sysErr->data2 = cgcpOrderBlocked;
11452       sendSignal(rg, GSN_SYSTEM_ERROR, signal,
11453                  SystemError::SignalLength, JBA);
11454     }
11455     ndbrequire(!c_GCP_PREPARE_Counter.done());
11456     return;
11457   }
11458   case GCP_COMMIT_SENT:
11459   {
11460     jam();
11461     /**
11462      * We're waiting for a GCP_NODEFINISH
11463      */
11464     infoEvent("Detected GCP stop(%d)...sending kill to %s",
11465 	      cgcpStatus, c_GCP_COMMIT_Counter.getText());
11466     ndbout_c("Detected GCP stop(%d)...sending kill to %s",
11467 	     cgcpStatus, c_GCP_COMMIT_Counter.getText());
11468 
11469     {
11470       NodeReceiverGroup rg(DBDIH, c_GCP_COMMIT_Counter);
11471       signal->theData[0] = 7022;
11472       sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
11473     }
11474 
11475     {
11476       NodeReceiverGroup rg(NDBCNTR, c_GCP_COMMIT_Counter);
11477       SystemError * const sysErr = (SystemError*)&signal->theData[0];
11478       sysErr->errorCode = SystemError::GCPStopDetected;
11479       sysErr->errorRef = reference();
11480       sysErr->data1 = cgcpStatus;
11481       sysErr->data2 = cgcpOrderBlocked;
11482       sendSignal(rg, GSN_SYSTEM_ERROR, signal,
11483                  SystemError::SignalLength, JBA);
11484     }
11485     ndbrequire(!c_GCP_COMMIT_Counter.done());
11486     return;
11487   }
11488   case GCP_NODE_FINISHED:
11489   {
11490     jam();
11491     /**
11492      * We're waiting for a GCP save conf
11493      */
11494     NodeReceiverGroup rg(DBLQH, c_GCP_SAVEREQ_Counter);
11495     signal->theData[0] = 2305;
11496     sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBB);
11497 
11498     infoEvent("Detected GCP stop(%d)...sending kill to %s",
11499               cgcpStatus, c_GCP_SAVEREQ_Counter.getText());
11500     ndbout_c("Detected GCP stop(%d)...sending kill to %s",
11501 	     cgcpStatus, c_GCP_SAVEREQ_Counter.getText());
11502     ndbrequire(!c_GCP_SAVEREQ_Counter.done());
11503     return;
11504   }
11505   case GCP_SAVE_LQH_FINISHED:
11506   {
11507     jam();
11508     /**
11509      * We're waiting for a COPY_GCICONF
11510      */
11511     infoEvent("Detected GCP stop(%d)...sending kill to %s",
11512 	      cgcpStatus, c_COPY_GCIREQ_Counter.getText());
11513     ndbout_c("Detected GCP stop(%d)...sending kill to %s",
11514 	     cgcpStatus, c_COPY_GCIREQ_Counter.getText());
11515 
11516     {
11517       NodeReceiverGroup rg(DBDIH, c_COPY_GCIREQ_Counter);
11518       signal->theData[0] = 7022;
11519       sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
11520     }
11521 
11522     {
11523       NodeReceiverGroup rg(NDBCNTR, c_COPY_GCIREQ_Counter);
11524       SystemError * const sysErr = (SystemError*)&signal->theData[0];
11525       sysErr->errorCode = SystemError::GCPStopDetected;
11526       sysErr->errorRef = reference();
11527       sysErr->data1 = cgcpStatus;
11528       sysErr->data2 = cgcpOrderBlocked;
11529       sendSignal(rg, GSN_SYSTEM_ERROR, signal,
11530                  SystemError::SignalLength, JBA);
11531     }
11532     ndbrequire(!c_COPY_GCIREQ_Counter.done());
11533     return;
11534   }
11535   case GCP_READY: (void)1;
11536   }
11537 
11538 dolocal:
11539   ndbout_c("m_copyReason: %d m_waiting: %d",
11540            c_copyGCIMaster.m_copyReason,
11541            c_copyGCIMaster.m_waiting);
11542 
11543   ndbout_c("c_copyGCISlave: sender{Data, Ref} %d %x reason: %d nextWord: %d",
11544 	   c_copyGCISlave.m_senderData,
11545 	   c_copyGCISlave.m_senderRef,
11546 	   c_copyGCISlave.m_copyReason,
11547 	   c_copyGCISlave.m_expectedNextWord);
11548 
11549   FileRecordPtr file0Ptr;
11550   file0Ptr.i = crestartInfoFile[0];
11551   ptrCheckGuard(file0Ptr, cfileFileSize, fileRecord);
11552   FileRecordPtr file1Ptr;
11553   file1Ptr.i = crestartInfoFile[1];
11554   ptrCheckGuard(file1Ptr, cfileFileSize, fileRecord);
11555 
11556   ndbout_c("file[0] status: %d type: %d reqStatus: %d file1: %d %d %d",
11557 	   file0Ptr.p->fileStatus, file0Ptr.p->fileType, file0Ptr.p->reqStatus,
11558 	   file1Ptr.p->fileStatus, file1Ptr.p->fileType, file1Ptr.p->reqStatus
11559 	   );
11560 
11561   signal->theData[0] = 404;
11562   signal->theData[1] = file0Ptr.p->fileRef;
11563   EXECUTE_DIRECT(NDBFS, GSN_DUMP_STATE_ORD, signal, 2);
11564 
11565   signal->theData[0] = 404;
11566   signal->theData[1] = file1Ptr.p->fileRef;
11567   EXECUTE_DIRECT(NDBFS, GSN_DUMP_STATE_ORD, signal, 2);
11568 
11569   ndbout_c("c_COPY_GCIREQ_Counter = %s",
11570 	   c_COPY_GCIREQ_Counter.getText());
11571   ndbout_c("c_COPY_TABREQ_Counter = %s",
11572 	   c_COPY_TABREQ_Counter.getText());
11573   ndbout_c("c_CREATE_FRAGREQ_Counter = %s",
11574 	   c_CREATE_FRAGREQ_Counter.getText());
11575   ndbout_c("c_DIH_SWITCH_REPLICA_REQ_Counter = %s",
11576 	   c_DIH_SWITCH_REPLICA_REQ_Counter.getText());
11577   ndbout_c("c_EMPTY_LCP_REQ_Counter = %s",c_EMPTY_LCP_REQ_Counter.getText());
11578   ndbout_c("c_END_TOREQ_Counter = %s", c_END_TOREQ_Counter.getText());
11579   ndbout_c("c_GCP_COMMIT_Counter = %s", c_GCP_COMMIT_Counter.getText());
11580   ndbout_c("c_GCP_PREPARE_Counter = %s", c_GCP_PREPARE_Counter.getText());
11581   ndbout_c("c_GCP_SAVEREQ_Counter = %s", c_GCP_SAVEREQ_Counter.getText());
11582   ndbout_c("c_INCL_NODEREQ_Counter = %s", c_INCL_NODEREQ_Counter.getText());
11583   ndbout_c("c_MASTER_GCPREQ_Counter = %s",
11584 	   c_MASTER_GCPREQ_Counter.getText());
11585   ndbout_c("c_MASTER_LCPREQ_Counter = %s",
11586 	   c_MASTER_LCPREQ_Counter.getText());
11587   ndbout_c("c_START_INFOREQ_Counter = %s",
11588 	   c_START_INFOREQ_Counter.getText());
11589   ndbout_c("c_START_RECREQ_Counter = %s", c_START_RECREQ_Counter.getText());
11590   ndbout_c("c_START_TOREQ_Counter = %s", c_START_TOREQ_Counter.getText());
11591   ndbout_c("c_STOP_ME_REQ_Counter = %s", c_STOP_ME_REQ_Counter.getText());
11592   ndbout_c("c_TC_CLOPSIZEREQ_Counter = %s",
11593 	   c_TC_CLOPSIZEREQ_Counter.getText());
11594   ndbout_c("c_TCGETOPSIZEREQ_Counter = %s",
11595 	   c_TCGETOPSIZEREQ_Counter.getText());
11596   ndbout_c("c_UPDATE_TOREQ_Counter = %s", c_UPDATE_TOREQ_Counter.getText());
11597 
11598   if (local == false)
11599   {
11600     jam();
11601     NodeRecordPtr nodePtr;
11602     for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
11603       jam();
11604       ptrAss(nodePtr, nodeRecord);
11605       if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
11606         jam();
11607         const BlockReference ref =
11608           numberToRef(refToBlock(cntrlblockref), nodePtr.i);
11609         SystemError * const sysErr = (SystemError*)&signal->theData[0];
11610         sysErr->errorCode = SystemError::GCPStopDetected;
11611         sysErr->errorRef = reference();
11612         sysErr->data1 = cgcpStatus;
11613         sysErr->data2 = cgcpOrderBlocked;
11614         sendSignal(ref, GSN_SYSTEM_ERROR, signal,
11615                    SystemError::SignalLength, JBA);
11616       }//if
11617     }//for
11618   }
11619   else
11620   {
11621     jam();
11622     SystemError * const sysErr = (SystemError*)&signal->theData[0];
11623     sysErr->errorCode = SystemError::GCPStopDetected;
11624     sysErr->errorRef = reference();
11625     sysErr->data1 = cgcpStatus;
11626     sysErr->data2 = cgcpOrderBlocked;
11627     EXECUTE_DIRECT(NDBCNTR, GSN_SYSTEM_ERROR,
11628                    signal, SystemError::SignalLength);
11629     ndbrequire(false);
11630   }
11631   return;
11632 }//Dbdih::crashSystemAtGcpStop()
11633 
11634 /*************************************************************************/
11635 /*                                                                       */
11636 /*       MODULE: ALLOCPAGE                                               */
11637 /*       DESCRIPTION: THE SUBROUTINE IS CALLED WITH POINTER TO PAGE      */
11638 /*                    RECORD. A PAGE  RECORD IS TAKEN FROM               */
11639 /*                    THE FREE PAGE  LIST                                */
11640 /*************************************************************************/
allocpage(PageRecordPtr & pagePtr)11641 void Dbdih::allocpage(PageRecordPtr& pagePtr)
11642 {
11643   ndbrequire(cfirstfreepage != RNIL);
11644   pagePtr.i = cfirstfreepage;
11645   ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
11646   cfirstfreepage = pagePtr.p->nextfreepage;
11647   pagePtr.p->nextfreepage = RNIL;
11648 }//Dbdih::allocpage()
11649 
11650 /*************************************************************************/
11651 /*                                                                       */
11652 /*       MODULE: ALLOC_STORED_REPLICA                                    */
11653 /*       DESCRIPTION: THE SUBROUTINE IS CALLED TO GET A REPLICA RECORD,  */
11654 /*                    TO INITIALISE IT AND TO LINK IT INTO THE FRAGMENT  */
11655 /*                    STORE RECORD. USED FOR STORED REPLICAS.            */
11656 /*************************************************************************/
allocStoredReplica(FragmentstorePtr fragPtr,ReplicaRecordPtr & newReplicaPtr,Uint32 nodeId)11657 void Dbdih::allocStoredReplica(FragmentstorePtr fragPtr,
11658                                ReplicaRecordPtr& newReplicaPtr,
11659                                Uint32 nodeId)
11660 {
11661   Uint32 i;
11662   ReplicaRecordPtr arrReplicaPtr;
11663   ReplicaRecordPtr arrPrevReplicaPtr;
11664 
11665   seizeReplicaRec(newReplicaPtr);
11666   for (i = 0; i < MAX_LCP_STORED; i++) {
11667     newReplicaPtr.p->maxGciCompleted[i] = 0;
11668     newReplicaPtr.p->maxGciStarted[i] = 0;
11669     newReplicaPtr.p->lcpId[i] = 0;
11670     newReplicaPtr.p->lcpStatus[i] = ZINVALID;
11671   }//for
11672   newReplicaPtr.p->noCrashedReplicas = 0;
11673   newReplicaPtr.p->initialGci = currentgcp;
11674   for (i = 0; i < 8; i++) {
11675     newReplicaPtr.p->replicaLastGci[i] = (Uint32)-1;
11676     newReplicaPtr.p->createGci[i] = 0;
11677   }//for
11678   newReplicaPtr.p->createGci[0] = currentgcp;
11679   ndbrequire(currentgcp != 0xF1F1F1F1);
11680   newReplicaPtr.p->nextLcp = 0;
11681   newReplicaPtr.p->procNode = nodeId;
11682   newReplicaPtr.p->lcpOngoingFlag = false;
11683   newReplicaPtr.p->lcpIdStarted = 0;
11684 
11685   arrPrevReplicaPtr.i = RNIL;
11686   arrReplicaPtr.i = fragPtr.p->storedReplicas;
11687   while (arrReplicaPtr.i != RNIL) {
11688     jam();
11689     ptrCheckGuard(arrReplicaPtr, creplicaFileSize, replicaRecord);
11690     arrPrevReplicaPtr = arrReplicaPtr;
11691     arrReplicaPtr.i = arrReplicaPtr.p->nextReplica;
11692   }//while
11693   if (arrPrevReplicaPtr.i == RNIL) {
11694     jam();
11695     fragPtr.p->storedReplicas = newReplicaPtr.i;
11696   } else {
11697     jam();
11698     arrPrevReplicaPtr.p->nextReplica = newReplicaPtr.i;
11699   }//if
11700   fragPtr.p->noStoredReplicas++;
11701 }//Dbdih::allocStoredReplica()
11702 
11703 /*************************************************************************/
11704 /*  CALCULATE HOW MANY HOT SPARES THAT ARE TO BE ASSIGNED IN THIS SYSTEM */
11705 /*************************************************************************/
calculateHotSpare()11706 void Dbdih::calculateHotSpare()
11707 {
11708   Uint32 tchsTmp;
11709   Uint32 tchsNoNodes;
11710 
11711   switch (cnoReplicas) {
11712   case 1:
11713     jam();
11714     cnoHotSpare = 0;
11715     break;
11716   case 2:
11717   case 3:
11718   case 4:
11719     jam();
11720     if (csystemnodes > cnoReplicas) {
11721       jam();
11722       /* --------------------------------------------------------------------- */
11723       /*  WITH MORE NODES THAN REPLICAS WE WILL ALWAYS USE AT LEAST ONE HOT    */
11724       /*  SPARE IF THAT HAVE BEEN REQUESTED BY THE CONFIGURATION FILE. THE     */
11725       /*  NUMBER OF NODES TO BE USED FOR NORMAL OPERATION IS ALWAYS            */
11726       /*  A MULTIPLE OF THE NUMBER OF REPLICAS SINCE WE WILL ORGANISE NODES    */
11727       /*  INTO NODE GROUPS. THE REMAINING NODES WILL BE HOT SPARE NODES.       */
11728       /* --------------------------------------------------------------------- */
11729       if ((csystemnodes - cnoReplicas) >= cminHotSpareNodes) {
11730         jam();
11731 	/* --------------------------------------------------------------------- */
11732 	// We set the minimum number of hot spares according to users request
11733 	// through the configuration file.
11734 	/* --------------------------------------------------------------------- */
11735         tchsNoNodes = csystemnodes - cminHotSpareNodes;
11736         cnoHotSpare = cminHotSpareNodes;
11737       } else if (cminHotSpareNodes > 0) {
11738         jam();
11739 	/* --------------------------------------------------------------------- */
11740 	// The user requested at least one hot spare node and we will support him
11741 	// in that.
11742 	/* --------------------------------------------------------------------- */
11743         tchsNoNodes = csystemnodes - 1;
11744         cnoHotSpare = 1;
11745       } else {
11746         jam();
11747 	/* --------------------------------------------------------------------- */
11748 	// The user did not request any hot spare nodes so in this case we will
11749 	// only use hot spare nodes if the number of nodes is such that we cannot
11750 	// use all nodes as normal nodes.
11751 	/* --------------------------------------------------------------------- */
11752         tchsNoNodes = csystemnodes;
11753         cnoHotSpare = 0;
11754       }//if
11755     } else {
11756       jam();
11757       /* --------------------------------------------------------------------- */
11758       // We only have enough to support the replicas. We will not have any hot
11759       // spares.
11760       /* --------------------------------------------------------------------- */
11761       tchsNoNodes = csystemnodes;
11762       cnoHotSpare = 0;
11763     }//if
11764     tchsTmp = tchsNoNodes - (cnoReplicas * (tchsNoNodes / cnoReplicas));
11765     cnoHotSpare = cnoHotSpare + tchsTmp;
11766     break;
11767   default:
11768     jam();
11769     ndbrequire(false);
11770     break;
11771   }//switch
11772 }//Dbdih::calculateHotSpare()
11773 
11774 /*************************************************************************/
11775 /* CHECK IF THE NODE CRASH IS TO ESCALATE INTO A SYSTEM CRASH. WE COULD  */
11776 /* DO THIS BECAUSE ALL REPLICAS OF SOME FRAGMENT ARE LOST. WE COULD ALSO */
11777 /* DO IT AFTER MANY NODE FAILURES THAT MAKE IT VERY DIFFICULT TO RESTORE */
11778 /* DATABASE AFTER A SYSTEM CRASH. IT MIGHT EVEN BE IMPOSSIBLE AND THIS   */
11779 /* MUST BE AVOIDED EVEN MORE THAN AVOIDING SYSTEM CRASHES.               */
11780 /*************************************************************************/
checkEscalation()11781 void Dbdih::checkEscalation()
11782 {
11783   Uint32 TnodeGroup[MAX_NDB_NODES];
11784   NodeRecordPtr nodePtr;
11785   Uint32 i;
11786   for (i = 0; i < MAX_NDB_NODES; i++) {
11787     TnodeGroup[i] = ZFALSE;
11788   }//for
11789   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
11790     jam();
11791     ptrAss(nodePtr, nodeRecord);
11792     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
11793 	nodePtr.p->activeStatus == Sysfile::NS_Active){
11794       ndbrequire(nodePtr.p->nodeGroup < MAX_NDB_NODES);
11795       TnodeGroup[nodePtr.p->nodeGroup] = ZTRUE;
11796     }
11797   }
11798   for (i = 0; i < cnoOfNodeGroups; i++) {
11799     jam();
11800     if (TnodeGroup[i] == ZFALSE) {
11801       jam();
11802       progError(__LINE__, NDBD_EXIT_LOST_NODE_GROUP, "Lost node group");
11803     }//if
11804   }//for
11805 }//Dbdih::checkEscalation()
11806 
11807 /*************************************************************************/
11808 /*                                                                       */
11809 /*       MODULE: CHECK_KEEP_GCI                                          */
11810 /*       DESCRIPTION: CHECK FOR MINIMUM GCI RESTORABLE WITH NEW LOCAL    */
11811 /*                    CHECKPOINT.                                        */
11812 /*************************************************************************/
checkKeepGci(TabRecordPtr tabPtr,Uint32 fragId,Fragmentstore *,Uint32 replicaStartIndex)11813 void Dbdih::checkKeepGci(TabRecordPtr tabPtr, Uint32 fragId, Fragmentstore*,
11814 			 Uint32 replicaStartIndex)
11815 {
11816   ReplicaRecordPtr ckgReplicaPtr;
11817   ckgReplicaPtr.i = replicaStartIndex;
11818   while (ckgReplicaPtr.i != RNIL) {
11819     jam();
11820     ptrCheckGuard(ckgReplicaPtr, creplicaFileSize, replicaRecord);
11821     Uint32 keepGci;
11822     Uint32 oldestRestorableGci;
11823     findMinGci(ckgReplicaPtr, keepGci, oldestRestorableGci);
11824     if (keepGci < c_lcpState.keepGci) {
11825       jam();
11826       /* ------------------------------------------------------------------- */
11827       /* WE MUST KEEP LOG RECORDS SO THAT WE CAN USE ALL LOCAL CHECKPOINTS   */
11828       /* THAT ARE AVAILABLE. THUS WE NEED TO CALCULATE THE MINIMUM OVER ALL  */
11829       /* FRAGMENTS.                                                          */
11830       /* ------------------------------------------------------------------- */
11831       c_lcpState.keepGci = keepGci;
11832     }//if
11833     if (oldestRestorableGci > c_lcpState.oldestRestorableGci) {
11834       jam();
11835       c_lcpState.oldestRestorableGci = oldestRestorableGci;
11836     }//if
11837     ckgReplicaPtr.i = ckgReplicaPtr.p->nextReplica;
11838   }//while
11839 }//Dbdih::checkKeepGci()
11840 
closeFile(Signal * signal,FileRecordPtr filePtr)11841 void Dbdih::closeFile(Signal* signal, FileRecordPtr filePtr)
11842 {
11843   signal->theData[0] = filePtr.p->fileRef;
11844   signal->theData[1] = reference();
11845   signal->theData[2] = filePtr.i;
11846   signal->theData[3] = ZCLOSE_NO_DELETE;
11847   sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
11848 }//Dbdih::closeFile()
11849 
closeFileDelete(Signal * signal,FileRecordPtr filePtr)11850 void Dbdih::closeFileDelete(Signal* signal, FileRecordPtr filePtr)
11851 {
11852   signal->theData[0] = filePtr.p->fileRef;
11853   signal->theData[1] = reference();
11854   signal->theData[2] = filePtr.i;
11855   signal->theData[3] = ZCLOSE_DELETE;
11856   sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
11857 }//Dbdih::closeFileDelete()
11858 
createFileRw(Signal * signal,FileRecordPtr filePtr)11859 void Dbdih::createFileRw(Signal* signal, FileRecordPtr filePtr)
11860 {
11861   signal->theData[0] = reference();
11862   signal->theData[1] = filePtr.i;
11863   signal->theData[2] = filePtr.p->fileName[0];
11864   signal->theData[3] = filePtr.p->fileName[1];
11865   signal->theData[4] = filePtr.p->fileName[2];
11866   signal->theData[5] = filePtr.p->fileName[3];
11867   signal->theData[6] = ZCREATE_READ_WRITE;
11868   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
11869 }//Dbdih::createFileRw()
11870 
emptyverificbuffer(Signal * signal,bool aContinueB)11871 void Dbdih::emptyverificbuffer(Signal* signal, bool aContinueB)
11872 {
11873   if(cfirstVerifyQueue == RNIL){
11874     jam();
11875     return;
11876   }//if
11877   ApiConnectRecordPtr localApiConnectptr;
11878   if(getBlockCommit() == false){
11879     jam();
11880     ndbrequire(cverifyQueueCounter > 0);
11881     cverifyQueueCounter--;
11882     localApiConnectptr.i = cfirstVerifyQueue;
11883     ptrCheckGuard(localApiConnectptr, capiConnectFileSize, apiConnectRecord);
11884     ndbrequire(localApiConnectptr.p->apiGci <= currentgcp);
11885     cfirstVerifyQueue = localApiConnectptr.p->nextApi;
11886     if (cfirstVerifyQueue == RNIL) {
11887       jam();
11888       ndbrequire(cverifyQueueCounter == 0);
11889       clastVerifyQueue = RNIL;
11890     }//if
11891     signal->theData[0] = localApiConnectptr.i;
11892     signal->theData[1] = currentgcp;
11893     sendSignal(clocaltcblockref, GSN_DIVERIFYCONF, signal, 2, JBB);
11894     if (aContinueB == true) {
11895       jam();
11896       //-----------------------------------------------------------------------
11897       // This emptying happened as part of a take-out process by continueb signals.
11898       // This ensures that we will empty the queue eventually. We will also empty
11899       // one item every time we insert one item to ensure that the list doesn't
11900       // grow when it is not blocked.
11901       //-----------------------------------------------------------------------
11902       signal->theData[0] = DihContinueB::ZEMPTY_VERIFY_QUEUE;
11903       sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
11904     }//if
11905   } else {
11906     jam();
11907     //-----------------------------------------------------------------------
11908     // We are blocked so it is no use in continuing the emptying of the
11909     // verify buffer. Whenever the block is removed the emptying will
11910     // restart.
11911     //-----------------------------------------------------------------------
11912   }
11913   return;
11914 }//Dbdih::emptyverificbuffer()
11915 
11916 /*----------------------------------------------------------------*/
11917 /*       FIND A FREE HOT SPARE IF AVAILABLE AND ALIVE.            */
11918 /*----------------------------------------------------------------*/
findHotSpare()11919 Uint32 Dbdih::findHotSpare()
11920 {
11921   NodeRecordPtr nodePtr;
11922   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
11923     jam();
11924     ptrAss(nodePtr, nodeRecord);
11925     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
11926       if (nodePtr.p->activeStatus == Sysfile::NS_HotSpare) {
11927         jam();
11928         return nodePtr.i;
11929       }//if
11930     }//if
11931   }//for
11932   return RNIL;
11933 }//Dbdih::findHotSpare()
11934 
11935 /*************************************************************************/
11936 /*       FIND THE NODES FROM WHICH WE CAN EXECUTE THE LOG TO RESTORE THE */
11937 /*       DATA NODE IN A SYSTEM RESTART.                                  */
11938 /*************************************************************************/
findLogNodes(CreateReplicaRecord * createReplica,FragmentstorePtr fragPtr,Uint32 startGci,Uint32 stopGci)11939 bool Dbdih::findLogNodes(CreateReplicaRecord* createReplica,
11940                          FragmentstorePtr fragPtr,
11941                          Uint32 startGci,
11942                          Uint32 stopGci)
11943 {
11944   ConstPtr<ReplicaRecord> flnReplicaPtr;
11945   flnReplicaPtr.i = createReplica->replicaRec;
11946   ptrCheckGuard(flnReplicaPtr, creplicaFileSize, replicaRecord);
11947   /* --------------------------------------------------------------------- */
11948   /*       WE START BY CHECKING IF THE DATA NODE CAN HANDLE THE LOG ALL BY */
11949   /*       ITSELF. THIS IS THE DESIRED BEHAVIOUR. IF THIS IS NOT POSSIBLE  */
11950   /*       THEN WE SEARCH FOR THE BEST POSSIBLE NODES AMONG THE NODES THAT */
11951   /*       ARE PART OF THIS SYSTEM RESTART.                                */
11952   /*       THIS CAN ONLY BE HANDLED BY THE LAST CRASHED REPLICA.           */
11953   /*       The condition is that the replica was created before or at the  */
11954   /*       time of the starting gci, in addition it must have been alive   */
11955   /*       at the time of the stopping gci. This is checked by two         */
11956   /*       conditions, the first checks replicaLastGci and the second      */
11957   /*       checks that it is also smaller than the last gci the node was   */
11958   /*       involved in. This is necessary to check since createGci is set  */
11959   /*       Last + 1 and sometimes startGci = stopGci + 1 and in that case  */
11960   /*       it could happen that replicaLastGci is set to -1 with CreateGci */
11961   /*       set to LastGci + 1.                                             */
11962   /* --------------------------------------------------------------------- */
11963   arrGuard(flnReplicaPtr.p->noCrashedReplicas, 8);
11964   const Uint32 noCrashed = flnReplicaPtr.p->noCrashedReplicas;
11965 
11966   if (!(ERROR_INSERTED(7073) || ERROR_INSERTED(7074))&&
11967       (startGci >= flnReplicaPtr.p->createGci[noCrashed]) &&
11968       (stopGci <= flnReplicaPtr.p->replicaLastGci[noCrashed]) &&
11969       (stopGci <= SYSFILE->lastCompletedGCI[flnReplicaPtr.p->procNode])) {
11970     jam();
11971     /* --------------------------------------------------------------------- */
11972     /*       WE FOUND ALL THE LOG RECORDS NEEDED IN THE DATA NODE. WE WILL   */
11973     /*       USE THOSE.                                                      */
11974     /* --------------------------------------------------------------------- */
11975     createReplica->noLogNodes = 1;
11976     createReplica->logStartGci[0] = startGci;
11977     createReplica->logStopGci[0] = stopGci;
11978     createReplica->logNodeId[0] = flnReplicaPtr.p->procNode;
11979     return true;
11980   }//if
11981   Uint32 logNode = 0;
11982   do {
11983     Uint32 fblStopGci;
11984     jam();
11985     if(!findBestLogNode(createReplica,
11986 			fragPtr,
11987 			startGci,
11988 			stopGci,
11989 			logNode,
11990 			fblStopGci)){
11991       jam();
11992       return false;
11993     }
11994 
11995     logNode++;
11996     if (fblStopGci >= stopGci) {
11997       jam();
11998       createReplica->noLogNodes = logNode;
11999       return true;
12000     }//if
12001     startGci = fblStopGci + 1;
12002     if (logNode >= 4) { // Why??
12003       jam();
12004       break;
12005     }//if
12006   } while (1);
12007   /* --------------------------------------------------------------------- */
12008   /*       IT WAS NOT POSSIBLE TO RESTORE THE REPLICA. THIS CAN EITHER BE  */
12009   /*       BECAUSE OF LACKING NODES OR BECAUSE OF A REALLY SERIOUS PROBLEM.*/
12010   /* --------------------------------------------------------------------- */
12011   return false;
12012 }//Dbdih::findLogNodes()
12013 
12014 /*************************************************************************/
12015 /*       FIND THE BEST POSSIBLE LOG NODE TO EXECUTE THE LOG AS SPECIFIED */
12016 /*       BY THE INPUT PARAMETERS. WE SCAN THROUGH ALL ALIVE REPLICAS.    */
12017 /*       THIS MEANS STORED, OLD_STORED                                   */
12018 /*************************************************************************/
12019 bool
findBestLogNode(CreateReplicaRecord * createReplica,FragmentstorePtr fragPtr,Uint32 startGci,Uint32 stopGci,Uint32 logNode,Uint32 & fblStopGci)12020 Dbdih::findBestLogNode(CreateReplicaRecord* createReplica,
12021 		       FragmentstorePtr fragPtr,
12022 		       Uint32 startGci,
12023 		       Uint32 stopGci,
12024 		       Uint32 logNode,
12025 		       Uint32& fblStopGci)
12026 {
12027   ConstPtr<ReplicaRecord> fblFoundReplicaPtr;
12028   ConstPtr<ReplicaRecord> fblReplicaPtr;
12029   LINT_INIT(fblFoundReplicaPtr.p);
12030 
12031   /* --------------------------------------------------------------------- */
12032   /*       WE START WITH ZERO AS FOUND TO ENSURE THAT FIRST HIT WILL BE    */
12033   /*       BETTER.                                                         */
12034   /* --------------------------------------------------------------------- */
12035   fblStopGci = 0;
12036   fblReplicaPtr.i = fragPtr.p->storedReplicas;
12037   while (fblReplicaPtr.i != RNIL) {
12038     jam();
12039     ptrCheckGuard(fblReplicaPtr, creplicaFileSize, replicaRecord);
12040     if (checkNodeAlive(fblReplicaPtr.p->procNode)) {
12041       jam();
12042       Uint32 fliStopGci = findLogInterval(fblReplicaPtr, startGci);
12043       if (fliStopGci > fblStopGci) {
12044         jam();
12045         fblStopGci = fliStopGci;
12046         fblFoundReplicaPtr = fblReplicaPtr;
12047       }//if
12048     }//if
12049     fblReplicaPtr.i = fblReplicaPtr.p->nextReplica;
12050   }//while
12051   fblReplicaPtr.i = fragPtr.p->oldStoredReplicas;
12052   while (fblReplicaPtr.i != RNIL) {
12053     jam();
12054     ptrCheckGuard(fblReplicaPtr, creplicaFileSize, replicaRecord);
12055     if (checkNodeAlive(fblReplicaPtr.p->procNode)) {
12056       jam();
12057       Uint32 fliStopGci = findLogInterval(fblReplicaPtr, startGci);
12058       if (fliStopGci > fblStopGci) {
12059         jam();
12060         fblStopGci = fliStopGci;
12061         fblFoundReplicaPtr = fblReplicaPtr;
12062       }//if
12063     }//if
12064     fblReplicaPtr.i = fblReplicaPtr.p->nextReplica;
12065   }//while
12066   if (fblStopGci != 0) {
12067     jam();
12068     ndbrequire(logNode < MAX_LOG_EXEC);
12069     createReplica->logNodeId[logNode] = fblFoundReplicaPtr.p->procNode;
12070     createReplica->logStartGci[logNode] = startGci;
12071     if (fblStopGci >= stopGci) {
12072       jam();
12073       createReplica->logStopGci[logNode] = stopGci;
12074     } else {
12075       jam();
12076       createReplica->logStopGci[logNode] = fblStopGci;
12077     }//if
12078   }//if
12079 
12080   return fblStopGci != 0;
12081 }//Dbdih::findBestLogNode()
12082 
findLogInterval(ConstPtr<ReplicaRecord> replicaPtr,Uint32 startGci)12083 Uint32 Dbdih::findLogInterval(ConstPtr<ReplicaRecord> replicaPtr,
12084 			      Uint32 startGci)
12085 {
12086   ndbrequire(replicaPtr.p->noCrashedReplicas <= 8);
12087   Uint32 loopLimit = replicaPtr.p->noCrashedReplicas + 1;
12088   for (Uint32 i = 0; i < loopLimit; i++) {
12089     jam();
12090     if (replicaPtr.p->createGci[i] <= startGci) {
12091       if (replicaPtr.p->replicaLastGci[i] >= startGci) {
12092         jam();
12093         return replicaPtr.p->replicaLastGci[i];
12094       }//if
12095     }//if
12096   }//for
12097   return 0;
12098 }//Dbdih::findLogInterval()
12099 
12100 /*************************************************************************/
12101 /*                                                                       */
12102 /*       MODULE: FIND THE MINIMUM GCI THAT THIS NODE HAS LOG RECORDS FOR.*/
12103 /*************************************************************************/
findMinGci(ReplicaRecordPtr fmgReplicaPtr,Uint32 & keepGci,Uint32 & oldestRestorableGci)12104 void Dbdih::findMinGci(ReplicaRecordPtr fmgReplicaPtr,
12105                        Uint32& keepGci,
12106                        Uint32& oldestRestorableGci)
12107 {
12108   Uint32 nextLcpNo;
12109   Uint32 lcpNo;
12110   for (Uint32 i = 0; i < MAX_LCP_STORED; i++) {
12111     jam();
12112     if ((fmgReplicaPtr.p->lcpStatus[i] == ZVALID) &&
12113         ((fmgReplicaPtr.p->lcpId[i] + MAX_LCP_STORED) <= (SYSFILE->latestLCP_ID + 1))) {
12114       jam();
12115       /*--------------------------------------------------------------------*/
12116       // We invalidate the checkpoint we are preparing to overwrite.
12117       // The LCP id is still the old lcp id,
12118       // this is the reason of comparing with lcpId + 1.
12119       /*---------------------------------------------------------------------*/
12120       fmgReplicaPtr.p->lcpStatus[i] = ZINVALID;
12121     }//if
12122   }//for
12123   keepGci = (Uint32)-1;
12124   oldestRestorableGci = 0;
12125   nextLcpNo = fmgReplicaPtr.p->nextLcp;
12126   lcpNo = fmgReplicaPtr.p->nextLcp;
12127   do {
12128     ndbrequire(lcpNo < MAX_LCP_STORED);
12129     if (fmgReplicaPtr.p->lcpStatus[lcpNo] == ZVALID)
12130     {
12131       jam();
12132       keepGci = fmgReplicaPtr.p->maxGciCompleted[lcpNo];
12133       oldestRestorableGci = fmgReplicaPtr.p->maxGciStarted[lcpNo];
12134       ndbassert(fmgReplicaPtr.p->maxGciStarted[lcpNo] <c_newest_restorable_gci);
12135       return;
12136     } else {
12137       jam();
12138       if (fmgReplicaPtr.p->createGci[0] == fmgReplicaPtr.p->initialGci) {
12139         jam();
12140 	/*-------------------------------------------------------------------
12141 	 * WE CAN STILL RESTORE THIS REPLICA WITHOUT ANY LOCAL CHECKPOINTS BY
12142 	 * ONLY USING THE LOG. IF THIS IS NOT POSSIBLE THEN WE REPORT THE LAST
12143 	 * VALID LOCAL CHECKPOINT AS THE MINIMUM GCI RECOVERABLE.
12144 	 *-----------------------------------------------------------------*/
12145         keepGci = fmgReplicaPtr.p->createGci[0];
12146       }//if
12147     }//if
12148     lcpNo = prevLcpNo(lcpNo);
12149   } while (lcpNo != nextLcpNo);
12150   return;
12151 }//Dbdih::findMinGci()
12152 
findStartGci(ConstPtr<ReplicaRecord> replicaPtr,Uint32 stopGci,Uint32 & startGci,Uint32 & lcpNo)12153 bool Dbdih::findStartGci(ConstPtr<ReplicaRecord> replicaPtr,
12154                          Uint32 stopGci,
12155                          Uint32& startGci,
12156                          Uint32& lcpNo)
12157 {
12158   lcpNo = replicaPtr.p->nextLcp;
12159   const Uint32 startLcpNo = lcpNo;
12160   do {
12161     lcpNo = prevLcpNo(lcpNo);
12162     ndbrequire(lcpNo < MAX_LCP_STORED);
12163     if (replicaPtr.p->lcpStatus[lcpNo] == ZVALID) {
12164       if (replicaPtr.p->maxGciStarted[lcpNo] < stopGci) {
12165         jam();
12166 	/* ----------------------------------------------------------------- */
12167 	/*   WE HAVE FOUND A USEFUL LOCAL CHECKPOINT THAT CAN BE USED FOR    */
12168 	/*   RESTARTING THIS FRAGMENT REPLICA.                               */
12169 	/* ----------------------------------------------------------------- */
12170         startGci = replicaPtr.p->maxGciCompleted[lcpNo] + 1;
12171         return true;
12172       }
12173     }
12174   } while (lcpNo != startLcpNo);
12175   /* --------------------------------------------------------------------- */
12176   /*       NO VALID LOCAL CHECKPOINT WAS AVAILABLE. WE WILL ADD THE        */
12177   /*       FRAGMENT. THUS THE NEXT LCP MUST BE SET TO ZERO.                */
12178   /*       WE MUST EXECUTE THE LOG FROM THE INITIAL GLOBAL CHECKPOINT WHEN */
12179   /*       THE TABLE WAS CREATED.                                          */
12180   /* --------------------------------------------------------------------- */
12181   startGci = replicaPtr.p->initialGci;
12182   ndbrequire(replicaPtr.p->nextLcp == 0);
12183   return false;
12184 }//Dbdih::findStartGci()
12185 
12186 /**************************************************************************/
12187 /* ---------------------------------------------------------------------- */
12188 /*       FIND A TAKE OVER REPLICA WHICH IS TO BE STARTED OR COMMITTED WHEN*/
12189 /*       TAKING OVER A FAILED NODE.                                       */
12190 /* ---------------------------------------------------------------------- */
12191 /*************************************************************************/
findToReplica(TakeOverRecord * regTakeOver,Uint32 replicaType,FragmentstorePtr fragPtr,ReplicaRecordPtr & ftrReplicaPtr)12192 void Dbdih::findToReplica(TakeOverRecord* regTakeOver,
12193                           Uint32 replicaType,
12194                           FragmentstorePtr fragPtr,
12195                           ReplicaRecordPtr& ftrReplicaPtr)
12196 {
12197   switch (replicaType) {
12198   case CreateFragReq::STORED:
12199   case CreateFragReq::COMMIT_STORED:
12200     /* ----------------------------------------------------------------------*/
12201     /* HERE WE SEARCH FOR STORED REPLICAS. THE REPLICA MUST BE STORED IN THE */
12202     /* SECTION FOR OLD STORED REPLICAS SINCE WE HAVE NOT TAKEN OVER YET.     */
12203     /* ----------------------------------------------------------------------*/
12204     ftrReplicaPtr.i = fragPtr.p->oldStoredReplicas;
12205     while (ftrReplicaPtr.i != RNIL) {
12206       ptrCheckGuard(ftrReplicaPtr, creplicaFileSize, replicaRecord);
12207       if (ftrReplicaPtr.p->procNode == regTakeOver->toStartingNode) {
12208         jam();
12209         return;
12210       } else {
12211         if (ftrReplicaPtr.p->procNode == regTakeOver->toFailedNode) {
12212           jam();
12213           return;
12214         } else {
12215           jam();
12216           ftrReplicaPtr.i = ftrReplicaPtr.p->nextReplica;
12217         }//if
12218       }//if
12219     }//while
12220     break;
12221   default:
12222     ndbrequire(false);
12223     break;
12224   }//switch
12225 }//Dbdih::findToReplica()
12226 
initCommonData()12227 void Dbdih::initCommonData()
12228 {
12229   c_blockCommit = false;
12230   c_blockCommitNo = 0;
12231   c_createFragmentLock = RNIL;
12232   c_endToLock = RNIL;
12233   cfailurenr = 1;
12234   cfirstAliveNode = RNIL;
12235   cfirstDeadNode = RNIL;
12236   cfirstVerifyQueue = RNIL;
12237   cgckptflag = false;
12238   cgcpDelay = 0;
12239   cgcpMasterTakeOverState = GMTOS_IDLE;
12240   cgcpOrderBlocked = 0;
12241   cgcpParticipantState = GCP_PARTICIPANT_READY;
12242   cgcpSameCounter = 0;
12243   cgcpStartCounter = 0;
12244   cgcpStatus = GCP_READY;
12245 
12246   clastVerifyQueue = RNIL;
12247   c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
12248 
12249   c_lcpState.clcpDelay = 0;
12250   c_lcpState.lcpStart = ZIDLE;
12251   c_lcpState.lcpStopGcp = 0;
12252   c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
12253   c_lcpState.currentFragment.tableId = 0;
12254   c_lcpState.currentFragment.fragmentId = 0;
12255   c_lcpState.noOfLcpFragRepOutstanding = 0;
12256   c_lcpState.keepGci = 0;
12257   c_lcpState.oldestRestorableGci = 0;
12258   c_lcpState.ctcCounter = 0;
12259   c_lcpState.ctimer = 0;
12260   c_lcpState.immediateLcpStart = false;
12261   c_lcpState.m_MASTER_LCPREQ_Received = false;
12262 
12263   cmasterdihref = 0;
12264   cmasterNodeId = 0;
12265   cmasterState = MASTER_IDLE;
12266   cmasterTakeOverNode = 0;
12267   cnewgcp = 0;
12268   cnoHotSpare = 0;
12269   cnoOfActiveTables = 0;
12270   cnoOfNodeGroups = 0;
12271   c_nextNodeGroup = 0;
12272   cnoReplicas = 0;
12273   coldgcp = 0;
12274   coldGcpId = 0;
12275   coldGcpStatus = cgcpStatus;
12276   con_lineNodes = 0;
12277   creceivedfrag = 0;
12278   crestartGci = 0;
12279   crestartInfoFile[0] = RNIL;
12280   crestartInfoFile[1] = RNIL;
12281   cstartGcpNow = false;
12282   cstartPhase = 0;
12283   c_startToLock = RNIL;
12284   cstarttype = (Uint32)-1;
12285   csystemnodes = 0;
12286   c_updateToLock = RNIL;
12287   currentgcp = 0;
12288   c_newest_restorable_gci = 0;
12289   cverifyQueueCounter = 0;
12290   cwaitLcpSr = false;
12291   c_nextLogPart = 0;
12292 
12293   nodeResetStart();
12294   c_nodeStartMaster.wait = ZFALSE;
12295 
12296   memset(&sysfileData[0], 0, sizeof(sysfileData));
12297 
12298   const ndb_mgm_configuration_iterator * p =
12299     m_ctx.m_config.getOwnConfigIterator();
12300   ndbrequire(p != 0);
12301 
12302   c_lcpState.clcpDelay = 20;
12303   ndb_mgm_get_int_parameter(p, CFG_DB_LCP_INTERVAL, &c_lcpState.clcpDelay);
12304   c_lcpState.clcpDelay = c_lcpState.clcpDelay > 31 ? 31 : c_lcpState.clcpDelay;
12305 
12306   cminHotSpareNodes = 0;
12307   //ndb_mgm_get_int_parameter(p, CFG_DB_MIN_HOT_SPARES, &cminHotSpareNodes);
12308   cminHotSpareNodes = cminHotSpareNodes > 2 ? 2 : cminHotSpareNodes;
12309 
12310   cnoReplicas = 1;
12311   ndb_mgm_get_int_parameter(p, CFG_DB_NO_REPLICAS, &cnoReplicas);
12312   if (cnoReplicas > 4)
12313   {
12314     progError(__LINE__, NDBD_EXIT_INVALID_CONFIG,
12315 	      "Only up to four replicas are supported. Check NoOfReplicas.");
12316   }
12317 
12318   cgcpDelay = 2000;
12319   ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay);
12320   cgcpDelay =  cgcpDelay > 60000 ? 60000 : (cgcpDelay < 10 ? 10 : cgcpDelay);
12321 }//Dbdih::initCommonData()
12322 
initFragstore(FragmentstorePtr fragPtr)12323 void Dbdih::initFragstore(FragmentstorePtr fragPtr)
12324 {
12325   fragPtr.p->storedReplicas = RNIL;
12326   fragPtr.p->oldStoredReplicas = RNIL;
12327 
12328   fragPtr.p->noStoredReplicas = 0;
12329   fragPtr.p->noOldStoredReplicas = 0;
12330   fragPtr.p->fragReplicas = 0;
12331   fragPtr.p->preferredPrimary = 0;
12332 
12333   for (Uint32 i = 0; i < MAX_REPLICAS; i++)
12334     fragPtr.p->activeNodes[i] = 0;
12335 
12336   fragPtr.p->noLcpReplicas = 0;
12337   fragPtr.p->distributionKey = 0;
12338 }//Dbdih::initFragstore()
12339 
12340 /*************************************************************************/
12341 /*                                                                       */
12342 /*       MODULE: INIT_RESTART_INFO                                       */
12343 /*       DESCRIPTION: INITIATE RESTART INFO VARIABLE AND VARIABLES FOR   */
12344 /*                    GLOBAL CHECKPOINTS.                                */
12345 /*************************************************************************/
initRestartInfo()12346 void Dbdih::initRestartInfo()
12347 {
12348   Uint32 i;
12349   for (i = 0; i < MAX_NDB_NODES; i++) {
12350     SYSFILE->lastCompletedGCI[i] = 0;
12351   }//for
12352   NodeRecordPtr nodePtr;
12353   nodePtr.i = cfirstAliveNode;
12354   do {
12355     jam();
12356     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12357     SYSFILE->lastCompletedGCI[nodePtr.i] = 1;
12358     /* FIRST GCP = 1 ALREADY SET BY LQH */
12359     nodePtr.i = nodePtr.p->nextNode;
12360   } while (nodePtr.i != RNIL);
12361   coldgcp = 1;
12362   currentgcp = 2;
12363   cnewgcp = 2;
12364   crestartGci = 1;
12365   c_newest_restorable_gci = 1;
12366 
12367   SYSFILE->keepGCI             = 1;
12368   SYSFILE->oldestRestorableGCI = 1;
12369   SYSFILE->newestRestorableGCI = 1;
12370   SYSFILE->systemRestartBits   = 0;
12371   for (i = 0; i < NodeBitmask::Size; i++) {
12372     SYSFILE->lcpActive[0]        = 0;
12373   }//for
12374   for (i = 0; i < Sysfile::TAKE_OVER_SIZE; i++) {
12375     SYSFILE->takeOver[i] = 0;
12376   }//for
12377   Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
12378   srand(time(0));
12379   globalData.m_restart_seq = SYSFILE->m_restart_seq = 0;
12380 }//Dbdih::initRestartInfo()
12381 
12382 /*--------------------------------------------------------------------*/
12383 /*       NODE GROUP BITS ARE INITIALISED BEFORE THIS.                 */
12384 /*       NODE ACTIVE BITS ARE INITIALISED BEFORE THIS.                */
12385 /*--------------------------------------------------------------------*/
12386 /*************************************************************************/
12387 /*                                                                       */
12388 /*       MODULE: INIT_RESTORABLE_GCI_FILES                               */
12389 /*       DESCRIPTION: THE SUBROUTINE SETS UP THE FILES THAT REFERS TO THE*/
12390 /*       FILES THAT KEEP THE VARIABLE CRESTART_INFO                      */
12391 /*************************************************************************/
initRestorableGciFiles()12392 void Dbdih::initRestorableGciFiles()
12393 {
12394   Uint32 tirgTmp;
12395   FileRecordPtr filePtr;
12396   seizeFile(filePtr);
12397   filePtr.p->tabRef = RNIL;
12398   filePtr.p->fileType = FileRecord::GCP_FILE;
12399   filePtr.p->reqStatus = FileRecord::IDLE;
12400   filePtr.p->fileStatus = FileRecord::CLOSED;
12401   crestartInfoFile[0] = filePtr.i;
12402   filePtr.p->fileName[0] = (Uint32)-1;  /* T DIRECTORY NOT USED  */
12403   filePtr.p->fileName[1] = (Uint32)-1;  /* F DIRECTORY NOT USED  */
12404   filePtr.p->fileName[2] = (Uint32)-1;  /* S PART IGNORED        */
12405   tirgTmp = 1;  /* FILE NAME VERSION 1   */
12406   tirgTmp = (tirgTmp << 8) + 6; /* .SYSFILE              */
12407   tirgTmp = (tirgTmp << 8) + 1; /* D1 DIRECTORY          */
12408   tirgTmp = (tirgTmp << 8) + 0; /* P0 FILE NAME          */
12409   filePtr.p->fileName[3] = tirgTmp;
12410   /* --------------------------------------------------------------------- */
12411   /*       THE NAME BECOMES /D1/DBDICT/S0.SYSFILE                          */
12412   /* --------------------------------------------------------------------- */
12413   seizeFile(filePtr);
12414   filePtr.p->tabRef = RNIL;
12415   filePtr.p->fileType = FileRecord::GCP_FILE;
12416   filePtr.p->reqStatus = FileRecord::IDLE;
12417   filePtr.p->fileStatus = FileRecord::CLOSED;
12418   crestartInfoFile[1] = filePtr.i;
12419   filePtr.p->fileName[0] = (Uint32)-1;  /* T DIRECTORY NOT USED  */
12420   filePtr.p->fileName[1] = (Uint32)-1;  /* F DIRECTORY NOT USED  */
12421   filePtr.p->fileName[2] = (Uint32)-1;  /* S PART IGNORED        */
12422   tirgTmp = 1;  /* FILE NAME VERSION 1   */
12423   tirgTmp = (tirgTmp << 8) + 6; /* .SYSFILE              */
12424   tirgTmp = (tirgTmp << 8) + 2; /* D1 DIRECTORY          */
12425   tirgTmp = (tirgTmp << 8) + 0; /* P0 FILE NAME          */
12426   filePtr.p->fileName[3] = tirgTmp;
12427   /* --------------------------------------------------------------------- */
12428   /*       THE NAME BECOMES /D2/DBDICT/P0.SYSFILE                          */
12429   /* --------------------------------------------------------------------- */
12430 }//Dbdih::initRestorableGciFiles()
12431 
initTable(TabRecordPtr tabPtr)12432 void Dbdih::initTable(TabRecordPtr tabPtr)
12433 {
12434   tabPtr.p->noOfFragChunks = 0;
12435   tabPtr.p->method = TabRecord::NOTDEFINED;
12436   tabPtr.p->tabStatus = TabRecord::TS_IDLE;
12437   tabPtr.p->noOfWords = 0;
12438   tabPtr.p->noPages = 0;
12439   tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
12440   tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
12441   tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
12442   tabPtr.p->noOfBackups = 0;
12443   tabPtr.p->kvalue = 0;
12444   tabPtr.p->hashpointer = (Uint32)-1;
12445   tabPtr.p->mask = 0;
12446   tabPtr.p->tabStorage = TabRecord::ST_NORMAL;
12447   tabPtr.p->tabErrorCode = 0;
12448   tabPtr.p->schemaVersion = (Uint32)-1;
12449   tabPtr.p->tabRemoveNode = RNIL;
12450   tabPtr.p->totalfragments = (Uint32)-1;
12451   tabPtr.p->connectrec = RNIL;
12452   tabPtr.p->tabFile[0] = RNIL;
12453   tabPtr.p->tabFile[1] = RNIL;
12454   tabPtr.p->m_dropTab.tabUserRef = 0;
12455   tabPtr.p->m_dropTab.tabUserPtr = RNIL;
12456   Uint32 i;
12457   for (i = 0; i < MAX_NDB_NODES; i++) {
12458     tabPtr.p->startFid[i] = RNIL;
12459   }//for
12460   for (i = 0; i < 8; i++) {
12461     tabPtr.p->pageRef[i] = RNIL;
12462   }//for
12463   tabPtr.p->tableType = DictTabInfo::UndefTableType;
12464 }//Dbdih::initTable()
12465 
12466 /*************************************************************************/
12467 /*                                                                       */
12468 /*       MODULE: INIT_TABLE_FILES                                        */
12469 /*       DESCRIPTION: THE SUBROUTINE SETS UP THE FILES THAT REFERS TO THE*/
12470 /*       FILES THAT KEEP THE TABLE FRAGMENTATION DESCRIPTION.            */
12471 /*************************************************************************/
initTableFile(TabRecordPtr tabPtr)12472 void Dbdih::initTableFile(TabRecordPtr tabPtr)
12473 {
12474   Uint32 titfTmp;
12475   FileRecordPtr filePtr;
12476   seizeFile(filePtr);
12477   filePtr.p->tabRef = tabPtr.i;
12478   filePtr.p->fileType = FileRecord::TABLE_FILE;
12479   filePtr.p->reqStatus = FileRecord::IDLE;
12480   filePtr.p->fileStatus = FileRecord::CLOSED;
12481   tabPtr.p->tabFile[0] = filePtr.i;
12482   filePtr.p->fileName[0] = (Uint32)-1;  /* T DIRECTORY NOT USED  */
12483   filePtr.p->fileName[1] = (Uint32)-1;  /* F DIRECTORY NOT USED  */
12484   filePtr.p->fileName[2] = tabPtr.i;    /* Stid FILE NAME        */
12485   titfTmp = 1;  /* FILE NAME VERSION 1   */
12486   titfTmp = (titfTmp << 8) + 3; /* .FRAGLIST             */
12487   titfTmp = (titfTmp << 8) + 1; /* D1 DIRECTORY          */
12488   titfTmp = (titfTmp << 8) + 255;       /* P PART IGNORED        */
12489   filePtr.p->fileName[3] = titfTmp;
12490   /* --------------------------------------------------------------------- */
12491   /*       THE NAME BECOMES /D1/DBDICT/Stid.FRAGLIST                       */
12492   /* --------------------------------------------------------------------- */
12493   seizeFile(filePtr);
12494   filePtr.p->tabRef = tabPtr.i;
12495   filePtr.p->fileType = FileRecord::TABLE_FILE;
12496   filePtr.p->reqStatus = FileRecord::IDLE;
12497   filePtr.p->fileStatus = FileRecord::CLOSED;
12498   tabPtr.p->tabFile[1] = filePtr.i;
12499   filePtr.p->fileName[0] = (Uint32)-1;  /* T DIRECTORY NOT USED  */
12500   filePtr.p->fileName[1] = (Uint32)-1;  /* F DIRECTORY NOT USED  */
12501   filePtr.p->fileName[2] = tabPtr.i;    /* Stid FILE NAME        */
12502   titfTmp = 1;  /* FILE NAME VERSION 1   */
12503   titfTmp = (titfTmp << 8) + 3; /* .FRAGLIST             */
12504   titfTmp = (titfTmp << 8) + 2; /* D2 DIRECTORY          */
12505   titfTmp = (titfTmp << 8) + 255;       /* P PART IGNORED        */
12506   filePtr.p->fileName[3] = titfTmp;
12507   /* --------------------------------------------------------------------- */
12508   /*       THE NAME BECOMES /D2/DBDICT/Stid.FRAGLIST                       */
12509   /* --------------------------------------------------------------------- */
12510 }//Dbdih::initTableFile()
12511 
initialiseRecordsLab(Signal * signal,Uint32 stepNo,Uint32 retRef,Uint32 retData)12512 void Dbdih::initialiseRecordsLab(Signal* signal,
12513 				 Uint32 stepNo, Uint32 retRef, Uint32 retData)
12514 {
12515   switch (stepNo) {
12516   case 0:
12517     jam();
12518     initCommonData();
12519     break;
12520   case 1:{
12521     ApiConnectRecordPtr apiConnectptr;
12522     jam();
12523     /******** INTIALIZING API CONNECT RECORDS ********/
12524     for (apiConnectptr.i = 0; apiConnectptr.i < capiConnectFileSize; apiConnectptr.i++) {
12525       refresh_watch_dog();
12526       ptrAss(apiConnectptr, apiConnectRecord);
12527       apiConnectptr.p->nextApi = RNIL;
12528     }//for
12529     jam();
12530     break;
12531   }
12532   case 2:{
12533     ConnectRecordPtr connectPtr;
12534     jam();
12535     /****** CONNECT ******/
12536     for (connectPtr.i = 0; connectPtr.i < cconnectFileSize; connectPtr.i++) {
12537       refresh_watch_dog();
12538       ptrAss(connectPtr, connectRecord);
12539       connectPtr.p->userpointer = RNIL;
12540       connectPtr.p->userblockref = ZNIL;
12541       connectPtr.p->connectState = ConnectRecord::FREE;
12542       connectPtr.p->table = RNIL;
12543       connectPtr.p->nfConnect = connectPtr.i + 1;
12544     }//for
12545     connectPtr.i = cconnectFileSize - 1;
12546     ptrAss(connectPtr, connectRecord);
12547     connectPtr.p->nfConnect = RNIL;
12548     cfirstconnect = 0;
12549     break;
12550   }
12551   case 3:
12552     {
12553       FileRecordPtr filePtr;
12554       jam();
12555       /******** INTIALIZING FILE RECORDS ********/
12556       for (filePtr.i = 0; filePtr.i < cfileFileSize; filePtr.i++) {
12557 	ptrAss(filePtr, fileRecord);
12558 	filePtr.p->nextFile = filePtr.i + 1;
12559 	filePtr.p->fileStatus = FileRecord::CLOSED;
12560 	filePtr.p->reqStatus = FileRecord::IDLE;
12561       }//for
12562       filePtr.i = cfileFileSize - 1;
12563       ptrAss(filePtr, fileRecord);
12564       filePtr.p->nextFile = RNIL;
12565       cfirstfreeFile = 0;
12566       initRestorableGciFiles();
12567       break;
12568     }
12569   case 4:
12570     jam();
12571     initialiseFragstore();
12572     break;
12573   case 5:
12574     {
12575       jam();
12576       /******* NODE GROUP RECORD ******/
12577       /******* NODE RECORD       ******/
12578       NodeGroupRecordPtr loopNGPtr;
12579       for (loopNGPtr.i = 0; loopNGPtr.i < MAX_NDB_NODES; loopNGPtr.i++) {
12580 	ptrAss(loopNGPtr, nodeGroupRecord);
12581 	loopNGPtr.p->nodesInGroup[0] = RNIL;
12582 	loopNGPtr.p->nodesInGroup[1] = RNIL;
12583 	loopNGPtr.p->nodesInGroup[2] = RNIL;
12584 	loopNGPtr.p->nodesInGroup[3] = RNIL;
12585 	loopNGPtr.p->nextReplicaNode = 0;
12586 	loopNGPtr.p->nodeCount = 0;
12587 	loopNGPtr.p->activeTakeOver = false;
12588       }//for
12589       NodeRecordPtr nodePtr;
12590       for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
12591 	ptrAss(nodePtr, nodeRecord);
12592 	new (nodePtr.p) NodeRecord();
12593       }//for
12594       break;
12595     }
12596   case 6:
12597     {
12598       PageRecordPtr pagePtr;
12599       jam();
12600       /******* PAGE RECORD ******/
12601       for (pagePtr.i = 0; pagePtr.i < cpageFileSize; pagePtr.i++) {
12602         refresh_watch_dog();
12603 	ptrAss(pagePtr, pageRecord);
12604 	pagePtr.p->nextfreepage = pagePtr.i + 1;
12605       }//for
12606       pagePtr.i = cpageFileSize - 1;
12607       ptrAss(pagePtr, pageRecord);
12608       pagePtr.p->nextfreepage = RNIL;
12609       cfirstfreepage = 0;
12610       break;
12611     }
12612   case 7:
12613     {
12614       ReplicaRecordPtr initReplicaPtr;
12615       jam();
12616       /******* REPLICA RECORD ******/
12617       for (initReplicaPtr.i = 0; initReplicaPtr.i < creplicaFileSize;
12618 	   initReplicaPtr.i++) {
12619         refresh_watch_dog();
12620 	ptrAss(initReplicaPtr, replicaRecord);
12621 	initReplicaPtr.p->lcpIdStarted = 0;
12622 	initReplicaPtr.p->lcpOngoingFlag = false;
12623 	initReplicaPtr.p->nextReplica = initReplicaPtr.i + 1;
12624       }//for
12625       initReplicaPtr.i = creplicaFileSize - 1;
12626       ptrAss(initReplicaPtr, replicaRecord);
12627       initReplicaPtr.p->nextReplica = RNIL;
12628       cnoFreeReplicaRec = creplicaFileSize;
12629       cfirstfreeReplica = 0;
12630       break;
12631     }
12632   case 8:
12633     {
12634       TabRecordPtr loopTabptr;
12635       jam();
12636       /********* TAB-DESCRIPTOR ********/
12637       for (loopTabptr.i = 0; loopTabptr.i < ctabFileSize; loopTabptr.i++) {
12638 	ptrAss(loopTabptr, tabRecord);
12639         refresh_watch_dog();
12640 	initTable(loopTabptr);
12641       }//for
12642       break;
12643     }
12644   case 9:
12645     {
12646       TakeOverRecordPtr takeOverPtr;
12647       jam();
12648       cfirstfreeTakeOver = RNIL;
12649       for (takeOverPtr.i = 0; takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
12650 	ptrAss(takeOverPtr, takeOverRecord);
12651 	initTakeOver(takeOverPtr);
12652 	releaseTakeOver(takeOverPtr.i);
12653       }//for
12654 
12655       ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
12656       conf->senderRef = reference();
12657       conf->senderData = retData;
12658       sendSignal(retRef, GSN_READ_CONFIG_CONF, signal,
12659 		 ReadConfigConf::SignalLength, JBB);
12660       return;
12661       break;
12662     }
12663   default:
12664     ndbrequire(false);
12665     break;
12666   }//switch
12667   jam();
12668   /* ---------------------------------------------------------------------- */
12669   /* SEND REAL-TIME BREAK DURING INIT OF VARIABLES DURING SYSTEM RESTART.   */
12670   /* ---------------------------------------------------------------------- */
12671   signal->theData[0] = DihContinueB::ZINITIALISE_RECORDS;
12672   signal->theData[1] = stepNo + 1;
12673   signal->theData[2] = retRef;
12674   signal->theData[3] = retData;
12675   sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
12676 }//Dbdih::initialiseRecordsLab()
12677 
12678 /*************************************************************************/
12679 /*       INSERT THE NODE INTO THE LINKED LIST OF NODES INVOLVED ALL      */
12680 /*       DISTRIBUTED PROTOCOLS (EXCEPT GCP PROTOCOL THAT USES THE DIH    */
12681 /*       LINKED LIST INSTEAD).                                           */
12682 /*************************************************************************/
insertAlive(NodeRecordPtr newNodePtr)12683 void Dbdih::insertAlive(NodeRecordPtr newNodePtr)
12684 {
12685   NodeRecordPtr nodePtr;
12686 
12687   nodePtr.i = cfirstAliveNode;
12688   if (nodePtr.i == RNIL) {
12689     jam();
12690     cfirstAliveNode = newNodePtr.i;
12691   } else {
12692     do {
12693       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12694       if (nodePtr.p->nextNode == RNIL) {
12695         jam();
12696         nodePtr.p->nextNode = newNodePtr.i;
12697         break;
12698       } else {
12699         jam();
12700         nodePtr.i = nodePtr.p->nextNode;
12701       }//if
12702     } while (1);
12703   }//if
12704   newNodePtr.p->nextNode = RNIL;
12705 }//Dbdih::insertAlive()
12706 
insertBackup(FragmentstorePtr fragPtr,Uint32 nodeId)12707 void Dbdih::insertBackup(FragmentstorePtr fragPtr, Uint32 nodeId)
12708 {
12709   for (Uint32 i = fragPtr.p->fragReplicas; i > 1; i--) {
12710     jam();
12711     ndbrequire(i < MAX_REPLICAS && i > 0);
12712     fragPtr.p->activeNodes[i] = fragPtr.p->activeNodes[i - 1];
12713   }//for
12714   fragPtr.p->activeNodes[1] = nodeId;
12715   fragPtr.p->fragReplicas++;
12716 }//Dbdih::insertBackup()
12717 
insertDeadNode(NodeRecordPtr newNodePtr)12718 void Dbdih::insertDeadNode(NodeRecordPtr newNodePtr)
12719 {
12720   NodeRecordPtr nodePtr;
12721 
12722   nodePtr.i = cfirstDeadNode;
12723   if (nodePtr.i == RNIL) {
12724     jam();
12725     cfirstDeadNode = newNodePtr.i;
12726   } else {
12727     do {
12728       jam();
12729       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12730       if (nodePtr.p->nextNode == RNIL) {
12731         jam();
12732         nodePtr.p->nextNode = newNodePtr.i;
12733         break;
12734       } else {
12735         jam();
12736         nodePtr.i = nodePtr.p->nextNode;
12737       }//if
12738     } while (1);
12739   }//if
12740   newNodePtr.p->nextNode = RNIL;
12741 }//Dbdih::insertDeadNode()
12742 
linkOldStoredReplica(FragmentstorePtr fragPtr,ReplicaRecordPtr replicatePtr)12743 void Dbdih::linkOldStoredReplica(FragmentstorePtr fragPtr,
12744                                  ReplicaRecordPtr replicatePtr)
12745 {
12746   ReplicaRecordPtr losReplicaPtr;
12747 
12748   replicatePtr.p->nextReplica = RNIL;
12749   fragPtr.p->noOldStoredReplicas++;
12750   losReplicaPtr.i = fragPtr.p->oldStoredReplicas;
12751   if (losReplicaPtr.i == RNIL) {
12752     jam();
12753     fragPtr.p->oldStoredReplicas = replicatePtr.i;
12754     return;
12755   }//if
12756   ptrCheckGuard(losReplicaPtr, creplicaFileSize, replicaRecord);
12757   while (losReplicaPtr.p->nextReplica != RNIL) {
12758     jam();
12759     losReplicaPtr.i = losReplicaPtr.p->nextReplica;
12760     ptrCheckGuard(losReplicaPtr, creplicaFileSize, replicaRecord);
12761   }//if
12762   losReplicaPtr.p->nextReplica = replicatePtr.i;
12763 }//Dbdih::linkOldStoredReplica()
12764 
linkStoredReplica(FragmentstorePtr fragPtr,ReplicaRecordPtr replicatePtr)12765 void Dbdih::linkStoredReplica(FragmentstorePtr fragPtr,
12766                               ReplicaRecordPtr replicatePtr)
12767 {
12768   ReplicaRecordPtr lsrReplicaPtr;
12769 
12770   fragPtr.p->noStoredReplicas++;
12771   replicatePtr.p->nextReplica = RNIL;
12772   lsrReplicaPtr.i = fragPtr.p->storedReplicas;
12773   if (fragPtr.p->storedReplicas == RNIL) {
12774     jam();
12775     fragPtr.p->storedReplicas = replicatePtr.i;
12776     return;
12777   }//if
12778   ptrCheckGuard(lsrReplicaPtr, creplicaFileSize, replicaRecord);
12779   while (lsrReplicaPtr.p->nextReplica != RNIL) {
12780     jam();
12781     lsrReplicaPtr.i = lsrReplicaPtr.p->nextReplica;
12782     ptrCheckGuard(lsrReplicaPtr, creplicaFileSize, replicaRecord);
12783   }//if
12784   lsrReplicaPtr.p->nextReplica = replicatePtr.i;
12785 }//Dbdih::linkStoredReplica()
12786 
12787 /*************************************************************************/
12788 /*        MAKE NODE GROUPS BASED ON THE LIST OF NODES RECEIVED FROM CNTR */
12789 /*************************************************************************/
makeNodeGroups(Uint32 nodeArray[])12790 void Dbdih::makeNodeGroups(Uint32 nodeArray[])
12791 {
12792   NodeRecordPtr mngNodeptr;
12793   Uint32 tmngNode;
12794   Uint32 tmngNodeGroup;
12795   Uint32 tmngLimit;
12796   Uint32 i, j;
12797 
12798   /**-----------------------------------------------------------------------
12799    * ASSIGN ALL ACTIVE NODES INTO NODE GROUPS. HOT SPARE NODES ARE ASSIGNED
12800    * TO NODE GROUP ZNIL
12801    *-----------------------------------------------------------------------*/
12802   tmngNodeGroup = 0;
12803   tmngLimit = csystemnodes - cnoHotSpare;
12804   ndbrequire(tmngLimit < MAX_NDB_NODES);
12805   for (i = 0; i < tmngLimit; i++) {
12806     NodeGroupRecordPtr NGPtr;
12807     jam();
12808     tmngNode = nodeArray[i];
12809     mngNodeptr.i = tmngNode;
12810     ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
12811     mngNodeptr.p->nodeGroup = tmngNodeGroup;
12812     NGPtr.i = tmngNodeGroup;
12813     ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
12814     arrGuard(NGPtr.p->nodeCount, MAX_REPLICAS);
12815     NGPtr.p->nodesInGroup[NGPtr.p->nodeCount++] = mngNodeptr.i;
12816     if (NGPtr.p->nodeCount == cnoReplicas) {
12817       jam();
12818       tmngNodeGroup++;
12819     }//if
12820   }//for
12821   cnoOfNodeGroups = tmngNodeGroup;
12822   ndbrequire(csystemnodes < MAX_NDB_NODES);
12823   for (i = tmngLimit + 1; i < csystemnodes; i++) {
12824     jam();
12825     tmngNode = nodeArray[i];
12826     mngNodeptr.i = tmngNode;
12827     ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
12828     mngNodeptr.p->nodeGroup = ZNIL;
12829   }//for
12830   for(i = 0; i < MAX_NDB_NODES; i++){
12831     jam();
12832     Sysfile::setNodeGroup(i, SYSFILE->nodeGroups, NO_NODE_GROUP_ID);
12833   }//for
12834   for (mngNodeptr.i = 1; mngNodeptr.i < MAX_NDB_NODES; mngNodeptr.i++) {
12835     jam();
12836     ptrAss(mngNodeptr, nodeRecord);
12837     if (mngNodeptr.p->nodeGroup != ZNIL) {
12838       jam();
12839       Sysfile::setNodeGroup(mngNodeptr.i, SYSFILE->nodeGroups, mngNodeptr.p->nodeGroup);
12840     }//if
12841   }//for
12842 
12843   for (i = 0; i<cnoOfNodeGroups; i++)
12844   {
12845     jam();
12846     bool alive = false;
12847     NodeGroupRecordPtr NGPtr;
12848     NGPtr.i = i;
12849     ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
12850     for (j = 0; j<NGPtr.p->nodeCount; j++)
12851     {
12852       jam();
12853       mngNodeptr.i = NGPtr.p->nodesInGroup[j];
12854       ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
12855       if (checkNodeAlive(NGPtr.p->nodesInGroup[j]))
12856       {
12857 	alive = true;
12858 	break;
12859       }
12860     }
12861 
12862     if (!alive)
12863     {
12864       char buf[255];
12865       BaseString::snprintf
12866 	(buf, sizeof(buf),
12867 	 "Illegal initial start, no alive node in nodegroup %u", i);
12868       progError(__LINE__,
12869 		NDBD_EXIT_INSUFFICENT_NODES,
12870 		buf);
12871 
12872     }
12873   }
12874 }//Dbdih::makeNodeGroups()
12875 
12876 /**
12877  * On node failure QMGR asks DIH about node groups.  This is
12878  * a direct signal (function call in same process).  Input is
12879  * bitmask of surviving nodes.  The routine is not concerned
12880  * about node count.  Reply is one of:
12881  * 1) win - we can survive, and nobody else can
12882  * 2) lose - we cannot survive
12883  * 3) partition - we can survive but there could be others
12884  */
execCHECKNODEGROUPSREQ(Signal * signal)12885 void Dbdih::execCHECKNODEGROUPSREQ(Signal* signal)
12886 {
12887   jamEntry();
12888   CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
12889 
12890   bool direct = (sd->requestType & CheckNodeGroups::Direct);
12891   bool ok = false;
12892   switch(sd->requestType & ~CheckNodeGroups::Direct){
12893   case CheckNodeGroups::ArbitCheck:{
12894     ok = true;
12895     jam();
12896     unsigned missall = 0;
12897     unsigned haveall = 0;
12898     for (Uint32 i = 0; i < cnoOfNodeGroups; i++) {
12899       jam();
12900       NodeGroupRecordPtr ngPtr;
12901       ngPtr.i = i;
12902       ptrAss(ngPtr, nodeGroupRecord);
12903       Uint32 count = 0;
12904       for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
12905 	jam();
12906 	Uint32 nodeId = ngPtr.p->nodesInGroup[j];
12907 	if (sd->mask.get(nodeId)) {
12908 	  jam();
12909 	  count++;
12910 	}//if
12911       }//for
12912       if (count == 0) {
12913 	jam();
12914 	missall++;
12915       }//if
12916       if (count == ngPtr.p->nodeCount) {
12917 	haveall++;
12918       }//if
12919     }//for
12920 
12921     if (missall) {
12922       jam();
12923       sd->output = CheckNodeGroups::Lose;
12924     } else if (haveall) {
12925       jam();
12926       sd->output = CheckNodeGroups::Win;
12927     } else {
12928       jam();
12929       sd->output = CheckNodeGroups::Partitioning;
12930     }//if
12931   }
12932     break;
12933   case CheckNodeGroups::GetNodeGroup:
12934     ok = true;
12935     sd->output = Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
12936     break;
12937   case CheckNodeGroups::GetNodeGroupMembers: {
12938     ok = true;
12939     Uint32 ownNodeGroup =
12940       Sysfile::getNodeGroup(sd->nodeId, SYSFILE->nodeGroups);
12941 
12942     sd->output = ownNodeGroup;
12943     sd->mask.clear();
12944 
12945     NodeGroupRecordPtr ngPtr;
12946     ngPtr.i = ownNodeGroup;
12947     ptrAss(ngPtr, nodeGroupRecord);
12948     for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
12949       jam();
12950       sd->mask.set(ngPtr.p->nodesInGroup[j]);
12951     }
12952 #if 0
12953     for (int i = 0; i < MAX_NDB_NODES; i++) {
12954       if (ownNodeGroup ==
12955 	  Sysfile::getNodeGroup(i, SYSFILE->nodeGroups)) {
12956 	sd->mask.set(i);
12957       }
12958     }
12959 #endif
12960   }
12961     break;
12962   }
12963   ndbrequire(ok);
12964 
12965   if (!direct)
12966     sendSignal(sd->blockRef, GSN_CHECKNODEGROUPSCONF, signal,
12967 	       CheckNodeGroups::SignalLength, JBB);
12968 }//Dbdih::execCHECKNODEGROUPSREQ()
12969 
makePrnList(ReadNodesConf * readNodes,Uint32 nodeArray[])12970 void Dbdih::makePrnList(ReadNodesConf * readNodes, Uint32 nodeArray[])
12971 {
12972   cfirstAliveNode = RNIL;
12973   ndbrequire(con_lineNodes > 0);
12974   ndbrequire(csystemnodes < MAX_NDB_NODES);
12975   for (Uint32 i = 0; i < csystemnodes; i++) {
12976     NodeRecordPtr nodePtr;
12977     jam();
12978     nodePtr.i = nodeArray[i];
12979     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12980     new (nodePtr.p) NodeRecord();
12981     if (NodeBitmask::get(readNodes->inactiveNodes, nodePtr.i) == false){
12982       jam();
12983       nodePtr.p->nodeStatus = NodeRecord::ALIVE;
12984       nodePtr.p->useInTransactions = true;
12985       nodePtr.p->copyCompleted = true;
12986       nodePtr.p->m_inclDihLcp = true;
12987       insertAlive(nodePtr);
12988     } else {
12989       jam();
12990       nodePtr.p->nodeStatus = NodeRecord::DEAD;
12991       insertDeadNode(nodePtr);
12992     }//if
12993   }//for
12994 }//Dbdih::makePrnList()
12995 
12996 /*************************************************************************/
12997 /*       A NEW CRASHED REPLICA IS ADDED BY A NODE FAILURE.               */
12998 /*************************************************************************/
newCrashedReplica(Uint32 nodeId,ReplicaRecordPtr ncrReplicaPtr)12999 void Dbdih::newCrashedReplica(Uint32 nodeId, ReplicaRecordPtr ncrReplicaPtr)
13000 {
13001   /*----------------------------------------------------------------------*/
13002   /*       SET THE REPLICA_LAST_GCI OF THE CRASHED REPLICA TO LAST GCI    */
13003   /*       EXECUTED BY THE FAILED NODE.                                   */
13004   /*----------------------------------------------------------------------*/
13005   /*       WE HAVE A NEW CRASHED REPLICA. INITIATE CREATE GCI TO INDICATE */
13006   /*       THAT THE NEW REPLICA IS NOT STARTED YET AND REPLICA_LAST_GCI IS*/
13007   /*       SET TO -1 TO INDICATE THAT IT IS NOT DEAD YET.                 */
13008   /*----------------------------------------------------------------------*/
13009   Uint32 lastGCI = SYSFILE->lastCompletedGCI[nodeId];
13010   arrGuardErr(ncrReplicaPtr.p->noCrashedReplicas + 1, 8,
13011               NDBD_EXIT_MAX_CRASHED_REPLICAS);
13012   ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
13013     lastGCI;
13014   ncrReplicaPtr.p->noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas + 1;
13015   ncrReplicaPtr.p->createGci[ncrReplicaPtr.p->noCrashedReplicas] = 0;
13016   ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
13017     (Uint32)-1;
13018 
13019   if (ncrReplicaPtr.p->noCrashedReplicas == 7 && lastGCI)
13020   {
13021     jam();
13022     SYSFILE->lastCompletedGCI[nodeId] = 0;
13023     warningEvent("Making filesystem for node %d unusable (need --initial)",
13024 		 nodeId);
13025   }
13026 }//Dbdih::newCrashedReplica()
13027 
13028 /*************************************************************************/
13029 /*       AT NODE FAILURE DURING START OF A NEW NODE WE NEED TO RESET A   */
13030 /*       SET OF VARIABLES CONTROLLING THE START AND INDICATING ONGOING   */
13031 /*       START OF A NEW NODE.                                            */
13032 /*************************************************************************/
nodeResetStart()13033 void Dbdih::nodeResetStart()
13034 {
13035   jam();
13036   c_nodeStartSlave.nodeId = 0;
13037   c_nodeStartMaster.startNode = RNIL;
13038   c_nodeStartMaster.failNr = cfailurenr;
13039   c_nodeStartMaster.activeState = false;
13040   c_nodeStartMaster.blockGcp = false;
13041   c_nodeStartMaster.blockLcp = false;
13042   c_nodeStartMaster.m_outstandingGsn = 0;
13043 }//Dbdih::nodeResetStart()
13044 
openFileRw(Signal * signal,FileRecordPtr filePtr)13045 void Dbdih::openFileRw(Signal* signal, FileRecordPtr filePtr)
13046 {
13047   signal->theData[0] = reference();
13048   signal->theData[1] = filePtr.i;
13049   signal->theData[2] = filePtr.p->fileName[0];
13050   signal->theData[3] = filePtr.p->fileName[1];
13051   signal->theData[4] = filePtr.p->fileName[2];
13052   signal->theData[5] = filePtr.p->fileName[3];
13053   signal->theData[6] = FsOpenReq::OM_READWRITE;
13054   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
13055 }//Dbdih::openFileRw()
13056 
openFileRo(Signal * signal,FileRecordPtr filePtr)13057 void Dbdih::openFileRo(Signal* signal, FileRecordPtr filePtr)
13058 {
13059   signal->theData[0] = reference();
13060   signal->theData[1] = filePtr.i;
13061   signal->theData[2] = filePtr.p->fileName[0];
13062   signal->theData[3] = filePtr.p->fileName[1];
13063   signal->theData[4] = filePtr.p->fileName[2];
13064   signal->theData[5] = filePtr.p->fileName[3];
13065   signal->theData[6] = FsOpenReq::OM_READONLY;
13066   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
13067 }//Dbdih::openFileRw()
13068 
13069 /*************************************************************************/
13070 /*       REMOVE A CRASHED REPLICA BY PACKING THE ARRAY OF CREATED GCI AND*/
13071 /*       THE LAST GCI OF THE CRASHED REPLICA.                            */
13072 /*************************************************************************/
packCrashedReplicas(ReplicaRecordPtr replicaPtr)13073 void Dbdih::packCrashedReplicas(ReplicaRecordPtr replicaPtr)
13074 {
13075   ndbrequire(replicaPtr.p->noCrashedReplicas > 0);
13076   ndbrequire(replicaPtr.p->noCrashedReplicas <= 8);
13077   for (Uint32 i = 0; i < replicaPtr.p->noCrashedReplicas; i++) {
13078     jam();
13079     replicaPtr.p->createGci[i] = replicaPtr.p->createGci[i + 1];
13080     replicaPtr.p->replicaLastGci[i] = replicaPtr.p->replicaLastGci[i + 1];
13081   }//for
13082   replicaPtr.p->noCrashedReplicas--;
13083 
13084 #ifdef VM_TRACE
13085   for (Uint32 i = 0; i < replicaPtr.p->noCrashedReplicas; i++) {
13086     jam();
13087     ndbrequire(replicaPtr.p->createGci[i] != 0xF1F1F1F1);
13088     ndbrequire(replicaPtr.p->replicaLastGci[i] != 0xF1F1F1F1);
13089   }//for
13090 #endif
13091 }//Dbdih::packCrashedReplicas()
13092 
prepareReplicas(FragmentstorePtr fragPtr)13093 void Dbdih::prepareReplicas(FragmentstorePtr fragPtr)
13094 {
13095   ReplicaRecordPtr prReplicaPtr;
13096   Uint32 prevReplica = RNIL;
13097 
13098   /* --------------------------------------------------------------------- */
13099   /*       BEGIN BY LINKING ALL REPLICA RECORDS ONTO THE OLD STORED REPLICA*/
13100   /*       LIST.                                                           */
13101   /*       AT A SYSTEM RESTART OBVIOUSLY ALL NODES ARE OLD.                */
13102   /* --------------------------------------------------------------------- */
13103   prReplicaPtr.i = fragPtr.p->storedReplicas;
13104   while (prReplicaPtr.i != RNIL) {
13105     jam();
13106     prevReplica = prReplicaPtr.i;
13107     ptrCheckGuard(prReplicaPtr, creplicaFileSize, replicaRecord);
13108     prReplicaPtr.i = prReplicaPtr.p->nextReplica;
13109   }//while
13110   /* --------------------------------------------------------------------- */
13111   /*       LIST OF STORED REPLICAS WILL BE EMPTY NOW.                      */
13112   /* --------------------------------------------------------------------- */
13113   if (prevReplica != RNIL) {
13114     prReplicaPtr.i = prevReplica;
13115     ptrCheckGuard(prReplicaPtr, creplicaFileSize, replicaRecord);
13116     prReplicaPtr.p->nextReplica = fragPtr.p->oldStoredReplicas;
13117     fragPtr.p->oldStoredReplicas = fragPtr.p->storedReplicas;
13118     fragPtr.p->storedReplicas = RNIL;
13119     fragPtr.p->noOldStoredReplicas += fragPtr.p->noStoredReplicas;
13120     fragPtr.p->noStoredReplicas = 0;
13121   }//if
13122 }//Dbdih::prepareReplicas()
13123 
readFragment(RWFragment * rf,FragmentstorePtr fragPtr)13124 void Dbdih::readFragment(RWFragment* rf, FragmentstorePtr fragPtr)
13125 {
13126   Uint32 TreadFid = readPageWord(rf);
13127   fragPtr.p->preferredPrimary = readPageWord(rf);
13128   fragPtr.p->noStoredReplicas = readPageWord(rf);
13129   fragPtr.p->noOldStoredReplicas = readPageWord(rf);
13130   Uint32 TdistKey = readPageWord(rf);
13131 
13132   ndbrequire(fragPtr.p->noStoredReplicas > 0);
13133   ndbrequire(TreadFid == rf->fragId);
13134   ndbrequire(TdistKey < 256);
13135   if ((cstarttype == NodeState::ST_NODE_RESTART) ||
13136       (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)) {
13137     jam();
13138     fragPtr.p->distributionKey = TdistKey;
13139   }//if
13140 
13141   fragPtr.p->m_log_part_id = readPageWord(rf);
13142 }//Dbdih::readFragment()
13143 
readPageWord(RWFragment * rf)13144 Uint32 Dbdih::readPageWord(RWFragment* rf)
13145 {
13146   if (rf->wordIndex >= 2048) {
13147     jam();
13148     ndbrequire(rf->wordIndex == 2048);
13149     rf->pageIndex++;
13150     ndbrequire(rf->pageIndex < 8);
13151     rf->rwfPageptr.i = rf->rwfTabPtr.p->pageRef[rf->pageIndex];
13152     ptrCheckGuard(rf->rwfPageptr, cpageFileSize, pageRecord);
13153     rf->wordIndex = 32;
13154   }//if
13155   Uint32 dataWord = rf->rwfPageptr.p->word[rf->wordIndex];
13156   rf->wordIndex++;
13157   return dataWord;
13158 }//Dbdih::readPageWord()
13159 
readReplica(RWFragment * rf,ReplicaRecordPtr readReplicaPtr)13160 void Dbdih::readReplica(RWFragment* rf, ReplicaRecordPtr readReplicaPtr)
13161 {
13162   Uint32 i;
13163   readReplicaPtr.p->procNode = readPageWord(rf);
13164   readReplicaPtr.p->initialGci = readPageWord(rf);
13165   readReplicaPtr.p->noCrashedReplicas = readPageWord(rf);
13166   readReplicaPtr.p->nextLcp = readPageWord(rf);
13167 
13168   for (i = 0; i < MAX_LCP_STORED; i++) {
13169     readReplicaPtr.p->maxGciCompleted[i] = readPageWord(rf);
13170     readReplicaPtr.p->maxGciStarted[i] = readPageWord(rf);
13171     readReplicaPtr.p->lcpId[i] = readPageWord(rf);
13172     readReplicaPtr.p->lcpStatus[i] = readPageWord(rf);
13173   }//for
13174   const Uint32 noCrashedReplicas = readReplicaPtr.p->noCrashedReplicas;
13175   ndbrequire(noCrashedReplicas < 8);
13176   for (i = 0; i < noCrashedReplicas; i++) {
13177     readReplicaPtr.p->createGci[i] = readPageWord(rf);
13178     readReplicaPtr.p->replicaLastGci[i] = readPageWord(rf);
13179     ndbrequire(readReplicaPtr.p->createGci[i] != 0xF1F1F1F1);
13180     ndbrequire(readReplicaPtr.p->replicaLastGci[i] != 0xF1F1F1F1);
13181   }//for
13182   for(i = noCrashedReplicas; i<8; i++){
13183     readReplicaPtr.p->createGci[i] = readPageWord(rf);
13184     readReplicaPtr.p->replicaLastGci[i] = readPageWord(rf);
13185     // They are not initialized...
13186     readReplicaPtr.p->createGci[i] = 0;
13187     readReplicaPtr.p->replicaLastGci[i] = ~0;
13188   }
13189   /* ---------------------------------------------------------------------- */
13190   /*       IF THE LAST COMPLETED LOCAL CHECKPOINT IS VALID AND LARGER THAN  */
13191   /*       THE LAST COMPLETED CHECKPOINT THEN WE WILL INVALIDATE THIS LOCAL */
13192   /*       CHECKPOINT FOR THIS REPLICA.                                     */
13193   /* ---------------------------------------------------------------------- */
13194   Uint32 trraLcp = prevLcpNo(readReplicaPtr.p->nextLcp);
13195   ndbrequire(trraLcp < MAX_LCP_STORED);
13196   if ((readReplicaPtr.p->lcpStatus[trraLcp] == ZVALID) &&
13197       (readReplicaPtr.p->lcpId[trraLcp] > SYSFILE->latestLCP_ID)) {
13198     jam();
13199     readReplicaPtr.p->lcpStatus[trraLcp] = ZINVALID;
13200   }//if
13201   /* ---------------------------------------------------------------------- */
13202   /*       WE ALSO HAVE TO INVALIDATE ANY LOCAL CHECKPOINTS THAT HAVE BEEN  */
13203   /*       INVALIDATED BY MOVING BACK THE RESTART GCI.                      */
13204   /* ---------------------------------------------------------------------- */
13205   for (i = 0; i < MAX_LCP_STORED; i++) {
13206     jam();
13207     if ((readReplicaPtr.p->lcpStatus[i] == ZVALID) &&
13208         (readReplicaPtr.p->maxGciStarted[i] > SYSFILE->newestRestorableGCI)) {
13209       jam();
13210       readReplicaPtr.p->lcpStatus[i] = ZINVALID;
13211     }//if
13212   }//for
13213   /* ---------------------------------------------------------------------- */
13214   /*       WE WILL REMOVE ANY OCCURRENCES OF REPLICAS THAT HAVE CRASHED     */
13215   /*       THAT ARE NO LONGER VALID DUE TO MOVING RESTART GCI BACKWARDS.    */
13216   /* ---------------------------------------------------------------------- */
13217   removeTooNewCrashedReplicas(readReplicaPtr);
13218   /* ---------------------------------------------------------------------- */
13219   /*       WE WILL REMOVE ANY OCCURRENCES OF REPLICAS THAT HAVE CRASHED     */
13220   /*       THAT ARE NO LONGER VALID SINCE THEY ARE NO LONGER RESTORABLE.    */
13221   /* ---------------------------------------------------------------------- */
13222   removeOldCrashedReplicas(readReplicaPtr);
13223   /* --------------------------------------------------------------------- */
13224   // We set the last GCI of the replica that was alive before the node
13225   // crashed last time. We set it to the last GCI which the node participated in.
13226   /* --------------------------------------------------------------------- */
13227   ndbrequire(readReplicaPtr.p->noCrashedReplicas < 8);
13228   readReplicaPtr.p->replicaLastGci[readReplicaPtr.p->noCrashedReplicas] =
13229     SYSFILE->lastCompletedGCI[readReplicaPtr.p->procNode];
13230   /* ---------------------------------------------------------------------- */
13231   /*       FIND PROCESSOR RECORD                                            */
13232   /* ---------------------------------------------------------------------- */
13233 }//Dbdih::readReplica()
13234 
readReplicas(RWFragment * rf,FragmentstorePtr fragPtr)13235 void Dbdih::readReplicas(RWFragment* rf, FragmentstorePtr fragPtr)
13236 {
13237   Uint32 i;
13238   ReplicaRecordPtr newReplicaPtr;
13239   Uint32 noStoredReplicas = fragPtr.p->noStoredReplicas;
13240   Uint32 noOldStoredReplicas = fragPtr.p->noOldStoredReplicas;
13241   /* ----------------------------------------------------------------------- */
13242   /*      WE CLEAR THE NUMBER OF STORED REPLICAS SINCE IT WILL BE CALCULATED */
13243   /*      BY THE LINKING SUBROUTINES.                                        */
13244   /* ----------------------------------------------------------------------- */
13245   fragPtr.p->noStoredReplicas = 0;
13246   fragPtr.p->noOldStoredReplicas = 0;
13247   Uint32 replicaIndex = 0;
13248   ndbrequire(noStoredReplicas + noOldStoredReplicas <= MAX_REPLICAS);
13249   for (i = 0; i < noStoredReplicas; i++) {
13250     seizeReplicaRec(newReplicaPtr);
13251     readReplica(rf, newReplicaPtr);
13252     if (checkNodeAlive(newReplicaPtr.p->procNode)) {
13253       jam();
13254       ndbrequire(replicaIndex < MAX_REPLICAS);
13255       fragPtr.p->activeNodes[replicaIndex] = newReplicaPtr.p->procNode;
13256       replicaIndex++;
13257       linkStoredReplica(fragPtr, newReplicaPtr);
13258     } else {
13259       jam();
13260       linkOldStoredReplica(fragPtr, newReplicaPtr);
13261     }//if
13262   }//for
13263   fragPtr.p->fragReplicas = noStoredReplicas;
13264   for (i = 0; i < noOldStoredReplicas; i++) {
13265     jam();
13266     seizeReplicaRec(newReplicaPtr);
13267     readReplica(rf, newReplicaPtr);
13268     linkOldStoredReplica(fragPtr, newReplicaPtr);
13269   }//for
13270 }//Dbdih::readReplicas()
13271 
readRestorableGci(Signal * signal,FileRecordPtr filePtr)13272 void Dbdih::readRestorableGci(Signal* signal, FileRecordPtr filePtr)
13273 {
13274   signal->theData[0] = filePtr.p->fileRef;
13275   signal->theData[1] = reference();
13276   signal->theData[2] = filePtr.i;
13277   signal->theData[3] = ZLIST_OF_PAIRS;
13278   signal->theData[4] = ZVAR_NO_CRESTART_INFO;
13279   signal->theData[5] = 1;
13280   signal->theData[6] = 0;
13281   signal->theData[7] = 0;
13282   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
13283 }//Dbdih::readRestorableGci()
13284 
readTabfile(Signal * signal,TabRecord * tab,FileRecordPtr filePtr)13285 void Dbdih::readTabfile(Signal* signal, TabRecord* tab, FileRecordPtr filePtr)
13286 {
13287   signal->theData[0] = filePtr.p->fileRef;
13288   signal->theData[1] = reference();
13289   signal->theData[2] = filePtr.i;
13290   signal->theData[3] = ZLIST_OF_PAIRS;
13291   signal->theData[4] = ZVAR_NO_WORD;
13292   signal->theData[5] = tab->noPages;
13293   for (Uint32 i = 0; i < tab->noPages; i++) {
13294     signal->theData[6 + (2 * i)] = tab->pageRef[i];
13295     signal->theData[7 + (2 * i)] = i;
13296   }//for
13297   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 22, JBA);
13298 }//Dbdih::readTabfile()
13299 
releasePage(Uint32 pageIndex)13300 void Dbdih::releasePage(Uint32 pageIndex)
13301 {
13302   PageRecordPtr pagePtr;
13303   pagePtr.i = pageIndex;
13304   ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
13305   pagePtr.p->nextfreepage = cfirstfreepage;
13306   cfirstfreepage = pagePtr.i;
13307 }//Dbdih::releasePage()
13308 
releaseTabPages(Uint32 tableId)13309 void Dbdih::releaseTabPages(Uint32 tableId)
13310 {
13311   TabRecordPtr tabPtr;
13312   tabPtr.i = tableId;
13313   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
13314   ndbrequire(tabPtr.p->noPages <= 8);
13315   for (Uint32 i = 0; i < tabPtr.p->noPages; i++) {
13316     jam();
13317     releasePage(tabPtr.p->pageRef[i]);
13318   }//for
13319   tabPtr.p->noPages = 0;
13320 }//Dbdih::releaseTabPages()
13321 
13322 /*************************************************************************/
13323 /*       REMOVE NODE FROM SET OF ALIVE NODES.                            */
13324 /*************************************************************************/
removeAlive(NodeRecordPtr removeNodePtr)13325 void Dbdih::removeAlive(NodeRecordPtr removeNodePtr)
13326 {
13327   NodeRecordPtr nodePtr;
13328 
13329   nodePtr.i = cfirstAliveNode;
13330   if (nodePtr.i == removeNodePtr.i) {
13331     jam();
13332     cfirstAliveNode = removeNodePtr.p->nextNode;
13333     return;
13334   }//if
13335   do {
13336     jam();
13337     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
13338     if (nodePtr.p->nextNode == removeNodePtr.i) {
13339       jam();
13340       nodePtr.p->nextNode = removeNodePtr.p->nextNode;
13341       break;
13342     } else {
13343       jam();
13344       nodePtr.i = nodePtr.p->nextNode;
13345     }//if
13346   } while (1);
13347 }//Dbdih::removeAlive()
13348 
13349 /*************************************************************************/
13350 /*       REMOVE NODE FROM SET OF DEAD NODES.                             */
13351 /*************************************************************************/
removeDeadNode(NodeRecordPtr removeNodePtr)13352 void Dbdih::removeDeadNode(NodeRecordPtr removeNodePtr)
13353 {
13354   NodeRecordPtr nodePtr;
13355 
13356   nodePtr.i = cfirstDeadNode;
13357   if (nodePtr.i == removeNodePtr.i) {
13358     jam();
13359     cfirstDeadNode = removeNodePtr.p->nextNode;
13360     return;
13361   }//if
13362   do {
13363     jam();
13364     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
13365     if (nodePtr.p->nextNode == removeNodePtr.i) {
13366       jam();
13367       nodePtr.p->nextNode = removeNodePtr.p->nextNode;
13368       break;
13369     } else {
13370       jam();
13371       nodePtr.i = nodePtr.p->nextNode;
13372     }//if
13373   } while (1);
13374 }//Dbdih::removeDeadNode()
13375 
13376 /*---------------------------------------------------------------*/
13377 /*       REMOVE REPLICAS OF A FAILED NODE FROM LIST OF STORED    */
13378 /*       REPLICAS AND MOVE IT TO THE LIST OF OLD STORED REPLICAS.*/
13379 /*       ALSO UPDATE THE CRASHED REPLICA INFORMATION.            */
13380 /*---------------------------------------------------------------*/
removeNodeFromStored(Uint32 nodeId,FragmentstorePtr fragPtr,ReplicaRecordPtr replicatePtr,bool temporary)13381 void Dbdih::removeNodeFromStored(Uint32 nodeId,
13382                                  FragmentstorePtr fragPtr,
13383                                  ReplicaRecordPtr replicatePtr,
13384 				 bool temporary)
13385 {
13386   if (!temporary)
13387   {
13388     jam();
13389     newCrashedReplica(nodeId, replicatePtr);
13390   }
13391   else
13392   {
13393     jam();
13394   }
13395   removeStoredReplica(fragPtr, replicatePtr);
13396   linkOldStoredReplica(fragPtr, replicatePtr);
13397   ndbrequire(fragPtr.p->storedReplicas != RNIL);
13398 }//Dbdih::removeNodeFromStored()
13399 
13400 /*************************************************************************/
13401 /*       REMOVE ANY OLD CRASHED REPLICAS THAT ARE NOT RESTORABLE ANY MORE*/
13402 /*************************************************************************/
removeOldCrashedReplicas(ReplicaRecordPtr rocReplicaPtr)13403 void Dbdih::removeOldCrashedReplicas(ReplicaRecordPtr rocReplicaPtr)
13404 {
13405   while (rocReplicaPtr.p->noCrashedReplicas > 0) {
13406     jam();
13407     /* --------------------------------------------------------------------- */
13408     /*       ONLY IF THERE IS AT LEAST ONE REPLICA THEN CAN WE REMOVE ANY.   */
13409     /* --------------------------------------------------------------------- */
13410     if (rocReplicaPtr.p->replicaLastGci[0] < SYSFILE->oldestRestorableGCI){
13411       jam();
13412       /* ------------------------------------------------------------------- */
13413       /*     THIS CRASHED REPLICA HAS BECOME EXTINCT AND MUST BE REMOVED TO  */
13414       /*     GIVE SPACE FOR NEW CRASHED REPLICAS.                            */
13415       /* ------------------------------------------------------------------- */
13416       packCrashedReplicas(rocReplicaPtr);
13417     } else {
13418       break;
13419     }//if
13420   }//while
13421   if (rocReplicaPtr.p->createGci[0] < SYSFILE->keepGCI){
13422     jam();
13423     /* --------------------------------------------------------------------- */
13424     /*       MOVE FORWARD THE CREATE GCI TO A GCI THAT CAN BE USED. WE HAVE  */
13425     /*       NO CERTAINTY IN FINDING ANY LOG RECORDS FROM OLDER GCI'S.       */
13426     /* --------------------------------------------------------------------- */
13427     rocReplicaPtr.p->createGci[0] = SYSFILE->keepGCI;
13428     ndbrequire(SYSFILE->keepGCI != 0xF1F1F1F1);
13429   }//if
13430 }//Dbdih::removeOldCrashedReplicas()
13431 
removeOldStoredReplica(FragmentstorePtr fragPtr,ReplicaRecordPtr replicatePtr)13432 void Dbdih::removeOldStoredReplica(FragmentstorePtr fragPtr,
13433                                    ReplicaRecordPtr replicatePtr)
13434 {
13435   ReplicaRecordPtr rosTmpReplicaPtr;
13436   ReplicaRecordPtr rosPrevReplicaPtr;
13437 
13438   fragPtr.p->noOldStoredReplicas--;
13439   if (fragPtr.p->oldStoredReplicas == replicatePtr.i) {
13440     jam();
13441     fragPtr.p->oldStoredReplicas = replicatePtr.p->nextReplica;
13442   } else {
13443     rosPrevReplicaPtr.i = fragPtr.p->oldStoredReplicas;
13444     ptrCheckGuard(rosPrevReplicaPtr, creplicaFileSize, replicaRecord);
13445     rosTmpReplicaPtr.i = rosPrevReplicaPtr.p->nextReplica;
13446     while (rosTmpReplicaPtr.i != replicatePtr.i) {
13447       jam();
13448       rosPrevReplicaPtr.i = rosTmpReplicaPtr.i;
13449       ptrCheckGuard(rosPrevReplicaPtr, creplicaFileSize, replicaRecord);
13450       ptrCheckGuard(rosTmpReplicaPtr, creplicaFileSize, replicaRecord);
13451       rosTmpReplicaPtr.i = rosTmpReplicaPtr.p->nextReplica;
13452     }//if
13453     rosPrevReplicaPtr.p->nextReplica = replicatePtr.p->nextReplica;
13454   }//if
13455 }//Dbdih::removeOldStoredReplica()
13456 
removeStoredReplica(FragmentstorePtr fragPtr,ReplicaRecordPtr replicatePtr)13457 void Dbdih::removeStoredReplica(FragmentstorePtr fragPtr,
13458                                 ReplicaRecordPtr replicatePtr)
13459 {
13460   ReplicaRecordPtr rsrTmpReplicaPtr;
13461   ReplicaRecordPtr rsrPrevReplicaPtr;
13462 
13463   fragPtr.p->noStoredReplicas--;
13464   if (fragPtr.p->storedReplicas == replicatePtr.i) {
13465     jam();
13466     fragPtr.p->storedReplicas = replicatePtr.p->nextReplica;
13467   } else {
13468     jam();
13469     rsrPrevReplicaPtr.i = fragPtr.p->storedReplicas;
13470     rsrTmpReplicaPtr.i = fragPtr.p->storedReplicas;
13471     ptrCheckGuard(rsrTmpReplicaPtr, creplicaFileSize, replicaRecord);
13472     rsrTmpReplicaPtr.i = rsrTmpReplicaPtr.p->nextReplica;
13473     while (rsrTmpReplicaPtr.i != replicatePtr.i) {
13474       jam();
13475       rsrPrevReplicaPtr.i = rsrTmpReplicaPtr.i;
13476       ptrCheckGuard(rsrTmpReplicaPtr, creplicaFileSize, replicaRecord);
13477       rsrTmpReplicaPtr.i = rsrTmpReplicaPtr.p->nextReplica;
13478     }//while
13479     ptrCheckGuard(rsrPrevReplicaPtr, creplicaFileSize, replicaRecord);
13480     rsrPrevReplicaPtr.p->nextReplica = replicatePtr.p->nextReplica;
13481   }//if
13482 }//Dbdih::removeStoredReplica()
13483 
13484 /*************************************************************************/
13485 /*       REMOVE ALL TOO NEW CRASHED REPLICAS THAT IS IN THIS REPLICA.    */
13486 /*************************************************************************/
removeTooNewCrashedReplicas(ReplicaRecordPtr rtnReplicaPtr)13487 void Dbdih::removeTooNewCrashedReplicas(ReplicaRecordPtr rtnReplicaPtr)
13488 {
13489   while (rtnReplicaPtr.p->noCrashedReplicas > 0) {
13490     jam();
13491     /* --------------------------------------------------------------------- */
13492     /*       REMOVE ALL REPLICAS THAT ONLY LIVED IN A PERIOD THAT HAVE BEEN  */
13493     /*       REMOVED FROM THE RESTART INFORMATION SINCE THE RESTART FAILED   */
13494     /*       TOO MANY TIMES.                                                 */
13495     /* --------------------------------------------------------------------- */
13496     arrGuard(rtnReplicaPtr.p->noCrashedReplicas - 1, 8);
13497     if (rtnReplicaPtr.p->createGci[rtnReplicaPtr.p->noCrashedReplicas - 1] >
13498         SYSFILE->newestRestorableGCI){
13499       jam();
13500       rtnReplicaPtr.p->createGci[rtnReplicaPtr.p->noCrashedReplicas - 1] =
13501 	(Uint32)-1;
13502       rtnReplicaPtr.p->replicaLastGci[rtnReplicaPtr.p->noCrashedReplicas - 1] =
13503 	(Uint32)-1;
13504       rtnReplicaPtr.p->noCrashedReplicas--;
13505     } else {
13506       break;
13507     }//if
13508   }//while
13509 }//Dbdih::removeTooNewCrashedReplicas()
13510 
13511 /*************************************************************************/
13512 /*                                                                       */
13513 /*       MODULE: SEARCH FOR POSSIBLE REPLICAS THAT CAN HANDLE THE GLOBAL */
13514 /*               CHECKPOINT WITHOUT NEEDING ANY EXTRA LOGGING FACILITIES.*/
13515 /*               A MAXIMUM OF FOUR NODES IS RETRIEVED.                   */
13516 /*************************************************************************/
13517 bool
setup_create_replica(FragmentstorePtr fragPtr,CreateReplicaRecord * createReplicaPtrP,ConstPtr<ReplicaRecord> replicaPtr)13518 Dbdih::setup_create_replica(FragmentstorePtr fragPtr,
13519 			    CreateReplicaRecord* createReplicaPtrP,
13520 			    ConstPtr<ReplicaRecord> replicaPtr)
13521 {
13522   createReplicaPtrP->dataNodeId = replicaPtr.p->procNode;
13523   createReplicaPtrP->replicaRec = replicaPtr.i;
13524 
13525   /* ----------------------------------------------------------------- */
13526   /*   WE NEED TO SEARCH FOR A PROPER LOCAL CHECKPOINT TO USE FOR THE  */
13527   /*   SYSTEM RESTART.                                                 */
13528   /* ----------------------------------------------------------------- */
13529   Uint32 startGci;
13530   Uint32 startLcpNo;
13531   Uint32 stopGci = SYSFILE->newestRestorableGCI;
13532   bool result = findStartGci(replicaPtr,
13533 			     stopGci,
13534 			     startGci,
13535 			     startLcpNo);
13536   if (!result)
13537   {
13538     jam();
13539     /* --------------------------------------------------------------- */
13540     /* WE COULD NOT FIND ANY LOCAL CHECKPOINT. THE FRAGMENT THUS DO NOT*/
13541     /* CONTAIN ANY VALID LOCAL CHECKPOINT. IT DOES HOWEVER CONTAIN A   */
13542     /* VALID FRAGMENT LOG. THUS BY FIRST CREATING THE FRAGMENT AND THEN*/
13543     /* EXECUTING THE FRAGMENT LOG WE CAN CREATE THE FRAGMENT AS        */
13544     /* DESIRED. THIS SHOULD ONLY OCCUR AFTER CREATING A FRAGMENT.      */
13545     /*                                                                 */
13546     /* TO INDICATE THAT NO LOCAL CHECKPOINT IS TO BE USED WE SET THE   */
13547     /* LOCAL CHECKPOINT TO ZNIL.                                       */
13548     /* --------------------------------------------------------------- */
13549     createReplicaPtrP->lcpNo = ZNIL;
13550   }
13551   else
13552   {
13553     jam();
13554     /* --------------------------------------------------------------- */
13555     /* WE FOUND A PROPER LOCAL CHECKPOINT TO RESTART FROM.             */
13556     /* SET LOCAL CHECKPOINT ID AND LOCAL CHECKPOINT NUMBER.            */
13557     /* --------------------------------------------------------------- */
13558     createReplicaPtrP->lcpNo = startLcpNo;
13559     arrGuard(startLcpNo, MAX_LCP_STORED);
13560     createReplicaPtrP->createLcpId = replicaPtr.p->lcpId[startLcpNo];
13561   }//if
13562 
13563 
13564   /* ----------------------------------------------------------------- */
13565   /*   WE HAVE EITHER FOUND A LOCAL CHECKPOINT OR WE ARE PLANNING TO   */
13566   /*   EXECUTE THE LOG FROM THE INITIAL CREATION OF THE TABLE. IN BOTH */
13567   /*   CASES WE NEED TO FIND A SET OF LOGS THAT CAN EXECUTE SUCH THAT  */
13568   /*   WE RECOVER TO THE SYSTEM RESTART GLOBAL CHECKPOINT.             */
13569   /* -_--------------------------------------------------------------- */
13570   return findLogNodes(createReplicaPtrP, fragPtr, startGci, stopGci);
13571 }
13572 
searchStoredReplicas(FragmentstorePtr fragPtr)13573 void Dbdih::searchStoredReplicas(FragmentstorePtr fragPtr)
13574 {
13575   Uint32 nextReplicaPtrI;
13576   Ptr<ReplicaRecord> replicaPtr;
13577 
13578   replicaPtr.i = fragPtr.p->storedReplicas;
13579   while (replicaPtr.i != RNIL) {
13580     jam();
13581     ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
13582     nextReplicaPtrI = replicaPtr.p->nextReplica;
13583     ConstPtr<ReplicaRecord> constReplicaPtr;
13584     constReplicaPtr.i = replicaPtr.i;
13585     constReplicaPtr.p = replicaPtr.p;
13586     NodeRecordPtr nodePtr;
13587     nodePtr.i = replicaPtr.p->procNode;
13588     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
13589     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
13590       jam();
13591       switch (nodePtr.p->activeStatus) {
13592       case Sysfile::NS_Active:
13593       case Sysfile::NS_ActiveMissed_1:
13594       case Sysfile::NS_ActiveMissed_2:{
13595 	/* ----------------------------------------------------------------- */
13596 	/*   INITIALISE THE CREATE REPLICA STRUCTURE THAT IS USED FOR SENDING*/
13597 	/*   TO LQH START_FRAGREQ.                                           */
13598 	/*   SET THE DATA NODE WHERE THE LOCAL CHECKPOINT IS FOUND. ALSO     */
13599 	/*   SET A REFERENCE TO THE REPLICA POINTER OF THAT.                 */
13600 	/* ----------------------------------------------------------------- */
13601 	CreateReplicaRecordPtr createReplicaPtr;
13602 	createReplicaPtr.i = cnoOfCreateReplicas;
13603 	ptrCheckGuard(createReplicaPtr, 4, createReplicaRecord);
13604 	cnoOfCreateReplicas++;
13605 
13606 	/**
13607 	 * Should have been checked in resetReplicaSr
13608 	 */
13609 	ndbrequire(setup_create_replica(fragPtr,
13610 					createReplicaPtr.p,
13611 					constReplicaPtr));
13612 	break;
13613       }
13614       default:
13615         jam();
13616         /*empty*/;
13617         break;
13618       }//switch
13619     }
13620     replicaPtr.i = nextReplicaPtrI;
13621   }//while
13622 }//Dbdih::searchStoredReplicas()
13623 
13624 /*************************************************************************/
13625 /*                                                                       */
13626 /*       MODULE: SEIZE_FILE                                              */
13627 /*       DESCRIPTION: THE SUBROUTINE SEIZES A FILE RECORD FROM THE       */
13628 /*                    FREE LIST.                                         */
13629 /*************************************************************************/
seizeFile(FileRecordPtr & filePtr)13630 void Dbdih::seizeFile(FileRecordPtr& filePtr)
13631 {
13632   filePtr.i = cfirstfreeFile;
13633   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
13634   cfirstfreeFile = filePtr.p->nextFile;
13635   filePtr.p->nextFile = RNIL;
13636 }//Dbdih::seizeFile()
13637 
13638 /*************************************************************************/
13639 /*       SEND CREATE_FRAGREQ TO ALL NODES IN THE NDB CLUSTER.            */
13640 /*************************************************************************/
13641 /*************************************************************************/
13642 /*                                                                       */
13643 /*       MODULE: FIND THE START GCI AND LOCAL CHECKPOINT TO USE.         */
13644 /*************************************************************************/
sendStartFragreq(Signal * signal,TabRecordPtr tabPtr,Uint32 fragId)13645 void Dbdih::sendStartFragreq(Signal* signal,
13646 			     TabRecordPtr tabPtr, Uint32 fragId)
13647 {
13648   CreateReplicaRecordPtr replicaPtr;
13649   for (replicaPtr.i = 0; replicaPtr.i < cnoOfCreateReplicas; replicaPtr.i++) {
13650     jam();
13651     ptrAss(replicaPtr, createReplicaRecord);
13652     BlockReference ref = calcLqhBlockRef(replicaPtr.p->dataNodeId);
13653     StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
13654     startFragReq->userPtr = replicaPtr.p->replicaRec;
13655     startFragReq->userRef = reference();
13656     startFragReq->lcpNo = replicaPtr.p->lcpNo;
13657     startFragReq->lcpId = replicaPtr.p->createLcpId;
13658     startFragReq->tableId = tabPtr.i;
13659     startFragReq->fragId = fragId;
13660 
13661     if(ERROR_INSERTED(7072) || ERROR_INSERTED(7074)){
13662       jam();
13663       const Uint32 noNodes = replicaPtr.p->noLogNodes;
13664       Uint32 start = replicaPtr.p->logStartGci[noNodes - 1];
13665       const Uint32 stop  = replicaPtr.p->logStopGci[noNodes - 1];
13666 
13667       for(Uint32 i = noNodes; i < 4 && (stop - start) > 0; i++){
13668 	replicaPtr.p->noLogNodes++;
13669 	replicaPtr.p->logStopGci[i - 1] = start;
13670 
13671 	replicaPtr.p->logNodeId[i] = replicaPtr.p->logNodeId[i-1];
13672 	replicaPtr.p->logStartGci[i] = start + 1;
13673 	replicaPtr.p->logStopGci[i] = stop;
13674 	start += 1;
13675       }
13676     }
13677 
13678     startFragReq->noOfLogNodes = replicaPtr.p->noLogNodes;
13679 
13680     for (Uint32 i = 0; i < 4 ; i++) {
13681       startFragReq->lqhLogNode[i] = replicaPtr.p->logNodeId[i];
13682       startFragReq->startGci[i] = replicaPtr.p->logStartGci[i];
13683       startFragReq->lastGci[i] = replicaPtr.p->logStopGci[i];
13684     }//for
13685 
13686     sendSignal(ref, GSN_START_FRAGREQ, signal,
13687 	       StartFragReq::SignalLength, JBB);
13688   }//for
13689 }//Dbdih::sendStartFragreq()
13690 
13691 /*************************************************************************/
13692 /*       SET THE INITIAL ACTIVE STATUS ON ALL NODES AND PUT INTO LISTS.  */
13693 /*************************************************************************/
setInitialActiveStatus()13694 void Dbdih::setInitialActiveStatus()
13695 {
13696   NodeRecordPtr siaNodeptr;
13697   Uint32 tsiaNoActiveNodes;
13698 
13699   tsiaNoActiveNodes = csystemnodes - cnoHotSpare;
13700   for(Uint32 i = 0; i<Sysfile::NODE_STATUS_SIZE; i++)
13701     SYSFILE->nodeStatus[i] = 0;
13702   for (siaNodeptr.i = 1; siaNodeptr.i < MAX_NDB_NODES; siaNodeptr.i++) {
13703     ptrAss(siaNodeptr, nodeRecord);
13704     switch(siaNodeptr.p->nodeStatus){
13705     case NodeRecord::ALIVE:
13706     case NodeRecord::DEAD:
13707       if (tsiaNoActiveNodes == 0) {
13708         jam();
13709         siaNodeptr.p->activeStatus = Sysfile::NS_HotSpare;
13710       } else {
13711         jam();
13712         tsiaNoActiveNodes = tsiaNoActiveNodes - 1;
13713         if (siaNodeptr.p->nodeStatus == NodeRecord::ALIVE)
13714 	{
13715 	  jam();
13716 	  siaNodeptr.p->activeStatus = Sysfile::NS_Active;
13717 	}
13718 	else
13719 	{
13720 	  siaNodeptr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
13721 	}
13722       }
13723       break;
13724     default:
13725       jam();
13726       siaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
13727       break;
13728     }//if
13729     Sysfile::setNodeStatus(siaNodeptr.i,
13730 			   SYSFILE->nodeStatus,
13731                            siaNodeptr.p->activeStatus);
13732   }//for
13733 }//Dbdih::setInitialActiveStatus()
13734 
13735 /*************************************************************************/
13736 /*       SET LCP ACTIVE STATUS AT THE END OF A LOCAL CHECKPOINT.        */
13737 /*************************************************************************/
setLcpActiveStatusEnd()13738 void Dbdih::setLcpActiveStatusEnd()
13739 {
13740   NodeRecordPtr nodePtr;
13741 
13742   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
13743     jam();
13744     ptrAss(nodePtr, nodeRecord);
13745     if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
13746       switch (nodePtr.p->activeStatus) {
13747       case Sysfile::NS_Active:
13748       case Sysfile::NS_ActiveMissed_1:
13749       case Sysfile::NS_ActiveMissed_2:
13750         jam();
13751 	/*-------------------------------------------------------------------*/
13752 	/* THE NODE PARTICIPATED IN THIS CHECKPOINT.
13753 	 * WE CAN SET ITS STATUS TO ACTIVE */
13754 	/*-------------------------------------------------------------------*/
13755         nodePtr.p->activeStatus = Sysfile::NS_Active;
13756         takeOverCompleted(nodePtr.i);
13757         break;
13758       case Sysfile::NS_TakeOver:
13759         jam();
13760 	/*-------------------------------------------------------------------*/
13761 	/* THE NODE HAS COMPLETED A CHECKPOINT AFTER TAKE OVER. WE CAN NOW   */
13762 	/* SET ITS STATUS TO ACTIVE. WE CAN ALSO COMPLETE THE TAKE OVER      */
13763 	/* AND ALSO WE CLEAR THE TAKE OVER NODE IN THE RESTART INFO.         */
13764 	/*-------------------------------------------------------------------*/
13765         nodePtr.p->activeStatus = Sysfile::NS_Active;
13766         takeOverCompleted(nodePtr.i);
13767         break;
13768       default:
13769         ndbrequire(false);
13770         return;
13771         break;
13772       }//switch
13773     }//if
13774   }//for
13775 
13776   if(getNodeState().getNodeRestartInProgress()){
13777     jam();
13778     if(c_lcpState.m_participatingLQH.get(getOwnNodeId())){
13779       nodePtr.i = getOwnNodeId();
13780       ptrAss(nodePtr, nodeRecord);
13781       ndbrequire(nodePtr.p->activeStatus == Sysfile::NS_Active);
13782       g_eventLogger.info("NR: setLcpActiveStatusEnd - m_participatingLQH");
13783     } else {
13784       g_eventLogger.info("NR: setLcpActiveStatusEnd - !m_participatingLQH");
13785     }
13786   }
13787 
13788   c_lcpState.m_participatingDIH.clear();
13789   c_lcpState.m_participatingLQH.clear();
13790   if (isMaster()) {
13791     jam();
13792     setNodeRestartInfoBits();
13793   }//if
13794 }//Dbdih::setLcpActiveStatusEnd()
13795 
takeOverCompleted(Uint32 aNodeId)13796 void Dbdih::takeOverCompleted(Uint32 aNodeId)
13797 {
13798   TakeOverRecordPtr takeOverPtr;
13799   takeOverPtr.i = findTakeOver(aNodeId);
13800   if (takeOverPtr.i != RNIL) {
13801     jam();
13802     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
13803     if (takeOverPtr.p->toMasterStatus != TakeOverRecord::WAIT_LCP) {
13804       jam();
13805       ndbrequire(!isMaster());
13806       return;
13807     }//if
13808     ndbrequire(isMaster());
13809     Sysfile::setTakeOverNode(aNodeId, SYSFILE->takeOver, 0);
13810     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_END_COPY;
13811     cstartGcpNow = true;
13812   }//if
13813 }//Dbdih::takeOverCompleted()
13814 
13815 /*************************************************************************/
13816 /*       SET LCP ACTIVE STATUS BEFORE STARTING A LOCAL CHECKPOINT.       */
13817 /*************************************************************************/
setLcpActiveStatusStart(Signal * signal)13818 void Dbdih::setLcpActiveStatusStart(Signal* signal)
13819 {
13820   NodeRecordPtr nodePtr;
13821 
13822   c_lcpState.m_participatingLQH.clear();
13823   c_lcpState.m_participatingDIH.clear();
13824 
13825   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
13826     ptrAss(nodePtr, nodeRecord);
13827 #if 0
13828     if(nodePtr.p->nodeStatus != NodeRecord::NOT_IN_CLUSTER){
13829       infoEvent("Node %d nodeStatus=%d activeStatus=%d copyCompleted=%d lcp=%d",
13830 		nodePtr.i,
13831 		nodePtr.p->nodeStatus,
13832 		nodePtr.p->activeStatus,
13833 		nodePtr.p->copyCompleted,
13834 		nodePtr.p->m_inclDihLcp);
13835     }
13836 #endif
13837     if(nodePtr.p->nodeStatus == NodeRecord::ALIVE && nodePtr.p->m_inclDihLcp){
13838       jam();
13839       c_lcpState.m_participatingDIH.set(nodePtr.i);
13840     }
13841 
13842     if ((nodePtr.p->nodeStatus == NodeRecord::ALIVE) &&
13843 	(nodePtr.p->copyCompleted)) {
13844       switch (nodePtr.p->activeStatus) {
13845       case Sysfile::NS_Active:
13846         jam();
13847 	/*-------------------------------------------------------------------*/
13848 	// The normal case. Starting a LCP for a started node which hasn't
13849 	// missed the previous LCP.
13850 	/*-------------------------------------------------------------------*/
13851 	c_lcpState.m_participatingLQH.set(nodePtr.i);
13852         break;
13853       case Sysfile::NS_ActiveMissed_1:
13854         jam();
13855 	/*-------------------------------------------------------------------*/
13856 	// The node is starting up and is participating in a local checkpoint
13857 	// as the final phase of the start-up. We can still use the checkpoints
13858 	// on the node after a system restart.
13859 	/*-------------------------------------------------------------------*/
13860 	c_lcpState.m_participatingLQH.set(nodePtr.i);
13861         break;
13862       case Sysfile::NS_ActiveMissed_2:
13863         jam();
13864 	/*-------------------------------------------------------------------*/
13865 	// The node is starting up and is participating in a local checkpoint
13866 	// as the final phase of the start-up. We have missed so
13867 	// many checkpoints that we no longer can use this node to
13868 	// recreate fragments from disk.
13869 	// It must be taken over with the copy fragment process after a system
13870 	// crash. We indicate this by setting the active status to TAKE_OVER.
13871 	/*-------------------------------------------------------------------*/
13872 	c_lcpState.m_participatingLQH.set(nodePtr.i);
13873         nodePtr.p->activeStatus = Sysfile::NS_TakeOver;
13874         //break; // Fall through
13875       case Sysfile::NS_TakeOver:{
13876         TakeOverRecordPtr takeOverPtr;
13877         jam();
13878 	/*-------------------------------------------------------------------*/
13879 	/*      THIS NODE IS CURRENTLY TAKING OVER A FAILED NODE.            */
13880 	/*-------------------------------------------------------------------*/
13881         takeOverPtr.i = findTakeOver(nodePtr.i);
13882         if (takeOverPtr.i != RNIL) {
13883           jam();
13884           ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
13885           if (takeOverPtr.p->toMasterStatus == TakeOverRecord::WAIT_LCP) {
13886             jam();
13887 	    /*---------------------------------------------------------------
13888 	     * ALL THE INFORMATION HAVE BEEN REPLICATED TO THE NEW
13889 	     * NODE AND WE ARE ONLY WAITING FOR A LOCAL CHECKPOINT TO BE
13890 	     * PERFORMED ON THE NODE TO SET ITS STATUS TO ACTIVE.
13891 	     */
13892 	    infoEvent("Node %d is WAIT_LCP including in LCP", nodePtr.i);
13893 	    c_lcpState.m_participatingLQH.set(nodePtr.i);
13894           }//if
13895         }//if
13896         break;
13897       }
13898       default:
13899         jam();
13900         /*empty*/;
13901         break;
13902       }//switch
13903     } else {
13904       switch (nodePtr.p->activeStatus) {
13905       case Sysfile::NS_Active:
13906         jam();
13907         nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
13908         break;
13909       case Sysfile::NS_ActiveMissed_1:
13910         jam();
13911         nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
13912         break;
13913       case Sysfile::NS_ActiveMissed_2:
13914         jam();
13915         CRASH_INSERTION(7192);
13916         if ((nodePtr.p->nodeStatus == NodeRecord::ALIVE) &&
13917             (!nodePtr.p->copyCompleted)) {
13918           jam();
13919 	  /*-----------------------------------------------------------------*/
13920 	  // The node is currently starting up and has not completed the
13921 	  // copy phase.
13922 	  // It will thus be in the TAKE_OVER state.
13923 	  /*-----------------------------------------------------------------*/
13924           ndbrequire(findTakeOver(nodePtr.i) != RNIL);
13925           nodePtr.p->activeStatus = Sysfile::NS_TakeOver;
13926         } else {
13927           jam();
13928 	  /*-----------------------------------------------------------------*/
13929 	  /* THE NODE IS ACTIVE AND HAS NOT COMPLETED ANY OF THE LAST 3
13930 	   * CHECKPOINTS */
13931 	  /* WE MUST TAKE IT OUT OF ACTION AND START A NEW NODE TO TAKE OVER.*/
13932 	  /*-----------------------------------------------------------------*/
13933           nodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
13934         }//if
13935         break;
13936       case Sysfile::NS_TakeOver:
13937 	jam();
13938 	break;
13939       default:
13940         jam();
13941         /*empty*/;
13942         break;
13943       }//switch
13944     }//if
13945   }//for
13946   if (isMaster()) {
13947     jam();
13948     checkStartTakeOver(signal);
13949     setNodeRestartInfoBits();
13950   }//if
13951 }//Dbdih::setLcpActiveStatusStart()
13952 
13953 /*************************************************************************/
13954 /* SET NODE ACTIVE STATUS AT SYSTEM RESTART AND WHEN UPDATED BY MASTER   */
13955 /*************************************************************************/
setNodeActiveStatus()13956 void Dbdih::setNodeActiveStatus()
13957 {
13958   NodeRecordPtr snaNodeptr;
13959 
13960   for (snaNodeptr.i = 1; snaNodeptr.i < MAX_NDB_NODES; snaNodeptr.i++) {
13961     ptrAss(snaNodeptr, nodeRecord);
13962     const Uint32 tsnaNodeBits = Sysfile::getNodeStatus(snaNodeptr.i,
13963                                                        SYSFILE->nodeStatus);
13964     switch (tsnaNodeBits) {
13965     case Sysfile::NS_Active:
13966       jam();
13967       snaNodeptr.p->activeStatus = Sysfile::NS_Active;
13968       break;
13969     case Sysfile::NS_ActiveMissed_1:
13970       jam();
13971       snaNodeptr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
13972       break;
13973     case Sysfile::NS_ActiveMissed_2:
13974       jam();
13975       snaNodeptr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
13976       break;
13977     case Sysfile::NS_TakeOver:
13978       jam();
13979       snaNodeptr.p->activeStatus = Sysfile::NS_TakeOver;
13980       break;
13981     case Sysfile::NS_HotSpare:
13982       jam();
13983       snaNodeptr.p->activeStatus = Sysfile::NS_HotSpare;
13984       break;
13985     case Sysfile::NS_NotActive_NotTakenOver:
13986       jam();
13987       snaNodeptr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
13988       break;
13989     case Sysfile::NS_NotDefined:
13990       jam();
13991       snaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
13992       break;
13993     default:
13994       ndbrequire(false);
13995       break;
13996     }//switch
13997   }//for
13998 }//Dbdih::setNodeActiveStatus()
13999 
14000 /***************************************************************************/
14001 /* SET THE NODE GROUP BASED ON THE RESTART INFORMATION OR AS SET BY MASTER */
14002 /***************************************************************************/
setNodeGroups()14003 void Dbdih::setNodeGroups()
14004 {
14005   NodeGroupRecordPtr NGPtr;
14006   NodeRecordPtr sngNodeptr;
14007   Uint32 Ti;
14008 
14009   for (Ti = 0; Ti < MAX_NDB_NODES; Ti++) {
14010     NGPtr.i = Ti;
14011     ptrAss(NGPtr, nodeGroupRecord);
14012     NGPtr.p->nodeCount = 0;
14013   }//for
14014   for (sngNodeptr.i = 1; sngNodeptr.i < MAX_NDB_NODES; sngNodeptr.i++) {
14015     ptrAss(sngNodeptr, nodeRecord);
14016     Sysfile::ActiveStatus s =
14017       (Sysfile::ActiveStatus)Sysfile::getNodeStatus(sngNodeptr.i,
14018 						    SYSFILE->nodeStatus);
14019     switch (s){
14020     case Sysfile::NS_Active:
14021     case Sysfile::NS_ActiveMissed_1:
14022     case Sysfile::NS_ActiveMissed_2:
14023     case Sysfile::NS_NotActive_NotTakenOver:
14024     case Sysfile::NS_TakeOver:
14025       jam();
14026       sngNodeptr.p->nodeGroup = Sysfile::getNodeGroup(sngNodeptr.i,
14027                                                       SYSFILE->nodeGroups);
14028       NGPtr.i = sngNodeptr.p->nodeGroup;
14029       ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
14030       NGPtr.p->nodesInGroup[NGPtr.p->nodeCount] = sngNodeptr.i;
14031       NGPtr.p->nodeCount++;
14032       break;
14033     case Sysfile::NS_HotSpare:
14034     case Sysfile::NS_NotDefined:
14035       jam();
14036       sngNodeptr.p->nodeGroup = ZNIL;
14037       break;
14038     default:
14039       ndbrequire(false);
14040       return;
14041       break;
14042     }//switch
14043   }//for
14044   cnoOfNodeGroups = 0;
14045   for (Ti = 0; Ti < MAX_NDB_NODES; Ti++) {
14046     jam();
14047     NGPtr.i = Ti;
14048     ptrAss(NGPtr, nodeGroupRecord);
14049     if (NGPtr.p->nodeCount != 0) {
14050       jam();
14051       cnoOfNodeGroups++;
14052     }//if
14053   }//for
14054   cnoHotSpare = csystemnodes - (cnoOfNodeGroups * cnoReplicas);
14055 }//Dbdih::setNodeGroups()
14056 
14057 /*************************************************************************/
14058 /* SET NODE INFORMATION AFTER RECEIVING RESTART INFORMATION FROM MASTER. */
14059 /* WE TAKE THE OPPORTUNITY TO SYNCHRONISE OUR DATA WITH THE MASTER. IT   */
14060 /* IS ONLY THE MASTER THAT WILL ACT ON THIS DATA. WE WILL KEEP THEM      */
14061 /* UPDATED FOR THE CASE WHEN WE HAVE TO BECOME MASTER.                   */
14062 /*************************************************************************/
setNodeInfo(Signal * signal)14063 void Dbdih::setNodeInfo(Signal* signal)
14064 {
14065   setNodeActiveStatus();
14066   setNodeGroups();
14067   sendHOT_SPAREREP(signal);
14068 }//Dbdih::setNodeInfo()
14069 
14070 /*************************************************************************/
14071 // Keep also DBDICT informed about the Hot Spare situation in the cluster.
14072 /*************************************************************************/
sendHOT_SPAREREP(Signal * signal)14073 void Dbdih::sendHOT_SPAREREP(Signal* signal)
14074 {
14075   NodeRecordPtr locNodeptr;
14076   Uint32 Ti = 0;
14077   HotSpareRep * const hotSpare = (HotSpareRep*)&signal->theData[0];
14078   NodeBitmask::clear(hotSpare->theHotSpareNodes);
14079   for (locNodeptr.i = 1; locNodeptr.i < MAX_NDB_NODES; locNodeptr.i++) {
14080     ptrAss(locNodeptr, nodeRecord);
14081     switch (locNodeptr.p->activeStatus) {
14082     case Sysfile::NS_HotSpare:
14083       jam();
14084       NodeBitmask::set(hotSpare->theHotSpareNodes, locNodeptr.i);
14085       Ti++;
14086       break;
14087     default:
14088       jam();
14089       break;
14090     }//switch
14091   }//for
14092   hotSpare->noHotSpareNodes = Ti;
14093   sendSignal(DBDICT_REF, GSN_HOT_SPAREREP,
14094              signal, HotSpareRep::SignalLength, JBB);
14095 }//Dbdih::sendHOT_SPAREREP()
14096 
14097 /*************************************************************************/
14098 /*       SET LCP ACTIVE STATUS FOR ALL NODES BASED ON THE INFORMATION IN */
14099 /*       THE RESTART INFORMATION.                                        */
14100 /*************************************************************************/
14101 #if 0
14102 void Dbdih::setNodeLcpActiveStatus()
14103 {
14104   c_lcpState.m_lcpActiveStatus.clear();
14105   for (Uint32 i = 1; i < MAX_NDB_NODES; i++) {
14106     if (NodeBitmask::get(SYSFILE->lcpActive, i)) {
14107       jam();
14108       c_lcpState.m_lcpActiveStatus.set(i);
14109     }//if
14110   }//for
14111 }//Dbdih::setNodeLcpActiveStatus()
14112 #endif
14113 
14114 /*************************************************************************/
14115 /* SET THE RESTART INFO BITS BASED ON THE NODES ACTIVE STATUS.           */
14116 /*************************************************************************/
setNodeRestartInfoBits()14117 void Dbdih::setNodeRestartInfoBits()
14118 {
14119   NodeRecordPtr nodePtr;
14120   Uint32 tsnrNodeGroup;
14121   Uint32 tsnrNodeActiveStatus;
14122   Uint32 i;
14123   for(i = 1; i < MAX_NDB_NODES; i++){
14124     Sysfile::setNodeStatus(i, SYSFILE->nodeStatus, Sysfile::NS_Active);
14125   }//for
14126   for(i = 1; i < Sysfile::NODE_GROUPS_SIZE; i++){
14127     SYSFILE->nodeGroups[i] = 0;
14128   }//for
14129   NdbNodeBitmask::clear(SYSFILE->lcpActive);
14130 
14131   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
14132     ptrAss(nodePtr, nodeRecord);
14133     switch (nodePtr.p->activeStatus) {
14134     case Sysfile::NS_Active:
14135       jam();
14136       tsnrNodeActiveStatus = Sysfile::NS_Active;
14137       break;
14138     case Sysfile::NS_ActiveMissed_1:
14139       jam();
14140       tsnrNodeActiveStatus = Sysfile::NS_ActiveMissed_1;
14141       break;
14142     case Sysfile::NS_ActiveMissed_2:
14143       jam();
14144       tsnrNodeActiveStatus = Sysfile::NS_ActiveMissed_2;
14145       break;
14146     case Sysfile::NS_HotSpare:
14147       jam();
14148       tsnrNodeActiveStatus = Sysfile::NS_HotSpare;
14149       break;
14150     case Sysfile::NS_TakeOver:
14151       jam();
14152       tsnrNodeActiveStatus = Sysfile::NS_TakeOver;
14153       break;
14154     case Sysfile::NS_NotActive_NotTakenOver:
14155       jam();
14156       tsnrNodeActiveStatus = Sysfile::NS_NotActive_NotTakenOver;
14157       break;
14158     case Sysfile::NS_NotDefined:
14159       jam();
14160       tsnrNodeActiveStatus = Sysfile::NS_NotDefined;
14161       break;
14162     default:
14163       ndbrequire(false);
14164       tsnrNodeActiveStatus = Sysfile::NS_NotDefined; // remove warning
14165       break;
14166     }//switch
14167     Sysfile::setNodeStatus(nodePtr.i, SYSFILE->nodeStatus,
14168                            tsnrNodeActiveStatus);
14169     if (nodePtr.p->nodeGroup == ZNIL) {
14170       jam();
14171       tsnrNodeGroup = NO_NODE_GROUP_ID;
14172     } else {
14173       jam();
14174       tsnrNodeGroup = nodePtr.p->nodeGroup;
14175     }//if
14176     Sysfile::setNodeGroup(nodePtr.i, SYSFILE->nodeGroups, tsnrNodeGroup);
14177     if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
14178       jam();
14179       NodeBitmask::set(SYSFILE->lcpActive, nodePtr.i);
14180     }//if
14181   }//for
14182 }//Dbdih::setNodeRestartInfoBits()
14183 
14184 /*************************************************************************/
14185 /*       START THE GLOBAL CHECKPOINT PROTOCOL IN MASTER AT START-UP      */
14186 /*************************************************************************/
startGcp(Signal * signal)14187 void Dbdih::startGcp(Signal* signal)
14188 {
14189   cgcpStatus = GCP_READY;
14190   coldGcpStatus = cgcpStatus;
14191   coldGcpId = cnewgcp;
14192   cgcpSameCounter = 0;
14193   signal->theData[0] = DihContinueB::ZSTART_GCP;
14194   signal->theData[1] = 0;
14195   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
14196   signal->theData[0] = DihContinueB::ZCHECK_GCP_STOP;
14197   sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
14198 }//Dbdih::startGcp()
14199 
updateNodeInfo(FragmentstorePtr fragPtr)14200 void Dbdih::updateNodeInfo(FragmentstorePtr fragPtr)
14201 {
14202   ReplicaRecordPtr replicatePtr;
14203   Uint32 index = 0;
14204   replicatePtr.i = fragPtr.p->storedReplicas;
14205   do {
14206     jam();
14207     ptrCheckGuard(replicatePtr, creplicaFileSize, replicaRecord);
14208     ndbrequire(index < MAX_REPLICAS);
14209     fragPtr.p->activeNodes[index] = replicatePtr.p->procNode;
14210     index++;
14211     replicatePtr.i = replicatePtr.p->nextReplica;
14212   } while (replicatePtr.i != RNIL);
14213   fragPtr.p->fragReplicas = index;
14214 
14215   /* ----------------------------------------------------------------------- */
14216   // We switch primary to the preferred primary if the preferred primary is
14217   // in the list.
14218   /* ----------------------------------------------------------------------- */
14219   const Uint32 prefPrim = fragPtr.p->preferredPrimary;
14220   for (Uint32 i = 1; i < index; i++) {
14221     jam();
14222     ndbrequire(i < MAX_REPLICAS);
14223     if (fragPtr.p->activeNodes[i] == prefPrim){
14224       jam();
14225       Uint32 switchNode = fragPtr.p->activeNodes[0];
14226       fragPtr.p->activeNodes[0] = prefPrim;
14227       fragPtr.p->activeNodes[i] = switchNode;
14228       break;
14229     }//if
14230   }//for
14231 }//Dbdih::updateNodeInfo()
14232 
writeFragment(RWFragment * wf,FragmentstorePtr fragPtr)14233 void Dbdih::writeFragment(RWFragment* wf, FragmentstorePtr fragPtr)
14234 {
14235   writePageWord(wf, wf->fragId);
14236   writePageWord(wf, fragPtr.p->preferredPrimary);
14237   writePageWord(wf, fragPtr.p->noStoredReplicas);
14238   writePageWord(wf, fragPtr.p->noOldStoredReplicas);
14239   writePageWord(wf, fragPtr.p->distributionKey);
14240   writePageWord(wf, fragPtr.p->m_log_part_id);
14241 }//Dbdih::writeFragment()
14242 
writePageWord(RWFragment * wf,Uint32 dataWord)14243 void Dbdih::writePageWord(RWFragment* wf, Uint32 dataWord)
14244 {
14245   if (wf->wordIndex >= 2048) {
14246     jam();
14247     ndbrequire(wf->wordIndex == 2048);
14248     allocpage(wf->rwfPageptr);
14249     wf->wordIndex = 32;
14250     wf->pageIndex++;
14251     ndbrequire(wf->pageIndex < 8);
14252     wf->rwfTabPtr.p->pageRef[wf->pageIndex] = wf->rwfPageptr.i;
14253     wf->rwfTabPtr.p->noPages++;
14254   }//if
14255   wf->rwfPageptr.p->word[wf->wordIndex] = dataWord;
14256   wf->wordIndex++;
14257 }//Dbdih::writePageWord()
14258 
writeReplicas(RWFragment * wf,Uint32 replicaStartIndex)14259 void Dbdih::writeReplicas(RWFragment* wf, Uint32 replicaStartIndex)
14260 {
14261   ReplicaRecordPtr wfReplicaPtr;
14262   wfReplicaPtr.i = replicaStartIndex;
14263   while (wfReplicaPtr.i != RNIL) {
14264     jam();
14265     ptrCheckGuard(wfReplicaPtr, creplicaFileSize, replicaRecord);
14266     writePageWord(wf, wfReplicaPtr.p->procNode);
14267     writePageWord(wf, wfReplicaPtr.p->initialGci);
14268     writePageWord(wf, wfReplicaPtr.p->noCrashedReplicas);
14269     writePageWord(wf, wfReplicaPtr.p->nextLcp);
14270     Uint32 i;
14271     for (i = 0; i < MAX_LCP_STORED; i++) {
14272       writePageWord(wf, wfReplicaPtr.p->maxGciCompleted[i]);
14273       writePageWord(wf, wfReplicaPtr.p->maxGciStarted[i]);
14274       writePageWord(wf, wfReplicaPtr.p->lcpId[i]);
14275       writePageWord(wf, wfReplicaPtr.p->lcpStatus[i]);
14276     }//if
14277     for (i = 0; i < 8; i++) {
14278       writePageWord(wf, wfReplicaPtr.p->createGci[i]);
14279       writePageWord(wf, wfReplicaPtr.p->replicaLastGci[i]);
14280     }//if
14281 
14282     wfReplicaPtr.i = wfReplicaPtr.p->nextReplica;
14283   }//while
14284 }//Dbdih::writeReplicas()
14285 
writeRestorableGci(Signal * signal,FileRecordPtr filePtr)14286 void Dbdih::writeRestorableGci(Signal* signal, FileRecordPtr filePtr)
14287 {
14288   for (Uint32 i = 0; i < Sysfile::SYSFILE_SIZE32; i++) {
14289     sysfileDataToFile[i] = sysfileData[i];
14290   }//for
14291   signal->theData[0] = filePtr.p->fileRef;
14292   signal->theData[1] = reference();
14293   signal->theData[2] = filePtr.i;
14294   signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
14295   signal->theData[4] = ZVAR_NO_CRESTART_INFO_TO_FILE;
14296   signal->theData[5] = 1; /* AMOUNT OF PAGES */
14297   signal->theData[6] = 0; /* MEMORY PAGE = 0 SINCE COMMON STORED VARIABLE  */
14298   signal->theData[7] = 0;
14299   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
14300 }//Dbdih::writeRestorableGci()
14301 
writeTabfile(Signal * signal,TabRecord * tab,FileRecordPtr filePtr)14302 void Dbdih::writeTabfile(Signal* signal, TabRecord* tab, FileRecordPtr filePtr)
14303 {
14304   signal->theData[0] = filePtr.p->fileRef;
14305   signal->theData[1] = reference();
14306   signal->theData[2] = filePtr.i;
14307   signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
14308   signal->theData[4] = ZVAR_NO_WORD;
14309   signal->theData[5] = tab->noPages;
14310   for (Uint32 i = 0; i < tab->noPages; i++) {
14311     jam();
14312     signal->theData[6 + (2 * i)] = tab->pageRef[i];
14313     signal->theData[7 + (2 * i)] = i;
14314   }//for
14315   Uint32 length = 6 + (2 * tab->noPages);
14316   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, length, JBA);
14317 }//Dbdih::writeTabfile()
14318 
execDEBUG_SIG(Signal * signal)14319 void Dbdih::execDEBUG_SIG(Signal* signal)
14320 {
14321   signal = signal; //Avoid compiler warnings
14322 }//Dbdih::execDEBUG_SIG()
14323 
14324 void
execDUMP_STATE_ORD(Signal * signal)14325 Dbdih::execDUMP_STATE_ORD(Signal* signal)
14326 {
14327   DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
14328   Uint32 arg = dumpState->args[0];
14329   if (arg == DumpStateOrd::DihDumpNodeRestartInfo) {
14330     infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d, c_nodeStartMaster.wait = %d",
14331 	      c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp, c_nodeStartMaster.wait);
14332     infoEvent("cstartGcpNow = %d, cgcpStatus = %d",
14333               cstartGcpNow, cgcpStatus);
14334     infoEvent("cfirstVerifyQueue = %d, cverifyQueueCounter = %d",
14335               cfirstVerifyQueue, cverifyQueueCounter);
14336     infoEvent("cgcpOrderBlocked = %d, cgcpStartCounter = %d",
14337               cgcpOrderBlocked, cgcpStartCounter);
14338   }//if
14339   if (arg == DumpStateOrd::DihDumpNodeStatusInfo) {
14340     NodeRecordPtr localNodePtr;
14341     infoEvent("Printing nodeStatus of all nodes");
14342     for (localNodePtr.i = 1; localNodePtr.i < MAX_NDB_NODES; localNodePtr.i++) {
14343       ptrAss(localNodePtr, nodeRecord);
14344       if (localNodePtr.p->nodeStatus != NodeRecord::NOT_IN_CLUSTER) {
14345         infoEvent("Node = %d has status = %d",
14346 		  localNodePtr.i, localNodePtr.p->nodeStatus);
14347       }//if
14348     }//for
14349   }//if
14350 
14351   if (arg == DumpStateOrd::DihPrintFragmentation){
14352     infoEvent("Printing fragmentation of all tables --");
14353     for(Uint32 i = 0; i<ctabFileSize; i++){
14354       TabRecordPtr tabPtr;
14355       tabPtr.i = i;
14356       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14357 
14358       if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
14359 	continue;
14360 
14361       for(Uint32 j = 0; j < tabPtr.p->totalfragments; j++){
14362 	FragmentstorePtr fragPtr;
14363 	getFragstore(tabPtr.p, j, fragPtr);
14364 
14365 	Uint32 nodeOrder[MAX_REPLICAS];
14366 	const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, nodeOrder);
14367 	char buf[100];
14368 	BaseString::snprintf(buf, sizeof(buf), " Table %d Fragment %d - ", tabPtr.i, j);
14369 	for(Uint32 k = 0; k < noOfReplicas; k++){
14370 	  char tmp[100];
14371 	  BaseString::snprintf(tmp, sizeof(tmp), "%d ", nodeOrder[k]);
14372 	  strcat(buf, tmp);
14373 	}
14374 	infoEvent(buf);
14375       }
14376     }
14377   }
14378 
14379   if (signal->theData[0] == 7000) {
14380     infoEvent("ctimer = %d, cgcpParticipantState = %d, cgcpStatus = %d",
14381               c_lcpState.ctimer, cgcpParticipantState, cgcpStatus);
14382     infoEvent("coldGcpStatus = %d, coldGcpId = %d, cmasterState = %d",
14383               coldGcpStatus, coldGcpId, cmasterState);
14384     infoEvent("cmasterTakeOverNode = %d, ctcCounter = %d",
14385               cmasterTakeOverNode, c_lcpState.ctcCounter);
14386   }//if
14387   if (signal->theData[0] == 7001) {
14388     infoEvent("c_lcpState.keepGci = %d",
14389               c_lcpState.keepGci);
14390     infoEvent("c_lcpState.lcpStatus = %d, clcpStopGcp = %d",
14391               c_lcpState.lcpStatus,
14392 	      c_lcpState.lcpStopGcp);
14393     infoEvent("cgcpStartCounter = %d, cimmediateLcpStart = %d",
14394               cgcpStartCounter, c_lcpState.immediateLcpStart);
14395   }//if
14396   if (signal->theData[0] == 7002) {
14397     infoEvent("cnoOfActiveTables = %d, cgcpDelay = %d",
14398               cnoOfActiveTables, cgcpDelay);
14399     infoEvent("cdictblockref = %d, cfailurenr = %d",
14400               cdictblockref, cfailurenr);
14401     infoEvent("con_lineNodes = %d, reference() = %d, creceivedfrag = %d",
14402               con_lineNodes, reference(), creceivedfrag);
14403   }//if
14404   if (signal->theData[0] == 7003) {
14405     infoEvent("cfirstAliveNode = %d, cgckptflag = %d",
14406               cfirstAliveNode, cgckptflag);
14407     infoEvent("clocallqhblockref = %d, clocaltcblockref = %d, cgcpOrderBlocked = %d",
14408               clocallqhblockref, clocaltcblockref, cgcpOrderBlocked);
14409     infoEvent("cstarttype = %d, csystemnodes = %d, currentgcp = %d",
14410               cstarttype, csystemnodes, currentgcp);
14411   }//if
14412   if (signal->theData[0] == 7004) {
14413     infoEvent("cmasterdihref = %d, cownNodeId = %d, cnewgcp = %d",
14414               cmasterdihref, cownNodeId, cnewgcp);
14415     infoEvent("cndbStartReqBlockref = %d, cremainingfrags = %d",
14416               cndbStartReqBlockref, cremainingfrags);
14417     infoEvent("cntrlblockref = %d, cgcpSameCounter = %d, coldgcp = %d",
14418               cntrlblockref, cgcpSameCounter, coldgcp);
14419   }//if
14420   if (signal->theData[0] == 7005) {
14421     infoEvent("crestartGci = %d",
14422               crestartGci);
14423   }//if
14424   if (signal->theData[0] == 7006) {
14425     infoEvent("clcpDelay = %d, cgcpMasterTakeOverState = %d",
14426               c_lcpState.clcpDelay, cgcpMasterTakeOverState);
14427     infoEvent("cmasterNodeId = %d", cmasterNodeId);
14428     infoEvent("cnoHotSpare = %d, c_nodeStartMaster.startNode = %d, c_nodeStartMaster.wait = %d",
14429               cnoHotSpare, c_nodeStartMaster.startNode, c_nodeStartMaster.wait);
14430   }//if
14431   if (signal->theData[0] == 7007) {
14432     infoEvent("c_nodeStartMaster.failNr = %d", c_nodeStartMaster.failNr);
14433     infoEvent("c_nodeStartMaster.startInfoErrorCode = %d",
14434               c_nodeStartMaster.startInfoErrorCode);
14435     infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d",
14436               c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp);
14437   }//if
14438   if (signal->theData[0] == 7008) {
14439     infoEvent("cfirstDeadNode = %d, cstartPhase = %d, cnoReplicas = %d",
14440               cfirstDeadNode, cstartPhase, cnoReplicas);
14441     infoEvent("cwaitLcpSr = %d",cwaitLcpSr);
14442   }//if
14443   if (signal->theData[0] == 7009) {
14444     infoEvent("ccalcOldestRestorableGci = %d, cnoOfNodeGroups = %d",
14445               c_lcpState.oldestRestorableGci, cnoOfNodeGroups);
14446     infoEvent("cstartGcpNow = %d",
14447               cstartGcpNow);
14448     infoEvent("crestartGci = %d",
14449               crestartGci);
14450   }//if
14451   if (signal->theData[0] == 7010) {
14452     infoEvent("cminHotSpareNodes = %d, c_lcpState.lcpStatusUpdatedPlace = %d, cLcpStart = %d",
14453               cminHotSpareNodes, c_lcpState.lcpStatusUpdatedPlace, c_lcpState.lcpStart);
14454     infoEvent("c_blockCommit = %d, c_blockCommitNo = %d",
14455               c_blockCommit, c_blockCommitNo);
14456   }//if
14457   if (signal->theData[0] == 7011){
14458     infoEvent("c_COPY_GCIREQ_Counter = %s",
14459 	      c_COPY_GCIREQ_Counter.getText());
14460     infoEvent("c_COPY_TABREQ_Counter = %s",
14461 	      c_COPY_TABREQ_Counter.getText());
14462     infoEvent("c_CREATE_FRAGREQ_Counter = %s",
14463 	      c_CREATE_FRAGREQ_Counter.getText());
14464     infoEvent("c_DIH_SWITCH_REPLICA_REQ_Counter = %s",
14465 	      c_DIH_SWITCH_REPLICA_REQ_Counter.getText());
14466     infoEvent("c_EMPTY_LCP_REQ_Counter = %s",c_EMPTY_LCP_REQ_Counter.getText());
14467     infoEvent("c_END_TOREQ_Counter = %s", c_END_TOREQ_Counter.getText());
14468     infoEvent("c_GCP_COMMIT_Counter = %s", c_GCP_COMMIT_Counter.getText());
14469     infoEvent("c_GCP_PREPARE_Counter = %s", c_GCP_PREPARE_Counter.getText());
14470     infoEvent("c_GCP_SAVEREQ_Counter = %s", c_GCP_SAVEREQ_Counter.getText());
14471     infoEvent("c_INCL_NODEREQ_Counter = %s", c_INCL_NODEREQ_Counter.getText());
14472     infoEvent("c_MASTER_GCPREQ_Counter = %s",
14473 	      c_MASTER_GCPREQ_Counter.getText());
14474     infoEvent("c_MASTER_LCPREQ_Counter = %s",
14475 	      c_MASTER_LCPREQ_Counter.getText());
14476     infoEvent("c_START_INFOREQ_Counter = %s",
14477 	      c_START_INFOREQ_Counter.getText());
14478     infoEvent("c_START_RECREQ_Counter = %s", c_START_RECREQ_Counter.getText());
14479     infoEvent("c_START_TOREQ_Counter = %s", c_START_TOREQ_Counter.getText());
14480     infoEvent("c_STOP_ME_REQ_Counter = %s", c_STOP_ME_REQ_Counter.getText());
14481     infoEvent("c_TC_CLOPSIZEREQ_Counter = %s",
14482 	      c_TC_CLOPSIZEREQ_Counter.getText());
14483     infoEvent("c_TCGETOPSIZEREQ_Counter = %s",
14484 	      c_TCGETOPSIZEREQ_Counter.getText());
14485     infoEvent("c_UPDATE_TOREQ_Counter = %s", c_UPDATE_TOREQ_Counter.getText());
14486   }
14487 
14488   if(signal->theData[0] == 7012){
14489     char buf[8*_NDB_NODE_BITMASK_SIZE+1];
14490     infoEvent("ParticipatingDIH = %s", c_lcpState.m_participatingDIH.getText(buf));
14491     infoEvent("ParticipatingLQH = %s", c_lcpState.m_participatingLQH.getText(buf));
14492     infoEvent("m_LCP_COMPLETE_REP_Counter_DIH = %s",
14493 	      c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.getText());
14494     infoEvent("m_LCP_COMPLETE_REP_Counter_LQH = %s",
14495 	      c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.getText());
14496     infoEvent("m_LAST_LCP_FRAG_ORD = %s",
14497 	      c_lcpState.m_LAST_LCP_FRAG_ORD.getText());
14498     infoEvent("m_LCP_COMPLETE_REP_From_Master_Received = %d",
14499 	      c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received);
14500 
14501     NodeRecordPtr nodePtr;
14502     for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
14503       jam();
14504       ptrAss(nodePtr, nodeRecord);
14505       if(nodePtr.p->nodeStatus == NodeRecord::ALIVE){
14506         Uint32 i;
14507 	for(i = 0; i<nodePtr.p->noOfStartedChkpt; i++){
14508 	  infoEvent("Node %d: started: table=%d fragment=%d replica=%d",
14509 		    nodePtr.i,
14510 		    nodePtr.p->startedChkpt[i].tableId,
14511 		    nodePtr.p->startedChkpt[i].fragId,
14512 		    nodePtr.p->startedChkpt[i].replicaPtr);
14513 	}
14514 
14515 	for(i = 0; i<nodePtr.p->noOfQueuedChkpt; i++){
14516 	  infoEvent("Node %d: queued: table=%d fragment=%d replica=%d",
14517 		    nodePtr.i,
14518 		    nodePtr.p->queuedChkpt[i].tableId,
14519 		    nodePtr.p->queuedChkpt[i].fragId,
14520 		    nodePtr.p->queuedChkpt[i].replicaPtr);
14521 	}
14522       }
14523     }
14524   }
14525 
14526   if(arg == 7019 && signal->getLength() == 2)
14527   {
14528     char buf2[8+1];
14529     NodeRecordPtr nodePtr;
14530     nodePtr.i = signal->theData[1];
14531     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
14532     infoEvent("NF Node %d tc: %d lqh: %d dih: %d dict: %d recNODE_FAILREP: %d",
14533 	      nodePtr.i,
14534 	      nodePtr.p->dbtcFailCompleted,
14535 	      nodePtr.p->dblqhFailCompleted,
14536 	      nodePtr.p->dbdihFailCompleted,
14537 	      nodePtr.p->dbdictFailCompleted,
14538 	      nodePtr.p->recNODE_FAILREP);
14539     infoEvent(" m_NF_COMPLETE_REP: %s m_nodefailSteps: %s",
14540 	      nodePtr.p->m_NF_COMPLETE_REP.getText(),
14541 	      nodePtr.p->m_nodefailSteps.getText(buf2));
14542   }
14543 
14544   if(arg == 7020 && signal->getLength() > 3)
14545   {
14546     Uint32 gsn= signal->theData[1];
14547     Uint32 block= signal->theData[2];
14548     Uint32 length= signal->length() - 3;
14549     memmove(signal->theData, signal->theData+3, 4*length);
14550     sendSignal(numberToRef(block, getOwnNodeId()), gsn, signal, length, JBB);
14551 
14552     warningEvent("-- SENDING CUSTOM SIGNAL --");
14553     char buf[100], buf2[100];
14554     buf2[0]= 0;
14555     for(Uint32 i = 0; i<length; i++)
14556     {
14557       snprintf(buf, 100, "%s %.8x", buf2, signal->theData[i]);
14558       snprintf(buf2, 100, "%s", buf);
14559     }
14560     warningEvent("gsn: %d block: %s, length: %d theData: %s",
14561 		 gsn, getBlockName(block, "UNKNOWN"), length, buf);
14562 
14563     g_eventLogger.warning("-- SENDING CUSTOM SIGNAL --");
14564     g_eventLogger.warning("gsn: %d block: %s, length: %d theData: %s",
14565 			  gsn, getBlockName(block, "UNKNOWN"), length, buf);
14566   }
14567 
14568   if(arg == DumpStateOrd::DihDumpLCPState){
14569     infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
14570     infoEvent("lcpStatus = %d (update place = %d) ",
14571 	      c_lcpState.lcpStatus, c_lcpState.lcpStatusUpdatedPlace);
14572     infoEvent
14573       ("lcpStart = %d lcpStopGcp = %d keepGci = %d oldestRestorable = %d",
14574        c_lcpState.lcpStart, c_lcpState.lcpStopGcp,
14575        c_lcpState.keepGci, c_lcpState.oldestRestorableGci);
14576 
14577     infoEvent
14578       ("immediateLcpStart = %d masterLcpNodeId = %d",
14579        c_lcpState.immediateLcpStart,
14580        refToNode(c_lcpState.m_masterLcpDihRef));
14581 
14582     for (Uint32 i = 0; i<10; i++)
14583     {
14584       infoEvent("%u : status: %u place: %u", i,
14585                 c_lcpState.m_saveState[i].m_status,
14586                 c_lcpState.m_saveState[i].m_place);
14587     }
14588 
14589     infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
14590   }
14591 
14592   if(arg == DumpStateOrd::DihDumpLCPMasterTakeOver){
14593     infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
14594     infoEvent
14595       ("c_lcpMasterTakeOverState.state = %d updatePlace = %d failedNodeId = %d",
14596        c_lcpMasterTakeOverState.state,
14597        c_lcpMasterTakeOverState.updatePlace,
14598        c_lcpMasterTakeOverState.failedNodeId);
14599 
14600     infoEvent("c_lcpMasterTakeOverState.minTableId = %u minFragId = %u",
14601 	      c_lcpMasterTakeOverState.minTableId,
14602 	      c_lcpMasterTakeOverState.minFragId);
14603 
14604     infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
14605   }
14606 
14607   if (signal->theData[0] == 7015)
14608   {
14609     if (signal->getLength() == 1)
14610     {
14611       signal->theData[1] = 0;
14612     }
14613 
14614     Uint32 tableId = signal->theData[1];
14615     if (tableId < ctabFileSize)
14616     {
14617       signal->theData[0] = 7021;
14618       execDUMP_STATE_ORD(signal);
14619       signal->theData[0] = 7015;
14620       signal->theData[1] = tableId + 1;
14621       sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
14622     }
14623   }
14624 
14625   if(arg == DumpStateOrd::EnableUndoDelayDataWrite){
14626     g_eventLogger.info("Dbdih:: delay write of datapages for table = %d",
14627                        dumpState->args[1]);
14628     // Send this dump to ACC and TUP
14629     EXECUTE_DIRECT(DBACC, GSN_DUMP_STATE_ORD, signal, 2);
14630     EXECUTE_DIRECT(DBTUP, GSN_DUMP_STATE_ORD, signal, 2);
14631 
14632     // Start immediate LCP
14633     c_lcpState.ctimer += (1 << c_lcpState.clcpDelay);
14634     return;
14635   }
14636 
14637   if (signal->theData[0] == DumpStateOrd::DihAllAllowNodeStart) {
14638     for (Uint32 i = 1; i < MAX_NDB_NODES; i++)
14639       setAllowNodeStart(i, true);
14640     return;
14641   }//if
14642   if (signal->theData[0] == DumpStateOrd::DihMinTimeBetweenLCP) {
14643     // Set time between LCP to min value
14644     g_eventLogger.info("Set time between LCP to min value");
14645     c_lcpState.clcpDelay = 0; // TimeBetweenLocalCheckpoints.min
14646     return;
14647   }
14648   if (signal->theData[0] == DumpStateOrd::DihMaxTimeBetweenLCP) {
14649     // Set time between LCP to max value
14650     g_eventLogger.info("Set time between LCP to max value");
14651     c_lcpState.clcpDelay = 31; // TimeBetweenLocalCheckpoints.max
14652     return;
14653   }
14654 
14655   if(arg == 7098){
14656     if(signal->length() == 3){
14657       jam();
14658       infoEvent("startLcpRoundLoopLab(tabel=%d, fragment=%d)",
14659 		signal->theData[1], signal->theData[2]);
14660       startLcpRoundLoopLab(signal, signal->theData[1], signal->theData[2]);
14661       return;
14662     } else {
14663       infoEvent("Invalid no of arguments to 7098 - startLcpRoundLoopLab -"
14664 		" expected 2 (tableId, fragmentId)");
14665     }
14666   }
14667 
14668   if(arg == DumpStateOrd::DihStartLcpImmediately){
14669     c_lcpState.ctimer += (1 << c_lcpState.clcpDelay);
14670     return;
14671   }
14672 
14673   if (arg == DumpStateOrd::DihSetTimeBetweenGcp)
14674   {
14675     if (signal->getLength() == 1)
14676     {
14677       const ndb_mgm_configuration_iterator * p =
14678 	m_ctx.m_config.getOwnConfigIterator();
14679       ndbrequire(p != 0);
14680       ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay);
14681     }
14682     else
14683     {
14684       cgcpDelay = signal->theData[1];
14685     }
14686     g_eventLogger.info("Setting time between gcp : %d", cgcpDelay);
14687   }
14688 
14689   if (arg == 7021 && signal->getLength() == 2)
14690   {
14691     TabRecordPtr tabPtr;
14692     tabPtr.i = signal->theData[1];
14693     if (tabPtr.i >= ctabFileSize)
14694       return;
14695 
14696     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14697 
14698     if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
14699       return;
14700 
14701     infoEvent
14702       ("Table %d: TabCopyStatus: %d TabUpdateStatus: %d TabLcpStatus: %d",
14703        tabPtr.i,
14704        tabPtr.p->tabCopyStatus,
14705        tabPtr.p->tabUpdateState,
14706        tabPtr.p->tabLcpStatus);
14707 
14708     FragmentstorePtr fragPtr;
14709     for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
14710       jam();
14711       getFragstore(tabPtr.p, fid, fragPtr);
14712 
14713       char buf[100], buf2[100];
14714       BaseString::snprintf(buf, sizeof(buf), " Fragment %d: noLcpReplicas==%d ",
14715 			   fid, fragPtr.p->noLcpReplicas);
14716 
14717       Uint32 num=0;
14718       ReplicaRecordPtr replicaPtr;
14719       replicaPtr.i = fragPtr.p->storedReplicas;
14720       do {
14721 	ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
14722 	BaseString::snprintf(buf2, sizeof(buf2), "%s %d(on %d)=%d(%s)",
14723 			     buf, num,
14724 			     replicaPtr.p->procNode,
14725 			     replicaPtr.p->lcpIdStarted,
14726 			     replicaPtr.p->lcpOngoingFlag ? "Ongoing" : "Idle");
14727 	BaseString::snprintf(buf, sizeof(buf), "%s", buf2);
14728 
14729 	num++;
14730 	replicaPtr.i = replicaPtr.p->nextReplica;
14731       } while (replicaPtr.i != RNIL);
14732       infoEvent(buf);
14733     }
14734   }
14735 
14736   if (arg == 7022)
14737   {
14738     jam();
14739     crashSystemAtGcpStop(signal, true);
14740   }
14741 }//Dbdih::execDUMP_STATE_ORD()
14742 
14743 void
execPREP_DROP_TAB_REQ(Signal * signal)14744 Dbdih::execPREP_DROP_TAB_REQ(Signal* signal){
14745   jamEntry();
14746 
14747   PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
14748 
14749   TabRecordPtr tabPtr;
14750   tabPtr.i = req->tableId;
14751   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14752 
14753   Uint32 senderRef = req->senderRef;
14754   Uint32 senderData = req->senderData;
14755 
14756   PrepDropTabRef::ErrorCode err = PrepDropTabRef::OK;
14757   { /**
14758      * Check table state
14759      */
14760     bool ok = false;
14761     switch(tabPtr.p->tabStatus){
14762     case TabRecord::TS_IDLE:
14763       ok = true;
14764       jam();
14765       err = PrepDropTabRef::NoSuchTable;
14766       break;
14767     case TabRecord::TS_DROPPING:
14768       ok = true;
14769       jam();
14770       err = PrepDropTabRef::PrepDropInProgress;
14771       break;
14772     case TabRecord::TS_CREATING:
14773       jam();
14774       ok = true;
14775       break;
14776     case TabRecord::TS_ACTIVE:
14777       ok = true;
14778       jam();
14779       break;
14780     }
14781     ndbrequire(ok);
14782   }
14783 
14784   if(err != PrepDropTabRef::OK){
14785     jam();
14786     PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
14787     ref->senderRef = reference();
14788     ref->senderData = senderData;
14789     ref->tableId = tabPtr.i;
14790     ref->errorCode = err;
14791     sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
14792 	       PrepDropTabRef::SignalLength, JBB);
14793     return;
14794   }
14795 
14796   tabPtr.p->tabStatus = TabRecord::TS_DROPPING;
14797   tabPtr.p->m_prepDropTab.senderRef = senderRef;
14798   tabPtr.p->m_prepDropTab.senderData = senderData;
14799 
14800   if(isMaster()){
14801     /**
14802      * Remove from queue
14803      */
14804     NodeRecordPtr nodePtr;
14805     for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
14806       jam();
14807       ptrAss(nodePtr, nodeRecord);
14808       if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
14809 
14810 	Uint32 index = 0;
14811 	Uint32 count = nodePtr.p->noOfQueuedChkpt;
14812 	while(index < count){
14813 	  if(nodePtr.p->queuedChkpt[index].tableId == tabPtr.i){
14814 	    jam();
14815 	    //	    g_eventLogger.info("Unqueuing %d", index);
14816 
14817 	    count--;
14818 	    for(Uint32 i = index; i<count; i++){
14819 	      jam();
14820 	      nodePtr.p->queuedChkpt[i] = nodePtr.p->queuedChkpt[i + 1];
14821 	    }
14822 	  } else {
14823 	    index++;
14824 	  }
14825 	}
14826 	nodePtr.p->noOfQueuedChkpt = count;
14827       }
14828     }
14829   }
14830 
14831   { /**
14832      * Check table lcp state
14833      */
14834 
14835     bool ok = false;
14836     switch(tabPtr.p->tabLcpStatus){
14837     case TabRecord::TLS_COMPLETED:
14838     case TabRecord::TLS_WRITING_TO_FILE:
14839       ok = true;
14840       jam();
14841       break;
14842       return;
14843     case TabRecord::TLS_ACTIVE:
14844       ok = true;
14845       jam();
14846 
14847       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
14848 
14849       /**
14850        * First check if all fragments are done
14851        */
14852       if(checkLcpAllTablesDoneInLqh()){
14853 	jam();
14854 
14855 	g_eventLogger.info("This is the last table");
14856 
14857 	/**
14858 	 * Then check if saving of tab info is done for all tables
14859 	 */
14860 	LcpStatus a = c_lcpState.lcpStatus;
14861 	checkLcpCompletedLab(signal);
14862 
14863 	if(a != c_lcpState.lcpStatus){
14864 	  g_eventLogger.info("And all tables are written to already written disk");
14865 	}
14866       }
14867       break;
14868     }
14869     ndbrequire(ok);
14870   }
14871 
14872   { /**
14873      * Send WaitDropTabReq to all LQH
14874      */
14875     WaitDropTabReq * req = (WaitDropTabReq*)signal->getDataPtrSend();
14876     req->tableId = tabPtr.i;
14877     req->senderRef = reference();
14878 
14879     NodeRecordPtr nodePtr;
14880     nodePtr.i = cfirstAliveNode;
14881     tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor();
14882     while(nodePtr.i != RNIL){
14883       jam();
14884       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
14885 
14886       tabPtr.p->m_prepDropTab.waitDropTabCount.setWaitingFor(nodePtr.i);
14887       sendSignal(calcLqhBlockRef(nodePtr.i), GSN_WAIT_DROP_TAB_REQ,
14888 		 signal, WaitDropTabReq::SignalLength, JBB);
14889 
14890       nodePtr.i = nodePtr.p->nextNode;
14891     }
14892   }
14893 
14894   waitDropTabWritingToFile(signal, tabPtr);
14895 }
14896 
14897 void
waitDropTabWritingToFile(Signal * signal,TabRecordPtr tabPtr)14898 Dbdih::waitDropTabWritingToFile(Signal* signal, TabRecordPtr tabPtr){
14899 
14900   if(tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE){
14901     jam();
14902     signal->theData[0] = DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE;
14903     signal->theData[1] = tabPtr.i;
14904     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
14905     return;
14906   }
14907 
14908   ndbrequire(tabPtr.p->tabLcpStatus ==  TabRecord::TLS_COMPLETED);
14909   checkPrepDropTabComplete(signal, tabPtr);
14910 }
14911 
14912 void
checkPrepDropTabComplete(Signal * signal,TabRecordPtr tabPtr)14913 Dbdih::checkPrepDropTabComplete(Signal* signal, TabRecordPtr tabPtr){
14914 
14915   if(tabPtr.p->tabLcpStatus !=  TabRecord::TLS_COMPLETED){
14916     jam();
14917     return;
14918   }
14919 
14920   if(!tabPtr.p->m_prepDropTab.waitDropTabCount.done()){
14921     jam();
14922     return;
14923   }
14924 
14925   const Uint32 ref = tabPtr.p->m_prepDropTab.senderRef;
14926   if(ref != 0){
14927     PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
14928     conf->tableId = tabPtr.i;
14929     conf->senderRef = reference();
14930     conf->senderData = tabPtr.p->m_prepDropTab.senderData;
14931     sendSignal(tabPtr.p->m_prepDropTab.senderRef, GSN_PREP_DROP_TAB_CONF,
14932 	       signal, PrepDropTabConf::SignalLength, JBB);
14933     tabPtr.p->m_prepDropTab.senderRef = 0;
14934   }
14935 }
14936 
14937 void
execWAIT_DROP_TAB_REF(Signal * signal)14938 Dbdih::execWAIT_DROP_TAB_REF(Signal* signal){
14939   jamEntry();
14940   WaitDropTabRef * ref = (WaitDropTabRef*)signal->getDataPtr();
14941 
14942   TabRecordPtr tabPtr;
14943   tabPtr.i = ref->tableId;
14944   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14945 
14946   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
14947   Uint32 nodeId = refToNode(ref->senderRef);
14948 
14949   ndbrequire(ref->errorCode == WaitDropTabRef::NoSuchTable ||
14950 	     ref->errorCode == WaitDropTabRef::NF_FakeErrorREF);
14951 
14952   tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor(nodeId);
14953   checkPrepDropTabComplete(signal, tabPtr);
14954 }
14955 
14956 void
execWAIT_DROP_TAB_CONF(Signal * signal)14957 Dbdih::execWAIT_DROP_TAB_CONF(Signal* signal){
14958   jamEntry();
14959   WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
14960 
14961   TabRecordPtr tabPtr;
14962   tabPtr.i = conf->tableId;
14963   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14964 
14965   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
14966   Uint32 nodeId = refToNode(conf->senderRef);
14967   tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor(nodeId);
14968   checkPrepDropTabComplete(signal, tabPtr);
14969 }
14970 
14971 void
checkWaitDropTabFailedLqh(Signal * signal,Uint32 nodeId,Uint32 tableId)14972 Dbdih::checkWaitDropTabFailedLqh(Signal* signal, Uint32 nodeId, Uint32 tableId){
14973 
14974   TabRecordPtr tabPtr;
14975   tabPtr.i = tableId;
14976 
14977   WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
14978   conf->tableId = tableId;
14979 
14980   const Uint32 RT_BREAK = 16;
14981   for(Uint32 i = 0; i<RT_BREAK && tabPtr.i < ctabFileSize; i++, tabPtr.i++){
14982     ptrAss(tabPtr, tabRecord);
14983     if(tabPtr.p->tabStatus == TabRecord::TS_DROPPING){
14984       if(tabPtr.p->m_prepDropTab.waitDropTabCount.isWaitingFor(nodeId)){
14985 	conf->senderRef = calcLqhBlockRef(nodeId);
14986 	execWAIT_DROP_TAB_CONF(signal);
14987 	tabPtr.i++;
14988 	break;
14989       }
14990     }
14991   }
14992 
14993   if(tabPtr.i == ctabFileSize){
14994     /**
14995      * Finished
14996      */
14997     jam();
14998     return;
14999   }
15000 
15001   signal->theData[0] = DihContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH;
15002   signal->theData[1] = nodeId;
15003   signal->theData[2] = tabPtr.i;
15004   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
15005 }
15006 
15007 
15008 void
execNDB_TAMPER(Signal * signal)15009 Dbdih::execNDB_TAMPER(Signal* signal)
15010 {
15011   if ((ERROR_INSERTED(7011)) &&
15012       (signal->theData[0] == 7012)) {
15013     CLEAR_ERROR_INSERT_VALUE;
15014     calculateKeepGciLab(signal, 0, 0);
15015     return;
15016   }//if
15017   SET_ERROR_INSERT_VALUE(signal->theData[0]);
15018   return;
15019 }//Dbdih::execNDB_TAMPER()
15020 
execBLOCK_COMMIT_ORD(Signal * signal)15021 void Dbdih::execBLOCK_COMMIT_ORD(Signal* signal){
15022   BlockCommitOrd* const block = (BlockCommitOrd *)&signal->theData[0];
15023 
15024   jamEntry();
15025 #if 0
15026   ndbrequire(c_blockCommit == false ||
15027 	     c_blockCommitNo == block->failNo);
15028 #else
15029   if(!(c_blockCommit == false || c_blockCommitNo == block->failNo)){
15030     infoEvent("Possible bug in Dbdih::execBLOCK_COMMIT_ORD c_blockCommit = %d c_blockCommitNo = %d"
15031 	      " sig->failNo = %d", c_blockCommit, c_blockCommitNo, block->failNo);
15032   }
15033 #endif
15034   c_blockCommit = true;
15035   c_blockCommitNo = block->failNo;
15036 }
15037 
execUNBLOCK_COMMIT_ORD(Signal * signal)15038 void Dbdih::execUNBLOCK_COMMIT_ORD(Signal* signal){
15039   UnblockCommitOrd* const unblock = (UnblockCommitOrd *)&signal->theData[0];
15040   (void)unblock;
15041 
15042   jamEntry();
15043 
15044   if(c_blockCommit == true){
15045     jam();
15046     //    ndbrequire(c_blockCommitNo == unblock->failNo);
15047 
15048     c_blockCommit = false;
15049     emptyverificbuffer(signal, true);
15050   }
15051 }
15052 
execSTOP_PERM_REQ(Signal * signal)15053 void Dbdih::execSTOP_PERM_REQ(Signal* signal){
15054 
15055   jamEntry();
15056 
15057   StopPermReq* const req = (StopPermReq*)&signal->theData[0];
15058   StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
15059 
15060   const Uint32 senderData = req->senderData;
15061   const BlockReference senderRef = req->senderRef;
15062   const NodeId nodeId = refToNode(senderRef);
15063 
15064   if (isMaster()) {
15065     /**
15066      * Master
15067      */
15068     jam();
15069     CRASH_INSERTION(7065);
15070     if (c_stopPermMaster.clientRef != 0) {
15071       jam();
15072 
15073       ref->senderData = senderData;
15074       ref->errorCode  = StopPermRef::NodeShutdownInProgress;
15075       sendSignal(senderRef, GSN_STOP_PERM_REF, signal,
15076                  StopPermRef::SignalLength, JBB);
15077       return;
15078     }//if
15079 
15080     if (c_nodeStartMaster.activeState) {
15081       jam();
15082       ref->senderData = senderData;
15083       ref->errorCode  = StopPermRef::NodeStartInProgress;
15084       sendSignal(senderRef, GSN_STOP_PERM_REF, signal,
15085                  StopPermRef::SignalLength, JBB);
15086       return;
15087     }//if
15088 
15089     /**
15090      * Lock
15091      */
15092     c_nodeStartMaster.activeState = true;
15093     c_stopPermMaster.clientRef = senderRef;
15094 
15095     c_stopPermMaster.clientData = senderData;
15096     c_stopPermMaster.returnValue = 0;
15097     c_switchReplicas.clear();
15098 
15099     Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
15100     Callback c = { safe_cast(&Dbdih::switch_primary_stop_node), nodeId };
15101     ndbrequire(mutex.lock(c));
15102   } else {
15103     /**
15104      * Proxy part
15105      */
15106     jam();
15107     CRASH_INSERTION(7066);
15108     if(c_stopPermProxy.clientRef != 0){
15109       jam();
15110       ref->senderData = senderData;
15111       ref->errorCode = StopPermRef::NodeShutdownInProgress;
15112       sendSignal(senderRef, GSN_STOP_PERM_REF, signal, 2, JBB);
15113       return;
15114     }//if
15115 
15116     c_stopPermProxy.clientRef = senderRef;
15117     c_stopPermProxy.masterRef = cmasterdihref;
15118     c_stopPermProxy.clientData = senderData;
15119 
15120     req->senderRef = reference();
15121     req->senderData = senderData;
15122     sendSignal(cmasterdihref, GSN_STOP_PERM_REQ, signal,
15123 	       StopPermReq::SignalLength, JBB);
15124   }//if
15125 }//Dbdih::execSTOP_PERM_REQ()
15126 
15127 void
switch_primary_stop_node(Signal * signal,Uint32 node_id,Uint32 ret_val)15128 Dbdih::switch_primary_stop_node(Signal* signal, Uint32 node_id, Uint32 ret_val)
15129 {
15130   ndbrequire(ret_val == 0);
15131   signal->theData[0] = DihContinueB::SwitchReplica;
15132   signal->theData[1] = node_id;
15133   signal->theData[2] = 0; // table id
15134   signal->theData[3] = 0; // fragment id
15135   sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
15136 }
15137 
execSTOP_PERM_REF(Signal * signal)15138 void Dbdih::execSTOP_PERM_REF(Signal* signal)
15139 {
15140   jamEntry();
15141   ndbrequire(c_stopPermProxy.clientRef != 0);
15142   ndbrequire(c_stopPermProxy.masterRef == signal->senderBlockRef());
15143   sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_REF, signal, 2, JBB);
15144   c_stopPermProxy.clientRef = 0;
15145 }//Dbdih::execSTOP_PERM_REF()
15146 
execSTOP_PERM_CONF(Signal * signal)15147 void Dbdih::execSTOP_PERM_CONF(Signal* signal)
15148 {
15149   jamEntry();
15150   ndbrequire(c_stopPermProxy.clientRef != 0);
15151   ndbrequire(c_stopPermProxy.masterRef == signal->senderBlockRef());
15152   sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_CONF, signal, 1, JBB);
15153   c_stopPermProxy.clientRef = 0;
15154 }//Dbdih::execSTOP_PERM_CONF()
15155 
execDIH_SWITCH_REPLICA_REQ(Signal * signal)15156 void Dbdih::execDIH_SWITCH_REPLICA_REQ(Signal* signal)
15157 {
15158   jamEntry();
15159   DihSwitchReplicaReq* const req = (DihSwitchReplicaReq*)&signal->theData[0];
15160   const Uint32 tableId = req->tableId;
15161   const Uint32 fragNo = req->fragNo;
15162   const BlockReference senderRef = req->senderRef;
15163 
15164   CRASH_INSERTION(7067);
15165   TabRecordPtr tabPtr;
15166   tabPtr.i = tableId;
15167   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
15168 
15169   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
15170   if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
15171     jam();
15172     sendSignal(reference(), GSN_DIH_SWITCH_REPLICA_REQ, signal,
15173 	       DihSwitchReplicaReq::SignalLength, JBB);
15174     return;
15175   }//if
15176   FragmentstorePtr fragPtr;
15177   getFragstore(tabPtr.p, fragNo, fragPtr);
15178 
15179   /**
15180    * Do funky stuff
15181    */
15182   Uint32 oldOrder[MAX_REPLICAS];
15183   const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, oldOrder);
15184 
15185   if (noOfReplicas < req->noOfReplicas) {
15186     jam();
15187     //---------------------------------------------------------------------
15188     // A crash occurred in the middle of our switch handling.
15189     //---------------------------------------------------------------------
15190     DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
15191     ref->senderNode = cownNodeId;
15192     ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
15193     sendSignal(senderRef, GSN_DIH_SWITCH_REPLICA_REF, signal,
15194                DihSwitchReplicaRef::SignalLength, JBB);
15195   }//if
15196   for (Uint32 i = 0; i < noOfReplicas; i++) {
15197     jam();
15198     ndbrequire(i < MAX_REPLICAS);
15199     fragPtr.p->activeNodes[i] = req->newNodeOrder[i];
15200   }//for
15201   /**
15202    * Reply
15203    */
15204   DihSwitchReplicaConf* const conf = (DihSwitchReplicaConf*)&signal->theData[0];
15205   conf->senderNode = cownNodeId;
15206   sendSignal(senderRef, GSN_DIH_SWITCH_REPLICA_CONF, signal,
15207              DihSwitchReplicaConf::SignalLength, JBB);
15208 }//Dbdih::execDIH_SWITCH_REPLICA_REQ()
15209 
execDIH_SWITCH_REPLICA_CONF(Signal * signal)15210 void Dbdih::execDIH_SWITCH_REPLICA_CONF(Signal* signal)
15211 {
15212   jamEntry();
15213   /**
15214    * Response to master
15215    */
15216   CRASH_INSERTION(7068);
15217   DihSwitchReplicaConf* const conf = (DihSwitchReplicaConf*)&signal->theData[0];
15218   switchReplicaReply(signal, conf->senderNode);
15219 }//Dbdih::execDIH_SWITCH_REPLICA_CONF()
15220 
execDIH_SWITCH_REPLICA_REF(Signal * signal)15221 void Dbdih::execDIH_SWITCH_REPLICA_REF(Signal* signal)
15222 {
15223   jamEntry();
15224   DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
15225   if(c_stopPermMaster.returnValue == 0){
15226     jam();
15227     c_stopPermMaster.returnValue = ref->errorCode;
15228   }//if
15229   switchReplicaReply(signal, ref->senderNode);
15230 }//Dbdih::execDIH_SWITCH_REPLICA_REF()
15231 
switchReplicaReply(Signal * signal,NodeId nodeId)15232 void Dbdih::switchReplicaReply(Signal* signal,
15233 			       NodeId nodeId){
15234   jam();
15235   receiveLoopMacro(DIH_SWITCH_REPLICA_REQ, nodeId);
15236   //------------------------------------------------------
15237   // We have received all responses from the nodes. Thus
15238   // we have completed switching replica roles. Continue
15239   // with the next fragment.
15240   //------------------------------------------------------
15241   if(c_stopPermMaster.returnValue != 0){
15242     jam();
15243     c_switchReplicas.tableId = ctabFileSize + 1;
15244   }//if
15245   c_switchReplicas.fragNo++;
15246 
15247   signal->theData[0] = DihContinueB::SwitchReplica;
15248   signal->theData[1] = c_switchReplicas.nodeId;
15249   signal->theData[2] = c_switchReplicas.tableId;
15250   signal->theData[3] = c_switchReplicas.fragNo;
15251   sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
15252 }//Dbdih::switchReplicaReply()
15253 
15254 void
switchReplica(Signal * signal,Uint32 nodeId,Uint32 tableId,Uint32 fragNo)15255 Dbdih::switchReplica(Signal* signal,
15256 		     Uint32 nodeId,
15257 		     Uint32 tableId,
15258 		     Uint32 fragNo){
15259   jam();
15260   DihSwitchReplicaReq* const req = (DihSwitchReplicaReq*)&signal->theData[0];
15261 
15262   const Uint32 RT_BREAK = 64;
15263 
15264   for (Uint32 i = 0; i < RT_BREAK; i++) {
15265     jam();
15266     if (tableId >= ctabFileSize) {
15267       jam();
15268       StopPermConf* const conf = (StopPermConf*)&signal->theData[0];
15269       StopPermRef*  const ref  = (StopPermRef*)&signal->theData[0];
15270       /**
15271        * Finished with all tables
15272        */
15273       if(c_stopPermMaster.returnValue == 0) {
15274 	jam();
15275 	conf->senderData = c_stopPermMaster.clientData;
15276 	sendSignal(c_stopPermMaster.clientRef, GSN_STOP_PERM_CONF,
15277 		   signal, 1, JBB);
15278       } else {
15279         jam();
15280         ref->senderData = c_stopPermMaster.clientData;
15281         ref->errorCode  = c_stopPermMaster.returnValue;
15282         sendSignal(c_stopPermMaster.clientRef, GSN_STOP_PERM_REF, signal, 2,JBB);
15283       }//if
15284 
15285       /**
15286        * UnLock
15287        */
15288       c_nodeStartMaster.activeState = false;
15289       c_stopPermMaster.clientRef = 0;
15290       c_stopPermMaster.clientData = 0;
15291       c_stopPermMaster.returnValue = 0;
15292       Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
15293       mutex.unlock(); // ignore result
15294       return;
15295     }//if
15296 
15297     TabRecordPtr tabPtr;
15298     tabPtr.i = tableId;
15299     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
15300 
15301     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
15302       jam();
15303       tableId++;
15304       fragNo = 0;
15305       continue;
15306     }//if
15307     if (fragNo >= tabPtr.p->totalfragments) {
15308       jam();
15309       tableId++;
15310       fragNo = 0;
15311       continue;
15312     }//if
15313     FragmentstorePtr fragPtr;
15314     getFragstore(tabPtr.p, fragNo, fragPtr);
15315 
15316     Uint32 oldOrder[MAX_REPLICAS];
15317     const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, oldOrder);
15318 
15319     if(oldOrder[0] != nodeId) {
15320       jam();
15321       fragNo++;
15322       continue;
15323     }//if
15324     req->tableId = tableId;
15325     req->fragNo = fragNo;
15326     req->noOfReplicas = noOfReplicas;
15327     for (Uint32 i = 0; i < (noOfReplicas - 1); i++) {
15328       req->newNodeOrder[i] = oldOrder[i+1];
15329     }//for
15330     req->newNodeOrder[noOfReplicas-1] = nodeId;
15331     req->senderRef = reference();
15332 
15333     /**
15334      * Initialize struct
15335      */
15336     c_switchReplicas.tableId = tableId;
15337     c_switchReplicas.fragNo = fragNo;
15338     c_switchReplicas.nodeId = nodeId;
15339 
15340     sendLoopMacro(DIH_SWITCH_REPLICA_REQ, sendDIH_SWITCH_REPLICA_REQ);
15341     return;
15342   }//for
15343 
15344   signal->theData[0] = DihContinueB::SwitchReplica;
15345   signal->theData[1] = nodeId;
15346   signal->theData[2] = tableId;
15347   signal->theData[3] = fragNo;
15348   sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
15349 }//Dbdih::switchReplica()
15350 
execSTOP_ME_REQ(Signal * signal)15351 void Dbdih::execSTOP_ME_REQ(Signal* signal)
15352 {
15353   jamEntry();
15354   StopMeReq* const req = (StopMeReq*)&signal->theData[0];
15355   const BlockReference senderRef = req->senderRef;
15356   const Uint32 senderData = req->senderData;
15357   const Uint32 nodeId = refToNode(senderRef);
15358   {
15359     /**
15360      * Set node dead (remove from operations)
15361      */
15362     NodeRecordPtr nodePtr;
15363     nodePtr.i = nodeId;
15364     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15365     nodePtr.p->useInTransactions = false;
15366   }
15367   if (nodeId != getOwnNodeId()) {
15368     jam();
15369     StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
15370     stopMeConf->senderData = senderData;
15371     stopMeConf->senderRef  = reference();
15372     sendSignal(senderRef, GSN_STOP_ME_CONF, signal,
15373 	       StopMeConf::SignalLength, JBB);
15374     return;
15375   }//if
15376 
15377   /**
15378    * Local signal
15379    */
15380   jam();
15381   ndbrequire(c_stopMe.clientRef == 0);
15382 
15383   c_stopMe.clientData  = senderData;
15384   c_stopMe.clientRef   = senderRef;
15385 
15386   req->senderData = senderData;
15387   req->senderRef  = reference();
15388 
15389   sendLoopMacro(STOP_ME_REQ, sendSTOP_ME_REQ);
15390 
15391   /**
15392    * Send conf to self
15393    */
15394   StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
15395   stopMeConf->senderData = senderData;
15396   stopMeConf->senderRef  = reference();
15397   sendSignal(reference(), GSN_STOP_ME_CONF, signal,
15398 	     StopMeConf::SignalLength, JBB);
15399 }//Dbdih::execSTOP_ME_REQ()
15400 
execSTOP_ME_REF(Signal * signal)15401 void Dbdih::execSTOP_ME_REF(Signal* signal)
15402 {
15403   ndbrequire(false);
15404 }
15405 
execSTOP_ME_CONF(Signal * signal)15406 void Dbdih::execSTOP_ME_CONF(Signal* signal)
15407 {
15408   jamEntry();
15409   StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
15410 
15411   const Uint32 senderRef  = stopMeConf->senderRef;
15412   const Uint32 senderData = stopMeConf->senderData;
15413   const Uint32 nodeId     = refToNode(senderRef);
15414 
15415   ndbrequire(c_stopMe.clientRef != 0);
15416   ndbrequire(c_stopMe.clientData == senderData);
15417 
15418   receiveLoopMacro(STOP_ME_REQ, nodeId);
15419   //---------------------------------------------------------
15420   // All STOP_ME_REQ have been received. We will send the
15421   // confirmation back to the requesting block.
15422   //---------------------------------------------------------
15423 
15424   stopMeConf->senderRef = reference();
15425   stopMeConf->senderData = c_stopMe.clientData;
15426   sendSignal(c_stopMe.clientRef, GSN_STOP_ME_CONF, signal,
15427 	     StopMeConf::SignalLength, JBB);
15428   c_stopMe.clientRef = 0;
15429 }//Dbdih::execSTOP_ME_CONF()
15430 
execWAIT_GCP_REQ(Signal * signal)15431 void Dbdih::execWAIT_GCP_REQ(Signal* signal)
15432 {
15433   jamEntry();
15434   WaitGCPReq* const req = (WaitGCPReq*)&signal->theData[0];
15435   WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
15436   WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
15437   const Uint32 senderData = req->senderData;
15438   const BlockReference senderRef = req->senderRef;
15439   const Uint32 requestType = req->requestType;
15440 
15441   if(requestType == WaitGCPReq::CurrentGCI) {
15442     jam();
15443     conf->senderData = senderData;
15444     conf->gcp = cnewgcp;
15445     conf->blockStatus = cgcpOrderBlocked;
15446     sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
15447 	       WaitGCPConf::SignalLength, JBB);
15448     return;
15449   }//if
15450 
15451   if (requestType == WaitGCPReq::BlockStartGcp)
15452   {
15453     jam();
15454     conf->senderData = senderData;
15455     conf->gcp = cnewgcp;
15456     conf->blockStatus = cgcpOrderBlocked;
15457     sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
15458 	       WaitGCPConf::SignalLength, JBB);
15459     cgcpOrderBlocked = 1;
15460     return;
15461   }
15462 
15463   if (requestType == WaitGCPReq::UnblockStartGcp)
15464   {
15465     jam();
15466     conf->senderData = senderData;
15467     conf->gcp = cnewgcp;
15468     conf->blockStatus = cgcpOrderBlocked;
15469     sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
15470 	       WaitGCPConf::SignalLength, JBB);
15471     cgcpOrderBlocked = 0;
15472     return;
15473   }
15474 
15475   if(isMaster()) {
15476     /**
15477      * Master
15478      */
15479     jam();
15480 
15481     if((requestType == WaitGCPReq::CompleteIfRunning) &&
15482        (cgcpStatus == GCP_READY)) {
15483       jam();
15484       conf->senderData = senderData;
15485       conf->gcp = coldgcp;
15486       conf->blockStatus = cgcpOrderBlocked;
15487       sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
15488 		 WaitGCPConf::SignalLength, JBB);
15489       return;
15490     }//if
15491 
15492     WaitGCPMasterPtr ptr;
15493     if(c_waitGCPMasterList.seize(ptr) == false){
15494       jam();
15495       ref->senderData = senderData;
15496       ref->errorCode = WaitGCPRef::NoWaitGCPRecords;
15497       sendSignal(senderRef, GSN_WAIT_GCP_REF, signal,
15498 		 WaitGCPRef::SignalLength, JBB);
15499       return;
15500     }//if
15501     ptr.p->clientRef = senderRef;
15502     ptr.p->clientData = senderData;
15503 
15504     if((requestType == WaitGCPReq::CompleteForceStart) &&
15505        (cgcpStatus == GCP_READY)) {
15506       jam();
15507       cstartGcpNow = true;
15508     }//if
15509     return;
15510   } else {
15511     /**
15512      * Proxy part
15513      */
15514     jam();
15515     WaitGCPProxyPtr ptr;
15516     if (c_waitGCPProxyList.seize(ptr) == false) {
15517       jam();
15518       ref->senderData = senderData;
15519       ref->errorCode = WaitGCPRef::NoWaitGCPRecords;
15520       sendSignal(senderRef, GSN_WAIT_GCP_REF, signal,
15521 		 WaitGCPRef::SignalLength, JBB);
15522       return;
15523     }//if
15524     ptr.p->clientRef = senderRef;
15525     ptr.p->clientData = senderData;
15526     ptr.p->masterRef = cmasterdihref;
15527 
15528     req->senderData = ptr.i;
15529     req->senderRef = reference();
15530     req->requestType = requestType;
15531 
15532     sendSignal(cmasterdihref, GSN_WAIT_GCP_REQ, signal,
15533 	       WaitGCPReq::SignalLength, JBB);
15534     return;
15535   }//if
15536 }//Dbdih::execWAIT_GCP_REQ()
15537 
execWAIT_GCP_REF(Signal * signal)15538 void Dbdih::execWAIT_GCP_REF(Signal* signal)
15539 {
15540   jamEntry();
15541   ndbrequire(!isMaster());
15542   WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
15543 
15544   const Uint32 proxyPtr = ref->senderData;
15545   const Uint32 errorCode = ref->errorCode;
15546 
15547   WaitGCPProxyPtr ptr;
15548   ptr.i = proxyPtr;
15549   c_waitGCPProxyList.getPtr(ptr);
15550 
15551   ref->senderData = ptr.p->clientData;
15552   ref->errorCode = errorCode;
15553   sendSignal(ptr.p->clientRef, GSN_WAIT_GCP_REF, signal,
15554 	     WaitGCPRef::SignalLength, JBB);
15555 
15556   c_waitGCPProxyList.release(ptr);
15557 }//Dbdih::execWAIT_GCP_REF()
15558 
execWAIT_GCP_CONF(Signal * signal)15559 void Dbdih::execWAIT_GCP_CONF(Signal* signal)
15560 {
15561   jamEntry();
15562   ndbrequire(!isMaster());
15563   WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
15564   const Uint32 proxyPtr = conf->senderData;
15565   const Uint32 gcp = conf->gcp;
15566   WaitGCPProxyPtr ptr;
15567 
15568   ptr.i = proxyPtr;
15569   c_waitGCPProxyList.getPtr(ptr);
15570 
15571   conf->senderData = ptr.p->clientData;
15572   conf->gcp = gcp;
15573   conf->blockStatus = cgcpOrderBlocked;
15574   sendSignal(ptr.p->clientRef, GSN_WAIT_GCP_CONF, signal,
15575 	     WaitGCPConf::SignalLength, JBB);
15576 
15577   c_waitGCPProxyList.release(ptr);
15578 }//Dbdih::execWAIT_GCP_CONF()
15579 
checkWaitGCPProxy(Signal * signal,NodeId failedNodeId)15580 void Dbdih::checkWaitGCPProxy(Signal* signal, NodeId failedNodeId)
15581 {
15582   jam();
15583   WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
15584   ref->errorCode = WaitGCPRef::NF_CausedAbortOfProcedure;
15585 
15586   WaitGCPProxyPtr ptr;
15587   c_waitGCPProxyList.first(ptr);
15588   while(ptr.i != RNIL) {
15589     jam();
15590     const Uint32 i = ptr.i;
15591     const Uint32 clientData = ptr.p->clientData;
15592     const BlockReference clientRef = ptr.p->clientRef;
15593     const BlockReference masterRef = ptr.p->masterRef;
15594 
15595     c_waitGCPProxyList.next(ptr);
15596     if(refToNode(masterRef) == failedNodeId) {
15597       jam();
15598       c_waitGCPProxyList.release(i);
15599       ref->senderData = clientData;
15600       sendSignal(clientRef, GSN_WAIT_GCP_REF, signal,
15601 		 WaitGCPRef::SignalLength, JBB);
15602     }//if
15603   }//while
15604 }//Dbdih::checkWaitGCPProxy()
15605 
checkWaitGCPMaster(Signal * signal,NodeId failedNodeId)15606 void Dbdih::checkWaitGCPMaster(Signal* signal, NodeId failedNodeId)
15607 {
15608   jam();
15609   WaitGCPMasterPtr ptr;
15610   c_waitGCPMasterList.first(ptr);
15611 
15612   while (ptr.i != RNIL) {
15613     jam();
15614     const Uint32 i = ptr.i;
15615     const NodeId nodeId = refToNode(ptr.p->clientRef);
15616 
15617     c_waitGCPMasterList.next(ptr);
15618     if (nodeId == failedNodeId) {
15619       jam()
15620 	c_waitGCPMasterList.release(i);
15621     }//if
15622   }//while
15623 }//Dbdih::checkWaitGCPMaster()
15624 
emptyWaitGCPMasterQueue(Signal * signal)15625 void Dbdih::emptyWaitGCPMasterQueue(Signal* signal)
15626 {
15627   jam();
15628   WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
15629   conf->gcp = coldgcp;
15630 
15631   WaitGCPMasterPtr ptr;
15632   c_waitGCPMasterList.first(ptr);
15633   while(ptr.i != RNIL) {
15634     jam();
15635     const Uint32 i = ptr.i;
15636     const Uint32 clientData = ptr.p->clientData;
15637     const BlockReference clientRef = ptr.p->clientRef;
15638 
15639     c_waitGCPMasterList.next(ptr);
15640     conf->senderData = clientData;
15641     conf->blockStatus = cgcpOrderBlocked;
15642     sendSignal(clientRef, GSN_WAIT_GCP_CONF, signal,
15643 	       WaitGCPConf::SignalLength, JBB);
15644 
15645     c_waitGCPMasterList.release(i);
15646   }//while
15647 }//Dbdih::emptyWaitGCPMasterQueue()
15648 
setNodeStatus(Uint32 nodeId,NodeRecord::NodeStatus newStatus)15649 void Dbdih::setNodeStatus(Uint32 nodeId, NodeRecord::NodeStatus newStatus)
15650 {
15651   NodeRecordPtr nodePtr;
15652   nodePtr.i = nodeId;
15653   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15654   nodePtr.p->nodeStatus = newStatus;
15655 }//Dbdih::setNodeStatus()
15656 
getNodeStatus(Uint32 nodeId)15657 Dbdih::NodeRecord::NodeStatus Dbdih::getNodeStatus(Uint32 nodeId)
15658 {
15659   NodeRecordPtr nodePtr;
15660   nodePtr.i = nodeId;
15661   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15662   return nodePtr.p->nodeStatus;
15663 }//Dbdih::getNodeStatus()
15664 
15665 Sysfile::ActiveStatus
getNodeActiveStatus(Uint32 nodeId)15666 Dbdih::getNodeActiveStatus(Uint32 nodeId)
15667 {
15668   NodeRecordPtr nodePtr;
15669   nodePtr.i = nodeId;
15670   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15671   return nodePtr.p->activeStatus;
15672 }//Dbdih::getNodeActiveStatus()
15673 
15674 
15675 void
setNodeActiveStatus(Uint32 nodeId,Sysfile::ActiveStatus newStatus)15676 Dbdih::setNodeActiveStatus(Uint32 nodeId, Sysfile::ActiveStatus newStatus)
15677 {
15678   NodeRecordPtr nodePtr;
15679   nodePtr.i = nodeId;
15680   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15681   nodePtr.p->activeStatus = newStatus;
15682 }//Dbdih::setNodeActiveStatus()
15683 
setAllowNodeStart(Uint32 nodeId,bool newState)15684 void Dbdih::setAllowNodeStart(Uint32 nodeId, bool newState)
15685 {
15686   NodeRecordPtr nodePtr;
15687   nodePtr.i = nodeId;
15688   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15689   nodePtr.p->allowNodeStart = newState;
15690 }//Dbdih::setAllowNodeStart()
15691 
setNodeCopyCompleted(Uint32 nodeId,bool newState)15692 void Dbdih::setNodeCopyCompleted(Uint32 nodeId, bool newState)
15693 {
15694   NodeRecordPtr nodePtr;
15695   nodePtr.i = nodeId;
15696   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15697   nodePtr.p->copyCompleted = newState;
15698 }//Dbdih::setNodeCopyCompleted()
15699 
getAllowNodeStart(Uint32 nodeId)15700 bool Dbdih::getAllowNodeStart(Uint32 nodeId)
15701 {
15702   NodeRecordPtr nodePtr;
15703   nodePtr.i = nodeId;
15704   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15705   return nodePtr.p->allowNodeStart;
15706 }//Dbdih::getAllowNodeStart()
15707 
getNodeCopyCompleted(Uint32 nodeId)15708 bool Dbdih::getNodeCopyCompleted(Uint32 nodeId)
15709 {
15710   NodeRecordPtr nodePtr;
15711   nodePtr.i = nodeId;
15712   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15713   return nodePtr.p->copyCompleted;
15714 }//Dbdih::getNodeCopyCompleted()
15715 
checkNodeAlive(Uint32 nodeId)15716 bool Dbdih::checkNodeAlive(Uint32 nodeId)
15717 {
15718   NodeRecordPtr nodePtr;
15719   nodePtr.i = nodeId;
15720   ndbrequire(nodeId > 0);
15721   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15722   if (nodePtr.p->nodeStatus != NodeRecord::ALIVE) {
15723     return false;
15724   } else {
15725     return true;
15726   }//if
15727 }//Dbdih::checkNodeAlive()
15728 
isMaster()15729 bool Dbdih::isMaster()
15730 {
15731   return (reference() == cmasterdihref);
15732 }//Dbdih::isMaster()
15733 
isActiveMaster()15734 bool Dbdih::isActiveMaster()
15735 {
15736   return ((reference() == cmasterdihref) && (cmasterState == MASTER_ACTIVE));
15737 }//Dbdih::isActiveMaster()
15738 
NodeRecord()15739 Dbdih::NodeRecord::NodeRecord(){
15740   m_nodefailSteps.clear();
15741   gcpstate = NodeRecord::READY;
15742 
15743   activeStatus = Sysfile::NS_NotDefined;
15744   recNODE_FAILREP = ZFALSE;
15745   nodeGroup = ZNIL;
15746   dbtcFailCompleted = ZTRUE;
15747   dbdictFailCompleted = ZTRUE;
15748   dbdihFailCompleted = ZTRUE;
15749   dblqhFailCompleted = ZTRUE;
15750   noOfStartedChkpt = 0;
15751   noOfQueuedChkpt = 0;
15752   lcpStateAtTakeOver = (MasterLCPConf::State)255;
15753 
15754   activeTabptr = RNIL;
15755   nodeStatus = NodeRecord::NOT_IN_CLUSTER;
15756   useInTransactions = false;
15757   copyCompleted = false;
15758   allowNodeStart = true;
15759 }
15760 
15761 // DICT lock slave
15762 
15763 void
sendDictLockReq(Signal * signal,Uint32 lockType,Callback c)15764 Dbdih::sendDictLockReq(Signal* signal, Uint32 lockType, Callback c)
15765 {
15766   DictLockReq* req = (DictLockReq*)&signal->theData[0];
15767   DictLockSlavePtr lockPtr;
15768 
15769   c_dictLockSlavePool.seize(lockPtr);
15770   ndbrequire(lockPtr.i != RNIL);
15771 
15772   req->userPtr = lockPtr.i;
15773   req->lockType = lockType;
15774   req->userRef = reference();
15775 
15776   lockPtr.p->lockPtr = RNIL;
15777   lockPtr.p->lockType = lockType;
15778   lockPtr.p->locked = false;
15779   lockPtr.p->callback = c;
15780 
15781   // handle rolling upgrade
15782   {
15783     Uint32 masterVersion = getNodeInfo(cmasterNodeId).m_version;
15784 
15785     const unsigned int get_major = getMajor(masterVersion);
15786     const unsigned int get_minor = getMinor(masterVersion);
15787     const unsigned int get_build = getBuild(masterVersion);
15788     ndbrequire(get_major >= 4);
15789 
15790     if (masterVersion < NDBD_DICT_LOCK_VERSION_5 ||
15791         masterVersion < NDBD_DICT_LOCK_VERSION_5_1 &&
15792           get_major == 5 && get_minor == 1 ||
15793         ERROR_INSERTED(7176)) {
15794       jam();
15795 
15796       infoEvent("DIH: detect upgrade: master node %u old version %u.%u.%u",
15797         (unsigned int)cmasterNodeId, get_major, get_minor, get_build);
15798 
15799       DictLockConf* conf = (DictLockConf*)&signal->theData[0];
15800       conf->userPtr = lockPtr.i;
15801       conf->lockType = lockType;
15802       conf->lockPtr = ZNIL;
15803 
15804       sendSignal(reference(), GSN_DICT_LOCK_CONF, signal,
15805           DictLockConf::SignalLength, JBB);
15806       return;
15807     }
15808   }
15809 
15810   BlockReference dictMasterRef = calcDictBlockRef(cmasterNodeId);
15811   sendSignal(dictMasterRef, GSN_DICT_LOCK_REQ, signal,
15812       DictLockReq::SignalLength, JBB);
15813 }
15814 
15815 void
execDICT_LOCK_CONF(Signal * signal)15816 Dbdih::execDICT_LOCK_CONF(Signal* signal)
15817 {
15818   jamEntry();
15819   recvDictLockConf(signal);
15820 }
15821 
15822 void
execDICT_LOCK_REF(Signal * signal)15823 Dbdih::execDICT_LOCK_REF(Signal* signal)
15824 {
15825   jamEntry();
15826   ndbrequire(false);
15827 }
15828 
15829 void
recvDictLockConf(Signal * signal)15830 Dbdih::recvDictLockConf(Signal* signal)
15831 {
15832   const DictLockConf* conf = (const DictLockConf*)&signal->theData[0];
15833 
15834   DictLockSlavePtr lockPtr;
15835   c_dictLockSlavePool.getPtr(lockPtr, conf->userPtr);
15836 
15837   lockPtr.p->lockPtr = conf->lockPtr;
15838   ndbrequire(lockPtr.p->lockType == conf->lockType);
15839   ndbrequire(lockPtr.p->locked == false);
15840   lockPtr.p->locked = true;
15841 
15842   lockPtr.p->callback.m_callbackData = lockPtr.i;
15843   execute(signal, lockPtr.p->callback, 0);
15844 }
15845 
15846 void
sendDictUnlockOrd(Signal * signal,Uint32 lockSlavePtrI)15847 Dbdih::sendDictUnlockOrd(Signal* signal, Uint32 lockSlavePtrI)
15848 {
15849   DictUnlockOrd* ord = (DictUnlockOrd*)&signal->theData[0];
15850 
15851   DictLockSlavePtr lockPtr;
15852   c_dictLockSlavePool.getPtr(lockPtr, lockSlavePtrI);
15853 
15854   ord->lockPtr = lockPtr.p->lockPtr;
15855   ord->lockType = lockPtr.p->lockType;
15856 
15857   c_dictLockSlavePool.release(lockPtr);
15858 
15859   // handle rolling upgrade
15860   {
15861     Uint32 masterVersion = getNodeInfo(cmasterNodeId).m_version;
15862 
15863     const unsigned int get_major = getMajor(masterVersion);
15864     const unsigned int get_minor = getMinor(masterVersion);
15865     ndbrequire(get_major >= 4);
15866 
15867     if (masterVersion < NDBD_DICT_LOCK_VERSION_5 ||
15868         masterVersion < NDBD_DICT_LOCK_VERSION_5_1 &&
15869           get_major == 5 && get_minor == 1 ||
15870         ERROR_INSERTED(7176)) {
15871       return;
15872     }
15873   }
15874 
15875   BlockReference dictMasterRef = calcDictBlockRef(cmasterNodeId);
15876   sendSignal(dictMasterRef, GSN_DICT_UNLOCK_ORD, signal,
15877       DictUnlockOrd::SignalLength, JBB);
15878 }
15879