1 /*
2    Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #include "DbtcProxy.hpp"
26 #include "Dbtc.hpp"
27 
DbtcProxy(Block_context & ctx)28 DbtcProxy::DbtcProxy(Block_context& ctx) :
29   LocalProxy(DBTC, ctx)
30 {
31   // GSN_TC_SCHVERREQ
32   addRecSignal(GSN_TC_SCHVERREQ, &DbtcProxy::execTC_SCHVERREQ);
33   addRecSignal(GSN_TC_SCHVERCONF, &DbtcProxy::execTC_SCHVERCONF);
34 
35   // GSN_TAB_COMMITREQ
36   addRecSignal(GSN_TAB_COMMITREQ, &DbtcProxy::execTAB_COMMITREQ);
37   addRecSignal(GSN_TAB_COMMITCONF, &DbtcProxy::execTAB_COMMITCONF);
38   addRecSignal(GSN_TAB_COMMITREF, &DbtcProxy::execTAB_COMMITREF);
39 
40   // GSN_TCSEIZEREQ
41   addRecSignal(GSN_TCSEIZEREQ, &DbtcProxy::execTCSEIZEREQ);
42 
43   // GSN_TCGETOPSIZEREQ
44   addRecSignal(GSN_TCGETOPSIZEREQ, &DbtcProxy::execTCGETOPSIZEREQ);
45   addRecSignal(GSN_TCGETOPSIZECONF, &DbtcProxy::execTCGETOPSIZECONF);
46 
47   // GSN_TCGETOPSIZEREQ
48   addRecSignal(GSN_TC_CLOPSIZEREQ, &DbtcProxy::execTC_CLOPSIZEREQ);
49   addRecSignal(GSN_TC_CLOPSIZECONF, &DbtcProxy::execTC_CLOPSIZECONF);
50 
51   // GSN_GCP_NOMORETRANS
52   addRecSignal(GSN_GCP_NOMORETRANS, &DbtcProxy::execGCP_NOMORETRANS);
53   addRecSignal(GSN_GCP_TCFINISHED, &DbtcProxy::execGCP_TCFINISHED);
54 
55   // GSN_API_FAILREQ
56   addRecSignal(GSN_API_FAILREQ, &DbtcProxy::execAPI_FAILREQ);
57   addRecSignal(GSN_API_FAILCONF, &DbtcProxy::execAPI_FAILCONF);
58 
59   // GSN_PREP_DROP_TAB_REQ
60   addRecSignal(GSN_PREP_DROP_TAB_REQ, &DbtcProxy::execPREP_DROP_TAB_REQ);
61   addRecSignal(GSN_PREP_DROP_TAB_CONF, &DbtcProxy::execPREP_DROP_TAB_CONF);
62   addRecSignal(GSN_PREP_DROP_TAB_REF, &DbtcProxy::execPREP_DROP_TAB_REF);
63 
64   // GSN_DROP_TAB_REQ
65   addRecSignal(GSN_DROP_TAB_REQ, &DbtcProxy::execDROP_TAB_REQ);
66   addRecSignal(GSN_DROP_TAB_CONF, &DbtcProxy::execDROP_TAB_CONF);
67   addRecSignal(GSN_DROP_TAB_REF, &DbtcProxy::execDROP_TAB_REF);
68 
69   // GSN_ALTER_TAB_REQ
70   addRecSignal(GSN_ALTER_TAB_REQ, &DbtcProxy::execALTER_TAB_REQ);
71   addRecSignal(GSN_ALTER_TAB_CONF, &DbtcProxy::execALTER_TAB_CONF);
72   addRecSignal(GSN_ALTER_TAB_REF, &DbtcProxy::execALTER_TAB_REF);
73 
74   // GSN_CREATE_INDX_IMPL_REQ
75   addRecSignal(GSN_CREATE_INDX_IMPL_REQ, &DbtcProxy::execCREATE_INDX_IMPL_REQ);
76   addRecSignal(GSN_CREATE_INDX_IMPL_CONF,&DbtcProxy::execCREATE_INDX_IMPL_CONF);
77   addRecSignal(GSN_CREATE_INDX_IMPL_REF, &DbtcProxy::execCREATE_INDX_IMPL_REF);
78 
79   // GSN_ALTER_INDX_IMPL_REQ
80   addRecSignal(GSN_ALTER_INDX_IMPL_REQ, &DbtcProxy::execALTER_INDX_IMPL_REQ);
81   addRecSignal(GSN_ALTER_INDX_IMPL_CONF,&DbtcProxy::execALTER_INDX_IMPL_CONF);
82   addRecSignal(GSN_ALTER_INDX_IMPL_REF, &DbtcProxy::execALTER_INDX_IMPL_REF);
83 
84   // GSN_DROP_INDX_IMPL_REQ
85   addRecSignal(GSN_DROP_INDX_IMPL_REQ, &DbtcProxy::execDROP_INDX_IMPL_REQ);
86   addRecSignal(GSN_DROP_INDX_IMPL_CONF,&DbtcProxy::execDROP_INDX_IMPL_CONF);
87   addRecSignal(GSN_DROP_INDX_IMPL_REF, &DbtcProxy::execDROP_INDX_IMPL_REF);
88 
89   // GSN_TAKE_OVERTCCONF
90   addRecSignal(GSN_TAKE_OVERTCCONF,&DbtcProxy::execTAKE_OVERTCCONF);
91 
92   m_tc_seize_req_instance = 0;
93 }
94 
~DbtcProxy()95 DbtcProxy::~DbtcProxy()
96 {
97 }
98 
99 SimulatedBlock*
newWorker(Uint32 instanceNo)100 DbtcProxy::newWorker(Uint32 instanceNo)
101 {
102   return new Dbtc(m_ctx, instanceNo);
103 }
104 
105 // GSN_NDB_STTOR
106 
107 void
callNDB_STTOR(Signal * signal)108 DbtcProxy::callNDB_STTOR(Signal* signal)
109 {
110   Ss_READ_NODES_REQ& ss = c_ss_READ_NODESREQ;
111   ndbrequire(ss.m_gsn == 0);
112 
113   const Uint32 startPhase = signal->theData[2];
114   switch (startPhase) {
115   case 3:
116     ss.m_gsn = GSN_NDB_STTOR;
117     sendREAD_NODESREQ(signal);
118     break;
119   default:
120     backNDB_STTOR(signal);
121     break;
122   }
123 }
124 
125 // GSN_TC_SCHVERREQ
126 
127 void
execTC_SCHVERREQ(Signal * signal)128 DbtcProxy::execTC_SCHVERREQ(Signal* signal)
129 {
130   Ss_TC_SCHVERREQ& ss = ssSeize<Ss_TC_SCHVERREQ>(1);
131 
132   const TcSchVerReq* req = (const TcSchVerReq*)signal->getDataPtr();
133   ss.m_req = *req;
134 
135   sendREQ(signal, ss);
136 }
137 
138 void
sendTC_SCHVERREQ(Signal * signal,Uint32 ssId,SectionHandle *)139 DbtcProxy::sendTC_SCHVERREQ(Signal* signal, Uint32 ssId, SectionHandle*)
140 {
141   Ss_TC_SCHVERREQ& ss = ssFind<Ss_TC_SCHVERREQ>(ssId);
142 
143   TcSchVerReq* req = (TcSchVerReq*)signal->getDataPtrSend();
144   *req = ss.m_req;
145   req->senderRef = reference();
146   req->senderData = ssId;
147   sendSignal(workerRef(ss.m_worker), GSN_TC_SCHVERREQ,
148              signal, TcSchVerReq::SignalLength, JBB);
149 }
150 
151 void
execTC_SCHVERCONF(Signal * signal)152 DbtcProxy::execTC_SCHVERCONF(Signal* signal)
153 {
154   const TcSchVerConf* conf = (const TcSchVerConf*)signal->getDataPtr();
155   Uint32 ssId = conf->senderData;
156   Ss_TC_SCHVERREQ& ss = ssFind<Ss_TC_SCHVERREQ>(ssId);
157   recvCONF(signal, ss);
158 }
159 
160 void
sendTC_SCHVERCONF(Signal * signal,Uint32 ssId)161 DbtcProxy::sendTC_SCHVERCONF(Signal* signal, Uint32 ssId)
162 {
163   Ss_TC_SCHVERREQ& ss = ssFind<Ss_TC_SCHVERREQ>(ssId);
164   BlockReference dictRef = ss.m_req.senderRef;
165 
166   if (!lastReply(ss))
167     return;
168 
169   TcSchVerConf* conf = (TcSchVerConf*)signal->getDataPtrSend();
170   conf->senderRef = reference();
171   conf->senderData = ss.m_req.senderData;
172   sendSignal(dictRef, GSN_TC_SCHVERCONF,
173              signal, TcSchVerConf::SignalLength, JBB);
174 
175   ssRelease<Ss_TC_SCHVERREQ>(ssId);
176 }
177 
178 // GSN_TAB_COMMITREQ [ sub-op ]
179 
180 void
execTAB_COMMITREQ(Signal * signal)181 DbtcProxy::execTAB_COMMITREQ(Signal* signal)
182 {
183   Ss_TAB_COMMITREQ& ss = ssSeize<Ss_TAB_COMMITREQ>(1); // lost connection
184 
185   const TabCommitReq* req = (const TabCommitReq*)signal->getDataPtr();
186   ss.m_req = *req;
187   sendREQ(signal, ss);
188 }
189 
190 void
sendTAB_COMMITREQ(Signal * signal,Uint32 ssId,SectionHandle *)191 DbtcProxy::sendTAB_COMMITREQ(Signal* signal, Uint32 ssId, SectionHandle*)
192 {
193   Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
194 
195   TabCommitReq* req = (TabCommitReq*)signal->getDataPtrSend();
196   req->senderRef = reference();
197   req->senderData = ssId;
198   req->tableId = ss.m_req.tableId;
199   sendSignal(workerRef(ss.m_worker), GSN_TAB_COMMITREQ,
200              signal, TabCommitReq::SignalLength, JBB);
201 }
202 
203 void
execTAB_COMMITCONF(Signal * signal)204 DbtcProxy::execTAB_COMMITCONF(Signal* signal)
205 {
206   const TabCommitConf* conf = (TabCommitConf*)signal->getDataPtr();
207   Uint32 ssId = conf->senderData;
208   Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
209   recvCONF(signal, ss);
210 }
211 
212 void
execTAB_COMMITREF(Signal * signal)213 DbtcProxy::execTAB_COMMITREF(Signal* signal)
214 {
215   const TabCommitRef* ref = (TabCommitRef*)signal->getDataPtr();
216   Uint32 ssId = ref->senderData;
217   Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
218 
219   recvREF(signal, ss, ref->errorCode);
220 }
221 
222 void
sendTAB_COMMITCONF(Signal * signal,Uint32 ssId)223 DbtcProxy::sendTAB_COMMITCONF(Signal* signal, Uint32 ssId)
224 {
225   Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
226   BlockReference dictRef = ss.m_req.senderRef;
227 
228   if (!lastReply(ss))
229     return;
230 
231   if (ss.m_error == 0) {
232     jam();
233     TabCommitConf* conf = (TabCommitConf*)signal->getDataPtrSend();
234     conf->senderData = ss.m_req.senderData;
235     conf->nodeId = getOwnNodeId();
236     conf->tableId = ss.m_req.tableId;
237     sendSignal(dictRef, GSN_TAB_COMMITCONF,
238                signal, TabCommitConf::SignalLength, JBB);
239   } else {
240     jam();
241     TabCommitRef* ref = (TabCommitRef*)signal->getDataPtrSend();
242     ref->senderData = ss.m_req.senderData;
243     ref->nodeId = getOwnNodeId();
244     ref->tableId = ss.m_req.tableId;
245     sendSignal(dictRef, GSN_TAB_COMMITREF,
246                signal, TabCommitRef::SignalLength, JBB);
247     return;
248   }
249 
250   ssRelease<Ss_TAB_COMMITREQ>(ssId);
251 }
252 
253 // GSN_PREP_DROP_TAB_REQ
254 
255 void
execPREP_DROP_TAB_REQ(Signal * signal)256 DbtcProxy::execPREP_DROP_TAB_REQ(Signal* signal)
257 {
258   const PrepDropTabReq* req = (const PrepDropTabReq*)signal->getDataPtr();
259   Uint32 ssId = getSsId(req);
260   Ss_PREP_DROP_TAB_REQ& ss = ssSeize<Ss_PREP_DROP_TAB_REQ>(ssId);
261   ss.m_req = *req;
262   ndbrequire(signal->getLength() == PrepDropTabReq::SignalLength);
263   sendREQ(signal, ss);
264 }
265 
266 void
sendPREP_DROP_TAB_REQ(Signal * signal,Uint32 ssId,SectionHandle *)267 DbtcProxy::sendPREP_DROP_TAB_REQ(Signal* signal, Uint32 ssId, SectionHandle*)
268 {
269   Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
270 
271   PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtrSend();
272   *req = ss.m_req;
273   req->senderRef = reference();
274   req->senderData = ssId; // redundant since tableId is used
275   sendSignal(workerRef(ss.m_worker), GSN_PREP_DROP_TAB_REQ,
276              signal, PrepDropTabReq::SignalLength, JBB);
277 }
278 
279 void
execPREP_DROP_TAB_CONF(Signal * signal)280 DbtcProxy::execPREP_DROP_TAB_CONF(Signal* signal)
281 {
282   const PrepDropTabConf* conf = (const PrepDropTabConf*)signal->getDataPtr();
283   Uint32 ssId = getSsId(conf);
284   Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
285   recvCONF(signal, ss);
286 }
287 
288 void
execPREP_DROP_TAB_REF(Signal * signal)289 DbtcProxy::execPREP_DROP_TAB_REF(Signal* signal)
290 {
291   const PrepDropTabRef* ref = (const PrepDropTabRef*)signal->getDataPtr();
292   Uint32 ssId = getSsId(ref);
293   Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
294   recvREF(signal, ss, ref->errorCode);
295 }
296 
297 void
sendPREP_DROP_TAB_CONF(Signal * signal,Uint32 ssId)298 DbtcProxy::sendPREP_DROP_TAB_CONF(Signal* signal, Uint32 ssId)
299 {
300   Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
301   BlockReference dictRef = ss.m_req.senderRef;
302 
303   if (!lastReply(ss))
304     return;
305 
306   if (ss.m_error == 0) {
307     jam();
308     PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
309     conf->senderRef = reference();
310     conf->senderData = ss.m_req.senderData;
311     conf->tableId = ss.m_req.tableId;
312     sendSignal(dictRef, GSN_PREP_DROP_TAB_CONF,
313                signal, PrepDropTabConf::SignalLength, JBB);
314   } else {
315     jam();
316     PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
317     ref->senderRef = reference();
318     ref->senderData = ss.m_req.senderData;
319     ref->tableId = ss.m_req.tableId;
320     ref->errorCode = ss.m_error;
321     sendSignal(dictRef, GSN_PREP_DROP_TAB_REF,
322                signal, PrepDropTabRef::SignalLength, JBB);
323   }
324 
325   ssRelease<Ss_PREP_DROP_TAB_REQ>(ssId);
326 }
327 
328 // GSN_DROP_TAB_REQ
329 
330 void
execDROP_TAB_REQ(Signal * signal)331 DbtcProxy::execDROP_TAB_REQ(Signal* signal)
332 {
333   const DropTabReq* req = (const DropTabReq*)signal->getDataPtr();
334   Uint32 ssId = getSsId(req);
335   Ss_DROP_TAB_REQ& ss = ssSeize<Ss_DROP_TAB_REQ>(ssId);
336   ss.m_req = *req;
337   ndbrequire(signal->getLength() == DropTabReq::SignalLength);
338   sendREQ(signal, ss);
339 }
340 
341 void
sendDROP_TAB_REQ(Signal * signal,Uint32 ssId,SectionHandle *)342 DbtcProxy::sendDROP_TAB_REQ(Signal* signal, Uint32 ssId, SectionHandle*)
343 {
344   Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
345 
346   DropTabReq* req = (DropTabReq*)signal->getDataPtrSend();
347   *req = ss.m_req;
348   req->senderRef = reference();
349   req->senderData = ssId; // redundant since tableId is used
350   sendSignal(workerRef(ss.m_worker), GSN_DROP_TAB_REQ,
351              signal, DropTabReq::SignalLength, JBB);
352 }
353 
354 void
execDROP_TAB_CONF(Signal * signal)355 DbtcProxy::execDROP_TAB_CONF(Signal* signal)
356 {
357   const DropTabConf* conf = (const DropTabConf*)signal->getDataPtr();
358   Uint32 ssId = getSsId(conf);
359   Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
360   recvCONF(signal, ss);
361 }
362 
363 void
execDROP_TAB_REF(Signal * signal)364 DbtcProxy::execDROP_TAB_REF(Signal* signal)
365 {
366   const DropTabRef* ref = (const DropTabRef*)signal->getDataPtr();
367   Uint32 ssId = getSsId(ref);
368   Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
369   recvREF(signal, ss, ref->errorCode);
370 }
371 
372 void
sendDROP_TAB_CONF(Signal * signal,Uint32 ssId)373 DbtcProxy::sendDROP_TAB_CONF(Signal* signal, Uint32 ssId)
374 {
375   Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
376   BlockReference dictRef = ss.m_req.senderRef;
377 
378   if (!lastReply(ss))
379     return;
380 
381   if (ss.m_error == 0) {
382     jam();
383     DropTabConf* conf = (DropTabConf*)signal->getDataPtrSend();
384     conf->senderRef = reference();
385     conf->senderData = ss.m_req.senderData;
386     conf->tableId = ss.m_req.tableId;
387     sendSignal(dictRef, GSN_DROP_TAB_CONF,
388                signal, DropTabConf::SignalLength, JBB);
389   } else {
390     jam();
391     DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
392     ref->senderRef = reference();
393     ref->senderData = ss.m_req.senderData;
394     ref->tableId = ss.m_req.tableId;
395     ref->errorCode = ss.m_error;
396     sendSignal(dictRef, GSN_DROP_TAB_REF,
397                signal, DropTabConf::SignalLength, JBB);
398   }
399 
400   ssRelease<Ss_DROP_TAB_REQ>(ssId);
401 }
402 
403 // GSN_ALTER_TAB_REQ
404 
405 void
execALTER_TAB_REQ(Signal * signal)406 DbtcProxy::execALTER_TAB_REQ(Signal* signal)
407 {
408   if (!assembleFragments(signal))
409   {
410     jam();
411     return;
412   }
413 
414   const AlterTabReq* req = (const AlterTabReq*)signal->getDataPtr();
415   Uint32 ssId = getSsId(req);
416   Ss_ALTER_TAB_REQ& ss = ssSeize<Ss_ALTER_TAB_REQ>(ssId);
417   ss.m_req = *req;
418 
419   SectionHandle handle(this, signal);
420   saveSections(ss, handle);
421 
422   sendREQ(signal, ss);
423 }
424 
425 void
sendALTER_TAB_REQ(Signal * signal,Uint32 ssId,SectionHandle * handle)426 DbtcProxy::sendALTER_TAB_REQ(Signal* signal, Uint32 ssId,
427                              SectionHandle* handle)
428 {
429   Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
430 
431   AlterTabReq* req = (AlterTabReq*)signal->getDataPtrSend();
432   *req = ss.m_req;
433   req->senderRef = reference();
434   req->senderData = ssId;
435   sendSignalNoRelease(workerRef(ss.m_worker), GSN_ALTER_TAB_REQ,
436                       signal, AlterTabReq::SignalLength, JBB, handle);
437 }
438 
439 void
execALTER_TAB_CONF(Signal * signal)440 DbtcProxy::execALTER_TAB_CONF(Signal* signal)
441 {
442   const AlterTabConf* conf = (const AlterTabConf*)signal->getDataPtr();
443   Uint32 ssId = getSsId(conf);
444   Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
445   recvCONF(signal, ss);
446 }
447 
448 void
execALTER_TAB_REF(Signal * signal)449 DbtcProxy::execALTER_TAB_REF(Signal* signal)
450 {
451   const AlterTabRef* ref = (const AlterTabRef*)signal->getDataPtr();
452   Uint32 ssId = getSsId(ref);
453   Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
454   recvREF(signal, ss, ref->errorCode);
455 }
456 
457 void
sendALTER_TAB_CONF(Signal * signal,Uint32 ssId)458 DbtcProxy::sendALTER_TAB_CONF(Signal* signal, Uint32 ssId)
459 {
460   Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
461   BlockReference dictRef = ss.m_req.senderRef;
462 
463   if (!lastReply(ss))
464     return;
465 
466   if (ss.m_error == 0) {
467     jam();
468     AlterTabConf* conf = (AlterTabConf*)signal->getDataPtrSend();
469     conf->senderRef = reference();
470     conf->senderData = ss.m_req.senderData;
471     sendSignal(dictRef, GSN_ALTER_TAB_CONF,
472                signal, AlterTabConf::SignalLength, JBB);
473   } else {
474     jam();
475     AlterTabRef* ref = (AlterTabRef*)signal->getDataPtrSend();
476     ref->senderRef = reference();
477     ref->senderData = ss.m_req.senderData;
478     ref->errorCode = ss.m_error;
479     sendSignal(dictRef, GSN_ALTER_TAB_REF,
480                signal, AlterTabConf::SignalLength, JBB);
481   }
482 
483   ssRelease<Ss_ALTER_TAB_REQ>(ssId);
484 }
485 
486 void
execTCSEIZEREQ(Signal * signal)487 DbtcProxy::execTCSEIZEREQ(Signal* signal)
488 {
489   jamEntry();
490 
491   if (signal->getLength() >= 3 && signal->theData[2] != 0)
492   {
493     /**
494      * Specific instance requested...
495      */
496     Uint32 instance = signal->theData[2];
497     if (instance >= c_workers)
498     {
499       jam();
500       Uint32 senderData = signal->theData[0];
501       Uint32 senderRef = signal->theData[1];
502       signal->theData[0] = senderData;
503       signal->theData[1] = 289;
504       sendSignal(senderRef, GSN_TCSEIZEREF, signal, 2, JBB);
505       return;
506     }
507 
508     sendSignal(workerRef(instance), GSN_TCSEIZEREQ, signal,
509                signal->getLength(), JBB);
510     return;
511   }
512 
513   signal->theData[2] = 1 + m_tc_seize_req_instance;
514   sendSignal(workerRef(m_tc_seize_req_instance), GSN_TCSEIZEREQ, signal,
515              signal->getLength(), JBB);
516   m_tc_seize_req_instance = (m_tc_seize_req_instance + 1) % c_workers;
517 }
518 
519 // GSN_TCGETOPSIZEREQ
520 
521 void
execTCGETOPSIZEREQ(Signal * signal)522 DbtcProxy::execTCGETOPSIZEREQ(Signal* signal)
523 {
524   Ss_TCGETOPSIZEREQ& ss = ssSeize<Ss_TCGETOPSIZEREQ>(1);
525 
526   ss.m_sum = 0;
527   memcpy(ss.m_req, signal->getDataPtr(), 2*4);
528   sendREQ(signal, ss);
529 }
530 
531 void
sendTCGETOPSIZEREQ(Signal * signal,Uint32 ssId,SectionHandle *)532 DbtcProxy::sendTCGETOPSIZEREQ(Signal* signal, Uint32 ssId, SectionHandle*)
533 {
534   Ss_TCGETOPSIZEREQ& ss = ssFind<Ss_TCGETOPSIZEREQ>(ssId);
535 
536   signal->theData[0] = ssId;
537   signal->theData[1] = reference();
538   sendSignal(workerRef(ss.m_worker), GSN_TCGETOPSIZEREQ,
539              signal, 2, JBB);
540 }
541 
542 void
execTCGETOPSIZECONF(Signal * signal)543 DbtcProxy::execTCGETOPSIZECONF(Signal* signal)
544 {
545   Uint32 ssId = signal->theData[0];
546   Ss_TCGETOPSIZEREQ& ss = ssFind<Ss_TCGETOPSIZEREQ>(ssId);
547   ss.m_sum += signal->theData[1];
548   recvCONF(signal, ss);
549 }
550 
551 void
sendTCGETOPSIZECONF(Signal * signal,Uint32 ssId)552 DbtcProxy::sendTCGETOPSIZECONF(Signal* signal, Uint32 ssId)
553 {
554   Ss_TCGETOPSIZEREQ& ss = ssFind<Ss_TCGETOPSIZEREQ>(ssId);
555 
556   if (!lastReply(ss))
557     return;
558 
559   signal->theData[0] = ss.m_req[0];
560   signal->theData[1] = ss.m_sum;
561   sendSignal(ss.m_req[1], GSN_TCGETOPSIZECONF,
562              signal, 2, JBB);
563 
564   ssRelease<Ss_TCGETOPSIZEREQ>(ssId);
565 }
566 
567 // GSN_TC_CLOPSIZEREQ
568 
569 void
execTC_CLOPSIZEREQ(Signal * signal)570 DbtcProxy::execTC_CLOPSIZEREQ(Signal* signal)
571 {
572   Ss_TC_CLOPSIZEREQ& ss = ssSeize<Ss_TC_CLOPSIZEREQ>(1);
573 
574   memcpy(ss.m_req, signal->getDataPtr(), 2*4);
575   sendREQ(signal, ss);
576 }
577 
578 void
sendTC_CLOPSIZEREQ(Signal * signal,Uint32 ssId,SectionHandle *)579 DbtcProxy::sendTC_CLOPSIZEREQ(Signal* signal, Uint32 ssId, SectionHandle*)
580 {
581   Ss_TC_CLOPSIZEREQ& ss = ssFind<Ss_TC_CLOPSIZEREQ>(ssId);
582 
583   signal->theData[0] = ssId;
584   signal->theData[1] = reference();
585   sendSignal(workerRef(ss.m_worker), GSN_TC_CLOPSIZEREQ,
586              signal, 2, JBB);
587 }
588 
589 void
execTC_CLOPSIZECONF(Signal * signal)590 DbtcProxy::execTC_CLOPSIZECONF(Signal* signal)
591 {
592   Uint32 ssId = signal->theData[0];
593   Ss_TC_CLOPSIZEREQ& ss = ssFind<Ss_TC_CLOPSIZEREQ>(ssId);
594   recvCONF(signal, ss);
595 }
596 
597 void
sendTC_CLOPSIZECONF(Signal * signal,Uint32 ssId)598 DbtcProxy::sendTC_CLOPSIZECONF(Signal* signal, Uint32 ssId)
599 {
600   Ss_TC_CLOPSIZEREQ& ss = ssFind<Ss_TC_CLOPSIZEREQ>(ssId);
601 
602   if (!lastReply(ss))
603     return;
604 
605   signal->theData[0] = ss.m_req[0];
606   sendSignal(ss.m_req[1], GSN_TC_CLOPSIZECONF,
607              signal, 1, JBB);
608 
609   ssRelease<Ss_TC_CLOPSIZEREQ>(ssId);
610 }
611 
612 // GSN_GCP_NOMORETRANS
613 
614 void
execGCP_NOMORETRANS(Signal * signal)615 DbtcProxy::execGCP_NOMORETRANS(Signal* signal)
616 {
617   Ss_GCP_NOMORETRANS& ss = ssSeize<Ss_GCP_NOMORETRANS>(1);
618 
619   ss.m_req = *(GCPNoMoreTrans*)signal->getDataPtr();
620   sendREQ(signal, ss);
621 }
622 
623 void
sendGCP_NOMORETRANS(Signal * signal,Uint32 ssId,SectionHandle *)624 DbtcProxy::sendGCP_NOMORETRANS(Signal* signal, Uint32 ssId, SectionHandle*)
625 {
626   Ss_GCP_NOMORETRANS& ss = ssFind<Ss_GCP_NOMORETRANS>(ssId);
627 
628   GCPNoMoreTrans * req = (GCPNoMoreTrans*)signal->getDataPtrSend();
629   req->senderRef = reference();
630   req->senderData = ssId;
631   req->gci_hi = ss.m_req.gci_hi;
632   req->gci_lo = ss.m_req.gci_lo;
633   sendSignal(workerRef(ss.m_worker), GSN_GCP_NOMORETRANS,
634              signal, GCPNoMoreTrans::SignalLength, JBB);
635 }
636 
637 void
execGCP_TCFINISHED(Signal * signal)638 DbtcProxy::execGCP_TCFINISHED(Signal* signal)
639 {
640   GCPTCFinished* conf = (GCPTCFinished*)signal->getDataPtr();
641   Uint32 ssId = conf->senderData;
642   Ss_GCP_NOMORETRANS& ss = ssFind<Ss_GCP_NOMORETRANS>(ssId);
643   recvCONF(signal, ss);
644 }
645 
646 void
sendGCP_TCFINISHED(Signal * signal,Uint32 ssId)647 DbtcProxy::sendGCP_TCFINISHED(Signal* signal, Uint32 ssId)
648 {
649   Ss_GCP_NOMORETRANS& ss = ssFind<Ss_GCP_NOMORETRANS>(ssId);
650 
651   if (!lastReply(ss))
652     return;
653 
654   GCPTCFinished* conf = (GCPTCFinished*)signal->getDataPtrSend();
655   conf->senderData = ss.m_req.senderData;
656   conf->gci_hi = ss.m_req.gci_hi;
657   conf->gci_lo = ss.m_req.gci_lo;
658   sendSignal(ss.m_req.senderRef, GSN_GCP_TCFINISHED,
659              signal, GCPTCFinished::SignalLength, JBB);
660 
661   ssRelease<Ss_GCP_NOMORETRANS>(ssId);
662 }
663 
664 
665 // GSN_API_FAILREQ
666 
667 void
execAPI_FAILREQ(Signal * signal)668 DbtcProxy::execAPI_FAILREQ(Signal* signal)
669 {
670   Uint32 nodeId = signal->theData[0];
671   Ss_API_FAILREQ& ss = ssSeize<Ss_API_FAILREQ>(nodeId);
672 
673   ss.m_ref = signal->theData[1];
674   sendREQ(signal, ss);
675 }
676 
677 void
sendAPI_FAILREQ(Signal * signal,Uint32 ssId,SectionHandle *)678 DbtcProxy::sendAPI_FAILREQ(Signal* signal, Uint32 ssId, SectionHandle*)
679 {
680   Ss_API_FAILREQ& ss = ssFind<Ss_API_FAILREQ>(ssId);
681 
682   signal->theData[0] = ssId;
683   signal->theData[1] = reference();
684   sendSignal(workerRef(ss.m_worker), GSN_API_FAILREQ,
685              signal, 2, JBB);
686 }
687 
688 void
execAPI_FAILCONF(Signal * signal)689 DbtcProxy::execAPI_FAILCONF(Signal* signal)
690 {
691   Uint32 nodeId = signal->theData[0];
692   Ss_API_FAILREQ& ss = ssFind<Ss_API_FAILREQ>(nodeId);
693   recvCONF(signal, ss);
694 }
695 
696 void
sendAPI_FAILCONF(Signal * signal,Uint32 ssId)697 DbtcProxy::sendAPI_FAILCONF(Signal* signal, Uint32 ssId)
698 {
699   Ss_API_FAILREQ& ss = ssFind<Ss_API_FAILREQ>(ssId);
700 
701   if (!lastReply(ss))
702     return;
703 
704   signal->theData[0] = ssId;
705   signal->theData[1] = calcTcBlockRef(getOwnNodeId());
706   sendSignal(ss.m_ref, GSN_API_FAILCONF,
707              signal, 2, JBB);
708 
709   ssRelease<Ss_API_FAILREQ>(ssId);
710 }
711 
712 // GSN_CREATE_INDX_IMPL_REQ
713 
714 void
execCREATE_INDX_IMPL_REQ(Signal * signal)715 DbtcProxy::execCREATE_INDX_IMPL_REQ(Signal* signal)
716 {
717   jamEntry();
718   if (!assembleFragments(signal))
719   {
720     jam();
721     return;
722   }
723 
724   const CreateIndxImplReq* req = (const CreateIndxImplReq*)signal->getDataPtr();
725   Ss_CREATE_INDX_IMPL_REQ& ss = ssSeize<Ss_CREATE_INDX_IMPL_REQ>();
726   ss.m_req = *req;
727   SectionHandle handle(this, signal);
728   saveSections(ss, handle);
729   sendREQ(signal, ss);
730 }
731 
732 void
sendCREATE_INDX_IMPL_REQ(Signal * signal,Uint32 ssId,SectionHandle * handle)733 DbtcProxy::sendCREATE_INDX_IMPL_REQ(Signal* signal, Uint32 ssId,
734                                     SectionHandle * handle)
735 {
736   Ss_CREATE_INDX_IMPL_REQ& ss = ssFind<Ss_CREATE_INDX_IMPL_REQ>(ssId);
737 
738   CreateIndxImplReq* req = (CreateIndxImplReq*)signal->getDataPtrSend();
739   *req = ss.m_req;
740   req->senderRef = reference();
741   req->senderData = ssId;
742   sendSignalNoRelease(workerRef(ss.m_worker), GSN_CREATE_INDX_IMPL_REQ,
743                       signal, CreateIndxImplReq::SignalLength, JBB,
744                       handle);
745 }
746 
747 void
execCREATE_INDX_IMPL_CONF(Signal * signal)748 DbtcProxy::execCREATE_INDX_IMPL_CONF(Signal* signal)
749 {
750   const CreateIndxImplConf* conf = (const CreateIndxImplConf*)signal->getDataPtr();
751   Uint32 ssId = conf->senderData;
752   Ss_CREATE_INDX_IMPL_REQ& ss = ssFind<Ss_CREATE_INDX_IMPL_REQ>(ssId);
753   recvCONF(signal, ss);
754 }
755 
756 void
execCREATE_INDX_IMPL_REF(Signal * signal)757 DbtcProxy::execCREATE_INDX_IMPL_REF(Signal* signal)
758 {
759   const CreateIndxImplRef* ref = (const CreateIndxImplRef*)signal->getDataPtr();
760   Uint32 ssId = ref->senderData;
761   Ss_CREATE_INDX_IMPL_REQ& ss = ssFind<Ss_CREATE_INDX_IMPL_REQ>(ssId);
762   recvREF(signal, ss, ref->errorCode);
763 }
764 
765 void
sendCREATE_INDX_IMPL_CONF(Signal * signal,Uint32 ssId)766 DbtcProxy::sendCREATE_INDX_IMPL_CONF(Signal* signal, Uint32 ssId)
767 {
768   Ss_CREATE_INDX_IMPL_REQ& ss = ssFind<Ss_CREATE_INDX_IMPL_REQ>(ssId);
769   BlockReference dictRef = ss.m_req.senderRef;
770 
771   if (!lastReply(ss))
772     return;
773 
774   if (ss.m_error == 0) {
775     jam();
776     CreateIndxImplConf* conf = (CreateIndxImplConf*)signal->getDataPtrSend();
777     conf->senderRef = reference();
778     conf->senderData = ss.m_req.senderData;
779     sendSignal(dictRef, GSN_CREATE_INDX_IMPL_CONF,
780                signal, CreateIndxImplConf::SignalLength, JBB);
781   } else {
782     CreateIndxImplRef* ref = (CreateIndxImplRef*)signal->getDataPtrSend();
783     ref->senderRef = reference();
784     ref->senderData = ss.m_req.senderData;
785     ref->errorCode = ss.m_error;
786     sendSignal(dictRef, GSN_CREATE_INDX_IMPL_REF,
787                signal, CreateIndxImplRef::SignalLength, JBB);
788   }
789 
790   ssRelease<Ss_CREATE_INDX_IMPL_REQ>(ssId);
791 }
792 
793 // GSN_ALTER_INDX_IMPL_REQ
794 
795 void
execALTER_INDX_IMPL_REQ(Signal * signal)796 DbtcProxy::execALTER_INDX_IMPL_REQ(Signal* signal)
797 {
798   const AlterIndxImplReq* req = (const AlterIndxImplReq*)signal->getDataPtr();
799   Ss_ALTER_INDX_IMPL_REQ& ss = ssSeize<Ss_ALTER_INDX_IMPL_REQ>();
800   ss.m_req = *req;
801   ndbrequire(signal->getLength() == AlterIndxImplReq::SignalLength);
802   sendREQ(signal, ss);
803 }
804 
805 void
sendALTER_INDX_IMPL_REQ(Signal * signal,Uint32 ssId,SectionHandle *)806 DbtcProxy::sendALTER_INDX_IMPL_REQ(Signal* signal, Uint32 ssId, SectionHandle*)
807 {
808   Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
809 
810   AlterIndxImplReq* req = (AlterIndxImplReq*)signal->getDataPtrSend();
811   *req = ss.m_req;
812   req->senderRef = reference();
813   req->senderData = ssId;
814   sendSignal(workerRef(ss.m_worker), GSN_ALTER_INDX_IMPL_REQ,
815              signal, AlterIndxImplReq::SignalLength, JBB);
816 }
817 
818 void
execALTER_INDX_IMPL_CONF(Signal * signal)819 DbtcProxy::execALTER_INDX_IMPL_CONF(Signal* signal)
820 {
821   const AlterIndxImplConf* conf = (const AlterIndxImplConf*)signal->getDataPtr();
822   Uint32 ssId = conf->senderData;
823   Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
824   recvCONF(signal, ss);
825 }
826 
827 void
execALTER_INDX_IMPL_REF(Signal * signal)828 DbtcProxy::execALTER_INDX_IMPL_REF(Signal* signal)
829 {
830   const AlterIndxImplRef* ref = (const AlterIndxImplRef*)signal->getDataPtr();
831   Uint32 ssId = ref->senderData;
832   Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
833   recvREF(signal, ss, ref->errorCode);
834 }
835 
836 void
sendALTER_INDX_IMPL_CONF(Signal * signal,Uint32 ssId)837 DbtcProxy::sendALTER_INDX_IMPL_CONF(Signal* signal, Uint32 ssId)
838 {
839   Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
840   BlockReference dictRef = ss.m_req.senderRef;
841 
842   if (!lastReply(ss))
843     return;
844 
845   if (ss.m_error == 0) {
846     jam();
847     AlterIndxImplConf* conf = (AlterIndxImplConf*)signal->getDataPtrSend();
848     conf->senderRef = reference();
849     conf->senderData = ss.m_req.senderData;
850     sendSignal(dictRef, GSN_ALTER_INDX_IMPL_CONF,
851                signal, AlterIndxImplConf::SignalLength, JBB);
852   } else {
853     AlterIndxImplRef* ref = (AlterIndxImplRef*)signal->getDataPtrSend();
854     ref->senderRef = reference();
855     ref->senderData = ss.m_req.senderData;
856     ref->errorCode = ss.m_error;
857     sendSignal(dictRef, GSN_ALTER_INDX_IMPL_REF,
858                signal, AlterIndxImplRef::SignalLength, JBB);
859   }
860 
861   ssRelease<Ss_ALTER_INDX_IMPL_REQ>(ssId);
862 }
863 
864 // GSN_DROP_INDX_IMPL_REQ
865 
866 void
execDROP_INDX_IMPL_REQ(Signal * signal)867 DbtcProxy::execDROP_INDX_IMPL_REQ(Signal* signal)
868 {
869   const DropIndxImplReq* req = (const DropIndxImplReq*)signal->getDataPtr();
870   Ss_DROP_INDX_IMPL_REQ& ss = ssSeize<Ss_DROP_INDX_IMPL_REQ>();
871   ss.m_req = *req;
872   ndbrequire(signal->getLength() == DropIndxImplReq::SignalLength);
873   sendREQ(signal, ss);
874 }
875 
876 void
sendDROP_INDX_IMPL_REQ(Signal * signal,Uint32 ssId,SectionHandle *)877 DbtcProxy::sendDROP_INDX_IMPL_REQ(Signal* signal, Uint32 ssId, SectionHandle*)
878 {
879   Ss_DROP_INDX_IMPL_REQ& ss = ssFind<Ss_DROP_INDX_IMPL_REQ>(ssId);
880 
881   DropIndxImplReq* req = (DropIndxImplReq*)signal->getDataPtrSend();
882   *req = ss.m_req;
883   req->senderRef = reference();
884   req->senderData = ssId;
885   sendSignal(workerRef(ss.m_worker), GSN_DROP_INDX_IMPL_REQ,
886              signal, DropIndxImplReq::SignalLength, JBB);
887 }
888 
889 void
execDROP_INDX_IMPL_CONF(Signal * signal)890 DbtcProxy::execDROP_INDX_IMPL_CONF(Signal* signal)
891 {
892   const DropIndxImplConf* conf = (const DropIndxImplConf*)signal->getDataPtr();
893   Uint32 ssId = conf->senderData;
894   Ss_DROP_INDX_IMPL_REQ& ss = ssFind<Ss_DROP_INDX_IMPL_REQ>(ssId);
895   recvCONF(signal, ss);
896 }
897 
898 void
execDROP_INDX_IMPL_REF(Signal * signal)899 DbtcProxy::execDROP_INDX_IMPL_REF(Signal* signal)
900 {
901   const DropIndxImplRef* ref = (const DropIndxImplRef*)signal->getDataPtr();
902   Uint32 ssId = ref->senderData;
903   Ss_DROP_INDX_IMPL_REQ& ss = ssFind<Ss_DROP_INDX_IMPL_REQ>(ssId);
904   recvREF(signal, ss, ref->errorCode);
905 }
906 
907 void
sendDROP_INDX_IMPL_CONF(Signal * signal,Uint32 ssId)908 DbtcProxy::sendDROP_INDX_IMPL_CONF(Signal* signal, Uint32 ssId)
909 {
910   Ss_DROP_INDX_IMPL_REQ& ss = ssFind<Ss_DROP_INDX_IMPL_REQ>(ssId);
911   BlockReference dictRef = ss.m_req.senderRef;
912 
913   if (!lastReply(ss))
914     return;
915 
916   if (ss.m_error == 0) {
917     jam();
918     DropIndxImplConf* conf = (DropIndxImplConf*)signal->getDataPtrSend();
919     conf->senderRef = reference();
920     conf->senderData = ss.m_req.senderData;
921     sendSignal(dictRef, GSN_DROP_INDX_IMPL_CONF,
922                signal, DropIndxImplConf::SignalLength, JBB);
923   } else {
924     DropIndxImplRef* ref = (DropIndxImplRef*)signal->getDataPtrSend();
925     ref->senderRef = reference();
926     ref->senderData = ss.m_req.senderData;
927     ref->errorCode = ss.m_error;
928     sendSignal(dictRef, GSN_DROP_INDX_IMPL_REF,
929                signal, DropIndxImplRef::SignalLength, JBB);
930   }
931 
932   ssRelease<Ss_DROP_INDX_IMPL_REQ>(ssId);
933 }
934 
935 void
execTAKE_OVERTCCONF(Signal * signal)936 DbtcProxy::execTAKE_OVERTCCONF(Signal* signal)
937 {
938   jamEntry();
939 
940   if (!checkNodeFailSequence(signal))
941   {
942     jam();
943     return;
944   }
945 
946   for (Uint32 i = 0; i < c_workers; i++)
947   {
948     jam();
949     Uint32 ref = numberToRef(number(), workerInstance(i), getOwnNodeId());
950     sendSignal(ref, GSN_TAKE_OVERTCCONF, signal,
951                signal->getLength(),
952                JBB);
953   }
954 }
955 
956 BLOCK_FUNCTIONS(DbtcProxy)
957