1 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
22 
23 #include "DbtuxProxy.hpp"
24 #include "Dbtux.hpp"
25 #include "../dblqh/DblqhCommon.hpp"
26 
DbtuxProxy(Block_context & ctx)27 DbtuxProxy::DbtuxProxy(Block_context& ctx) :
28   LocalProxy(DBTUX, ctx)
29 {
30   // GSN_ALTER_INDX_IMPL_REQ
31   addRecSignal(GSN_ALTER_INDX_IMPL_REQ, &DbtuxProxy::execALTER_INDX_IMPL_REQ);
32   addRecSignal(GSN_ALTER_INDX_IMPL_CONF, &DbtuxProxy::execALTER_INDX_IMPL_CONF);
33   addRecSignal(GSN_ALTER_INDX_IMPL_REF, &DbtuxProxy::execALTER_INDX_IMPL_REF);
34 
35   // GSN_INDEX_STAT_IMPL_REQ
36   addRecSignal(GSN_INDEX_STAT_IMPL_REQ, &DbtuxProxy::execINDEX_STAT_IMPL_REQ);
37   addRecSignal(GSN_INDEX_STAT_IMPL_CONF, &DbtuxProxy::execINDEX_STAT_IMPL_CONF);
38   addRecSignal(GSN_INDEX_STAT_IMPL_REF, &DbtuxProxy::execINDEX_STAT_IMPL_REF);
39 
40   // GSN_INDEX_STAT_REP
41   addRecSignal(GSN_INDEX_STAT_REP, &DbtuxProxy::execINDEX_STAT_REP);
42 }
43 
~DbtuxProxy()44 DbtuxProxy::~DbtuxProxy()
45 {
46 }
47 
48 SimulatedBlock*
newWorker(Uint32 instanceNo)49 DbtuxProxy::newWorker(Uint32 instanceNo)
50 {
51   return new Dbtux(m_ctx, instanceNo);
52 }
53 
54 // GSN_ALTER_INDX_IMPL_REQ
55 
56 void
execALTER_INDX_IMPL_REQ(Signal * signal)57 DbtuxProxy::execALTER_INDX_IMPL_REQ(Signal* signal)
58 {
59   const AlterIndxImplReq* req = (const AlterIndxImplReq*)signal->getDataPtr();
60   Ss_ALTER_INDX_IMPL_REQ& ss = ssSeize<Ss_ALTER_INDX_IMPL_REQ>();
61   ss.m_req = *req;
62   ndbrequire(signal->getLength() == AlterIndxImplReq::SignalLength);
63   sendREQ(signal, ss);
64 }
65 
66 void
sendALTER_INDX_IMPL_REQ(Signal * signal,Uint32 ssId,SectionHandle * handle)67 DbtuxProxy::sendALTER_INDX_IMPL_REQ(Signal* signal, Uint32 ssId,
68                                     SectionHandle * handle)
69 {
70   Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
71 
72   AlterIndxImplReq* req = (AlterIndxImplReq*)signal->getDataPtrSend();
73   *req = ss.m_req;
74   req->senderRef = reference();
75   req->senderData = ssId;
76   sendSignalNoRelease(workerRef(ss.m_worker), GSN_ALTER_INDX_IMPL_REQ,
77                       signal, AlterIndxImplReq::SignalLength, JBB, handle);
78 }
79 
80 void
execALTER_INDX_IMPL_CONF(Signal * signal)81 DbtuxProxy::execALTER_INDX_IMPL_CONF(Signal* signal)
82 {
83   const AlterIndxImplConf* conf = (const AlterIndxImplConf*)signal->getDataPtr();
84   Uint32 ssId = conf->senderData;
85   Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
86   recvCONF(signal, ss);
87 }
88 
89 void
execALTER_INDX_IMPL_REF(Signal * signal)90 DbtuxProxy::execALTER_INDX_IMPL_REF(Signal* signal)
91 {
92   const AlterIndxImplRef* ref = (const AlterIndxImplRef*)signal->getDataPtr();
93   Uint32 ssId = ref->senderData;
94   Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
95   recvREF(signal, ss, ref->errorCode);
96 }
97 
98 void
sendALTER_INDX_IMPL_CONF(Signal * signal,Uint32 ssId)99 DbtuxProxy::sendALTER_INDX_IMPL_CONF(Signal* signal, Uint32 ssId)
100 {
101   Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
102   BlockReference dictRef = ss.m_req.senderRef;
103 
104   if (!lastReply(ss))
105     return;
106 
107   if (ss.m_error == 0) {
108     jam();
109     AlterIndxImplConf* conf = (AlterIndxImplConf*)signal->getDataPtrSend();
110     conf->senderRef = reference();
111     conf->senderData = ss.m_req.senderData;
112     sendSignal(dictRef, GSN_ALTER_INDX_IMPL_CONF,
113                signal, AlterIndxImplConf::SignalLength, JBB);
114   } else {
115     AlterIndxImplRef* ref = (AlterIndxImplRef*)signal->getDataPtrSend();
116     ref->senderRef = reference();
117     ref->senderData = ss.m_req.senderData;
118     ref->errorCode = ss.m_error;
119     sendSignal(dictRef, GSN_ALTER_INDX_IMPL_REF,
120                signal, AlterIndxImplRef::SignalLength, JBB);
121   }
122 
123   ssRelease<Ss_ALTER_INDX_IMPL_REQ>(ssId);
124 }
125 
126 // GSN_INDEX_STAT_IMPL_REQ
127 
128 void
execINDEX_STAT_IMPL_REQ(Signal * signal)129 DbtuxProxy::execINDEX_STAT_IMPL_REQ(Signal* signal)
130 {
131   jamEntry();
132   const IndexStatImplReq* req =
133     (const IndexStatImplReq*)signal->getDataPtr();
134   Ss_INDEX_STAT_IMPL_REQ& ss = ssSeize<Ss_INDEX_STAT_IMPL_REQ>();
135   ss.m_req = *req;
136   ndbrequire(signal->getLength() == IndexStatImplReq::SignalLength);
137   sendREQ(signal, ss);
138 }
139 
140 void
sendINDEX_STAT_IMPL_REQ(Signal * signal,Uint32 ssId,SectionHandle *)141 DbtuxProxy::sendINDEX_STAT_IMPL_REQ(Signal* signal, Uint32 ssId,
142                                     SectionHandle*)
143 {
144   Ss_INDEX_STAT_IMPL_REQ& ss = ssFind<Ss_INDEX_STAT_IMPL_REQ>(ssId);
145 
146   IndexStatImplReq* req = (IndexStatImplReq*)signal->getDataPtrSend();
147   *req = ss.m_req;
148   req->senderRef = reference();
149   req->senderData = ssId;
150 
151   const Uint32 instance = workerInstance(ss.m_worker);
152   NdbLogPartInfo lpinfo(instance);
153 
154   //XXX remove unused
155   switch (req->requestType) {
156   case IndexStatReq::RT_START_MON:
157     /*
158      * DICT sets fragId if assigned frag is on this node, or else ZNIL
159      * to turn off any possible old assignment.  In MT-LQH we also have
160      * to check which worker owns the frag.
161      */
162     if (req->fragId != ZNIL
163         && !lpinfo.partNoOwner(req->indexId, req->fragId)) {
164       jam();
165       req->fragId = ZNIL;
166     }
167     break;
168   case IndexStatReq::RT_STOP_MON:
169     /*
170      * DICT sets fragId to ZNIL always.  There is no (pointless) check
171      * to see if the frag was ever assigned.
172      */
173     ndbrequire(req->fragId == ZNIL);
174     break;
175   case IndexStatReq::RT_SCAN_FRAG:
176     ndbrequire(req->fragId != ZNIL);
177     if (!lpinfo.partNoOwner(req->indexId, req->fragId)) {
178       jam();
179       skipReq(ss);
180       return;
181     }
182     break;
183   case IndexStatReq::RT_CLEAN_NEW:
184   case IndexStatReq::RT_CLEAN_OLD:
185   case IndexStatReq::RT_CLEAN_ALL:
186     ndbrequire(req->fragId == ZNIL);
187     break;
188   case IndexStatReq::RT_DROP_HEAD:
189     /*
190      * Only one client can do the PK-delete of the head record.  We use
191      * of course the worker which owns the assigned fragment.
192      */
193     ndbrequire(req->fragId != ZNIL);
194     if (!lpinfo.partNoOwner(req->indexId, req->fragId)) {
195       jam();
196       skipReq(ss);
197       return;
198     }
199     break;
200   default:
201     ndbrequire(false);
202     break;
203   }
204 
205   sendSignal(workerRef(ss.m_worker), GSN_INDEX_STAT_IMPL_REQ,
206              signal, IndexStatImplReq::SignalLength, JBB);
207 }
208 
209 void
execINDEX_STAT_IMPL_CONF(Signal * signal)210 DbtuxProxy::execINDEX_STAT_IMPL_CONF(Signal* signal)
211 {
212   jamEntry();
213   const IndexStatImplConf* conf =
214     (const IndexStatImplConf*)signal->getDataPtr();
215   Uint32 ssId = conf->senderData;
216   Ss_INDEX_STAT_IMPL_REQ& ss = ssFind<Ss_INDEX_STAT_IMPL_REQ>(ssId);
217   recvCONF(signal, ss);
218 }
219 
220 void
execINDEX_STAT_IMPL_REF(Signal * signal)221 DbtuxProxy::execINDEX_STAT_IMPL_REF(Signal* signal)
222 {
223   jamEntry();
224   const IndexStatImplRef* ref = (const IndexStatImplRef*)signal->getDataPtr();
225   Uint32 ssId = ref->senderData;
226   Ss_INDEX_STAT_IMPL_REQ& ss = ssFind<Ss_INDEX_STAT_IMPL_REQ>(ssId);
227   recvREF(signal, ss, ref->errorCode);
228 }
229 
230 void
sendINDEX_STAT_IMPL_CONF(Signal * signal,Uint32 ssId)231 DbtuxProxy::sendINDEX_STAT_IMPL_CONF(Signal* signal, Uint32 ssId)
232 {
233   Ss_INDEX_STAT_IMPL_REQ& ss = ssFind<Ss_INDEX_STAT_IMPL_REQ>(ssId);
234   BlockReference dictRef = ss.m_req.senderRef;
235 
236   if (!lastReply(ss))
237     return;
238 
239   if (ss.m_error == 0) {
240     jam();
241     IndexStatImplConf* conf = (IndexStatImplConf*)signal->getDataPtrSend();
242     conf->senderRef = reference();
243     conf->senderData = ss.m_req.senderData;
244     sendSignal(dictRef, GSN_INDEX_STAT_IMPL_CONF,
245                signal, IndexStatImplConf::SignalLength, JBB);
246   } else {
247     IndexStatImplRef* ref = (IndexStatImplRef*)signal->getDataPtrSend();
248     ref->senderRef = reference();
249     ref->senderData = ss.m_req.senderData;
250     ref->errorCode = ss.m_error;
251     sendSignal(dictRef, GSN_INDEX_STAT_IMPL_REF,
252                signal, IndexStatImplRef::SignalLength, JBB);
253   }
254 
255   ssRelease<Ss_INDEX_STAT_IMPL_REQ>(ssId);
256 }
257 
258 // GSN_INDEX_STAT_REP
259 
260 void
execINDEX_STAT_REP(Signal * signal)261 DbtuxProxy::execINDEX_STAT_REP(Signal* signal)
262 {
263   jamEntry();
264   const IndexStatRep* rep =
265     (const IndexStatRep*)signal->getDataPtr();
266   Ss_INDEX_STAT_REP& ss = ssSeize<Ss_INDEX_STAT_REP>();
267   ss.m_rep = *rep;
268   ndbrequire(signal->getLength() == IndexStatRep::SignalLength);
269   sendREQ(signal, ss);
270   ssRelease<Ss_INDEX_STAT_REP>(ss);
271 }
272 
273 void
sendINDEX_STAT_REP(Signal * signal,Uint32 ssId,SectionHandle *)274 DbtuxProxy::sendINDEX_STAT_REP(Signal* signal, Uint32 ssId,
275                                SectionHandle*)
276 {
277   Ss_INDEX_STAT_REP& ss = ssFind<Ss_INDEX_STAT_REP>(ssId);
278 
279   IndexStatRep* rep = (IndexStatRep*)signal->getDataPtrSend();
280   *rep = ss.m_rep;
281   rep->senderData = reference();
282   rep->senderData = ssId;
283 
284   const Uint32 instance = workerInstance(ss.m_worker);
285   NdbLogPartInfo lpinfo(instance);
286 
287   ndbrequire(rep->fragId != ZNIL);
288   if (!lpinfo.partNoOwner(rep->indexId, rep->fragId)) {
289     jam();
290     skipReq(ss);
291     return;
292   }
293 
294   sendSignal(workerRef(ss.m_worker), GSN_INDEX_STAT_REP,
295              signal, IndexStatRep::SignalLength, JBB);
296 }
297 
298 BLOCK_FUNCTIONS(DbtuxProxy)
299