MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SCI_Transporter.cpp
1 /*
2  Copyright (C) 2003-2008 MySQL AB, 2008 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <ndb_global.h>
20 
21 #include "SCI_Transporter.hpp"
22 #include <NdbOut.hpp>
23 #include <NdbSleep.h>
24 #include <NdbTick.h>
25 #include <NdbTick.h>
26 
27 #include "TransporterInternalDefinitions.hpp"
28 #include <TransporterCallback.hpp>
29 
30 #include <InputStream.hpp>
31 #include <OutputStream.hpp>
32 
33 #define FLAGS 0
34 #define DEBUG_TRANSPORTER
35 SCI_Transporter::SCI_Transporter(TransporterRegistry &t_reg,
36  const char *lHostName,
37  const char *rHostName,
38  int r_port,
39  bool isMgmConnection,
40  Uint32 packetSize,
41  Uint32 bufferSize,
42  Uint32 nAdapters,
43  Uint16 remoteSciNodeId0,
44  Uint16 remoteSciNodeId1,
45  NodeId _localNodeId,
46  NodeId _remoteNodeId,
47  NodeId serverNodeId,
48  bool chksm,
49  bool signalId,
50  Uint32 reportFreq) :
51  Transporter(t_reg, tt_SCI_TRANSPORTER,
52  lHostName, rHostName, r_port, isMgmConnection, _localNodeId,
53  _remoteNodeId, serverNodeId, 0, false, chksm, signalId,
54  4 * ((packetSize + 3)/4) + MAX_MESSAGE_SIZE)
55 {
56  DBUG_ENTER("SCI_Transporter::SCI_Transporter");
57  m_PacketSize = (packetSize + 3)/4 ;
58  m_BufferSize = bufferSize;
59 
60  m_RemoteSciNodeId = remoteSciNodeId0;
61 
62  if(remoteSciNodeId0 == 0 || remoteSciNodeId1 == 0)
63  m_numberOfRemoteNodes=1;
64  else
65  m_numberOfRemoteNodes=2;
66 
67  m_RemoteSciNodeId1 = remoteSciNodeId1;
68 
69 
70  m_initLocal=false;
71  m_failCounter=0;
72  m_remoteNodes[0]=remoteSciNodeId0;
73  m_remoteNodes[1]=remoteSciNodeId1;
74  m_adapters = nAdapters;
75  m_ActiveAdapterId=0;
76  m_StandbyAdapterId=1;
77 
78  m_mapped = false;
79  m_sciinit=false;
80 
81  sciAdapters= new SciAdapter[nAdapters* (sizeof (SciAdapter))];
82  if(sciAdapters==NULL) {
83  }
84  m_SourceSegm= new sourceSegm[nAdapters* (sizeof (sourceSegm))];
85  if(m_SourceSegm==NULL) {
86  }
87  m_TargetSegm= new targetSegm[nAdapters* (sizeof (targetSegm))];
88  if(m_TargetSegm==NULL) {
89  }
90  m_reportFreq= reportFreq;
91 
92  //reset all statistic counters.
93 #ifdef DEBUG_TRANSPORTER
94  i1024=0;
95  i2048=0;
96  i2049=0;
97  i10242048=0;
98  i20484096=0;
99  i4096=0;
100  i4097=0;
101 #endif
102  DBUG_VOID_RETURN;
103 }
104 
105 
106 bool
107 SCI_Transporter::configure_derived(const TransporterConfiguration* conf)
108 {
109  if (conf->sci.sendLimit == (m_PacketSize + 3)/4 &&
110  conf->sci.bufferSize == m_buffersize &&
111  conf->sci.nLocalAdapters == m_adapters &&
112  conf->sci.remoteSciNodeId0 == m_remoteNodes[0] &&
113  conf->sci.remoteSciNodeId1 == m_remoteNodes[1])
114  return true; // No change
115  return false; // Can't reconfigure
116 }
117 
118 
120 {
121  DBUG_ENTER("SCI_Transporter::disconnectImpl");
122  sci_error_t err;
123  if(m_mapped){
124  setDisconnect();
125  DBUG_PRINT("info", ("connect status = %d, remote node = %d",
126  (int)getConnectionStatus(), remoteNodeId));
127  disconnectRemote();
128  disconnectLocal();
129  }
130 
131  m_initLocal=false;
132  m_mapped = false;
133 
134  if(m_sciinit) {
135  for(Uint32 i=0; i<m_adapters ; i++) {
136  SCIClose(sciAdapters[i].scidesc, FLAGS, &err);
137 
138  if(err != SCI_ERR_OK) {
139  report_error(TE_SCI_UNABLE_TO_CLOSE_CHANNEL);
140  DBUG_PRINT("error",
141  ("Cannot close channel to the driver. Error code 0x%x",
142  err));
143  }
144  }
145  }
146  m_sciinit=false;
147 
148 #ifdef DEBUG_TRANSPORTER
149  ndbout << "total: " << i1024+ i10242048 + i2048+i2049 << endl;
150  ndbout << "<1024: " << i1024 << endl;
151  ndbout << "1024-2047: " << i10242048 << endl;
152  ndbout << "==2048: " << i2048 << endl;
153  ndbout << "2049-4096: " << i20484096 << endl;
154  ndbout << "==4096: " << i4096 << endl;
155  ndbout << ">4096: " << i4097 << endl;
156 #endif
157  DBUG_VOID_RETURN;
158 }
159 
160 
162  DBUG_ENTER("SCI_Transporter::initTransporter");
163  if(m_BufferSize < (2*MAX_MESSAGE_SIZE + 4096)){
164  m_BufferSize = 2 * MAX_MESSAGE_SIZE + 4096;
165  }
166 
167  DBUG_PRINT("info", ("SCI packet size %d", m_PacketSize * 4));
168  if(!getLinkStatus(m_ActiveAdapterId) ||
169  (m_adapters > 1 &&
170  !getLinkStatus(m_StandbyAdapterId))) {
171  DBUG_PRINT("error",
172  ("The link is not fully operational. Check the cables and the switches"));
173  //NDB should terminate
174  report_error(TE_SCI_LINK_ERROR);
175  DBUG_RETURN(false);
176  }
177  DBUG_RETURN(true);
178 } // initTransporter()
179 
180 
181 
182 Uint32 SCI_Transporter::getLocalNodeId(Uint32 adapterNo)
183 {
184  sci_query_adapter_t queryAdapter;
185  sci_error_t error;
186  Uint32 _localNodeId;
187 
188  queryAdapter.subcommand = SCI_Q_ADAPTER_NODEID;
189  queryAdapter.localAdapterNo = adapterNo;
190  queryAdapter.data = &_localNodeId;
191 
192  SCIQuery(SCI_Q_ADAPTER,(void*)(&queryAdapter),(Uint32)NULL,&error);
193 
194  if(error != SCI_ERR_OK)
195  return 0;
196  return _localNodeId;
197 }
198 
199 
200 bool SCI_Transporter::getLinkStatus(Uint32 adapterNo)
201 {
202  sci_query_adapter_t queryAdapter;
203  sci_error_t error;
204  int linkstatus;
205  queryAdapter.subcommand = SCI_Q_ADAPTER_LINK_OPERATIONAL;
206 
207  queryAdapter.localAdapterNo = adapterNo;
208  queryAdapter.data = &linkstatus;
209 
210  SCIQuery(SCI_Q_ADAPTER,(void*)(&queryAdapter),(Uint32)NULL,&error);
211 
212  if(error != SCI_ERR_OK) {
213  DBUG_PRINT("error", ("error %d querying adapter", error));
214  return false;
215  }
216  if(linkstatus<=0)
217  return false;
218  return true;
219 }
220 
221 
222 
224  DBUG_ENTER("SCI_Transporter::initLocalSegment");
225  Uint32 segmentSize = m_BufferSize;
226  Uint32 offset = 0;
227  sci_error_t err;
228  if(!m_sciinit) {
229  for(Uint32 i=0; i<m_adapters ; i++) {
230  SCIOpen(&(sciAdapters[i].scidesc), FLAGS, &err);
231  sciAdapters[i].localSciNodeId=getLocalNodeId(i);
232  DBUG_PRINT("info", ("SCInode iD %d adapter %d\n",
233  sciAdapters[i].localSciNodeId, i));
234  if(err != SCI_ERR_OK) {
235  DBUG_PRINT("error",
236  ("Cannot open an SCI virtual device. Error code 0x%x",
237  err));
238  DBUG_RETURN(err);
239  }
240  }
241  }
242 
243  m_sciinit=true;
244 
245  SCICreateSegment(sciAdapters[0].scidesc,
246  &(m_SourceSegm[0].localHandle),
247  hostSegmentId(localNodeId, remoteNodeId),
248  segmentSize,
249  0,
250  0,
251  0,
252  &err);
253 
254  if(err != SCI_ERR_OK) {
255  DBUG_PRINT("error", ("Error creating segment, err = 0x%x", err));
256  DBUG_RETURN(err);
257  } else {
258  DBUG_PRINT("info", ("created segment id : %d",
259  hostSegmentId(localNodeId, remoteNodeId)));
260  }
261 
263  for(Uint32 i=0; i < m_adapters; i++) {
264  SCIPrepareSegment((m_SourceSegm[0].localHandle),
265  i,
266  FLAGS,
267  &err);
268 
269  if(err != SCI_ERR_OK) {
270  DBUG_PRINT("error",
271  ("Local Segment is not accessible by an SCI adapter. Error code 0x%x\n",
272  err));
273  DBUG_RETURN(err);
274  }
275  }
276 
277 
278  m_SourceSegm[0].mappedMemory =
279  SCIMapLocalSegment((m_SourceSegm[0].localHandle),
280  &(m_SourceSegm[0].lhm[0].map),
281  offset,
282  segmentSize,
283  NULL,
284  FLAGS,
285  &err);
286 
287 
288 
289  if(err != SCI_ERR_OK) {
290  DBUG_PRINT("error", ("Cannot map area of size %d. Error code 0x%x",
291  segmentSize,err));
292  doDisconnect();
293  DBUG_RETURN(err);
294  }
295 
296 
298  for(Uint32 i=0; i < m_adapters; i++) {
299  SCISetSegmentAvailable((m_SourceSegm[0].localHandle),
300  i,
301  FLAGS,
302  &err);
303 
304  if(err != SCI_ERR_OK) {
305  DBUG_PRINT("error",
306  ("Local Segment is not available for remote connections. Error code 0x%x\n",
307  err));
308  DBUG_RETURN(err);
309  }
310  }
311  setupLocalSegment();
312  DBUG_RETURN(err);
313 
314 } // initLocalSegment()
315 
316 
317 bool SCI_Transporter::doSend() {
318 #ifdef DEBUG_TRANSPORTER
319  NDB_TICKS startSec=0, stopSec=0;
320  Uint32 startMicro=0, stopMicro=0, totalMicro=0;
321 #endif
322  sci_error_t err;
323  Uint32 retry=0;
324 
325  if (!fetch_send_iovec_data())
326  return false;
327 
328  Uint32 used = m_send_iovec_used;
329  if (used == 0)
330  return true; // Nothing to send
331 
332 #ifdef DEBUG_TRANSPORTER
333  Uint32 sizeToSend = 0;
334  for (Uint32 i = 0; i < used; i++)
335  sizeToSend += m_send_iovec[i].iov_len;
336 
337  if(sizeToSend < 1024 )
338  i1024++;
339  if(sizeToSend > 1024 && sizeToSend < 2048 )
340  i10242048++;
341  if(sizeToSend==2048)
342  i2048++;
343  if(sizeToSend>2048 && sizeToSend < 4096)
344  i20484096++;
345  if(sizeToSend==4096)
346  i4096++;
347  if(sizeToSend==4097)
348  i4097++;
349 #endif
350 
351  bool status = true;
352  Uint32 curr = 0;
353  Uint32 total = 0;
354  while (curr < used)
355  {
356  tryagain:
357  if (retry > 3) {
358  DBUG_PRINT("error", ("SCI Transfer failed"));
359  report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
360  status = false;
361  break;
362  }
363  Uint32 segSize = m_send_iovec[curr].iov_len;
364  Uint32 * insertPtr = (Uint32 *)
365  (m_TargetSegm[m_ActiveAdapterId].writer)->getWritePtr(segSize);
366 
367  if(insertPtr != 0) {
368 
369  const Uint32 remoteOffset=(Uint32)
370  ((char*)insertPtr -
371  (char*)(m_TargetSegm[m_ActiveAdapterId].mappedMemory));
372 
373  SCIMemCpy(m_TargetSegm[m_ActiveAdapterId].sequence,
374  (void*)m_send_iovec[curr].iov_base,
375  m_TargetSegm[m_ActiveAdapterId].rhm[m_ActiveAdapterId].map,
376  remoteOffset,
377  segSize,
378  SCI_FLAG_ERROR_CHECK,
379  &err);
380 
381  if (err != SCI_ERR_OK) {
382  if (err == SCI_ERR_OUT_OF_RANGE ||
383  err == SCI_ERR_SIZE_ALIGNMENT ||
384  err == SCI_ERR_OFFSET_ALIGNMENT) {
385  DBUG_PRINT("error", ("Data transfer error = %d", err));
386  report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
387  status = false;
388  break;
389  }
390  if(err == SCI_ERR_TRANSFER_FAILED) {
391  if(getLinkStatus(m_ActiveAdapterId))
392  {
393  retry++;
394  goto tryagain;
395  }
396  if (m_adapters == 1) {
397  DBUG_PRINT("error", ("SCI Transfer failed"));
398  report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
399  status = false;
400  break;
401  }
402  m_failCounter++;
403  Uint32 temp=m_ActiveAdapterId;
404  if (getLinkStatus(m_StandbyAdapterId)) {
405  failoverShmWriter();
406  SCIStoreBarrier(m_TargetSegm[m_StandbyAdapterId].sequence,0);
407  m_ActiveAdapterId=m_StandbyAdapterId;
408  m_StandbyAdapterId=temp;
409  DBUG_PRINT("error", ("Swapping from adapter %u to %u",
410  m_StandbyAdapterId, m_ActiveAdapterId));
411  } else {
412  report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
413  DBUG_PRINT("error", ("SCI Transfer failed"));
414  }
415  }
416  break;
417  } else {
418  SHM_Writer * writer = (m_TargetSegm[m_ActiveAdapterId].writer);
419  writer->updateWritePtr(segSize);
420 
421  curr++;
422  total += segSize;
423  }
424  } else {
429  if (curr == 0)
430  {
431  DBUG_PRINT("error", ("the segment is full for some reason"));
432  status = false;
433  }
434  break;
435  } //if
436  }
437 
438  if (total > 0)
439  iovec_data_sent(total);
440 
441  return status;
442 } // doSend()
443 
444 
445 
446 void SCI_Transporter::failoverShmWriter() {
447 #if 0
448  (m_TargetSegm[m_StandbyAdapterId].writer)
449  ->copyIndexes((m_TargetSegm[m_StandbyAdapterId].writer));
450 #endif
451 } //failoverShm
452 
453 
454 void SCI_Transporter::setupLocalSegment()
455 {
456  DBUG_ENTER("SCI_Transporter::setupLocalSegment");
457  Uint32 sharedSize = 0;
458  sharedSize =4096; //start of the buffer is page aligend
459 
460  Uint32 sizeOfBuffer = m_BufferSize;
461 
462  sizeOfBuffer -= sharedSize;
463 
464  Uint32 * localReadIndex =
465  (Uint32*)m_SourceSegm[m_ActiveAdapterId].mappedMemory;
466  Uint32 * localWriteIndex = (Uint32*)(localReadIndex+ 1);
467  m_localStatusFlag = (Uint32*)(localReadIndex + 3);
468 
469  char * localStartOfBuf = (char*)
470  ((char*)m_SourceSegm[m_ActiveAdapterId].mappedMemory+sharedSize);
471 
472  * localReadIndex = 0;
473  * localWriteIndex = 0;
474 
475  const Uint32 slack = MAX_MESSAGE_SIZE;
476 
477  reader = new SHM_Reader(localStartOfBuf,
478  sizeOfBuffer,
479  slack,
480  localReadIndex,
481  localWriteIndex);
482 
483  reader->clear();
484  DBUG_VOID_RETURN;
485 } //setupLocalSegment
486 
487 void SCI_Transporter::setupRemoteSegment()
488 {
489  DBUG_ENTER("SCI_Transporter::setupRemoteSegment");
490  Uint32 sharedSize = 0;
491  sharedSize =4096; //start of the buffer is page aligned
492 
493  Uint32 sizeOfBuffer = m_BufferSize;
494  const Uint32 slack = MAX_MESSAGE_SIZE;
495  sizeOfBuffer -= sharedSize;
496 
497  Uint32 *segPtr = (Uint32*) m_TargetSegm[m_ActiveAdapterId].mappedMemory ;
498 
499  Uint32 * remoteReadIndex = (Uint32*)segPtr;
500  Uint32 * remoteWriteIndex = (Uint32*)(segPtr + 1);
501  m_remoteStatusFlag = (Uint32*)(segPtr + 3);
502 
503  char * remoteStartOfBuf = ( char*)((char*)segPtr+(sharedSize));
504 
505  writer = new SHM_Writer(remoteStartOfBuf,
506  sizeOfBuffer,
507  slack,
508  remoteReadIndex,
509  remoteWriteIndex);
510 
511  writer->clear();
512 
513  m_TargetSegm[0].writer=writer;
514 
515  if(createSequence(m_ActiveAdapterId)!=SCI_ERR_OK) {
516  report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE);
517  DBUG_PRINT("error", ("Unable to create sequence on active"));
518  doDisconnect();
519  }
520  if (m_adapters > 1) {
521  segPtr = (Uint32*) m_TargetSegm[m_StandbyAdapterId].mappedMemory ;
522 
523  Uint32 * remoteReadIndex2 = (Uint32*)segPtr;
524  Uint32 * remoteWriteIndex2 = (Uint32*) (segPtr + 1);
525  m_remoteStatusFlag2 = (Uint32*)(segPtr + 3);
526 
527  char * remoteStartOfBuf2 = ( char*)((char *)segPtr+sharedSize);
528 
535  writer2 = new SHM_Writer(remoteStartOfBuf2,
536  sizeOfBuffer,
537  slack,
538  remoteReadIndex2,
539  remoteWriteIndex2);
540 
541  * remoteReadIndex = 0;
542  * remoteWriteIndex = 0;
543  writer2->clear();
544  m_TargetSegm[1].writer=writer2;
545  if(createSequence(m_StandbyAdapterId)!=SCI_ERR_OK) {
546  report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE);
547  DBUG_PRINT("error", ("Unable to create sequence on standby"));
548  doDisconnect();
549  }
550  }
551  DBUG_VOID_RETURN;
552 } //setupRemoteSegment
553 
554 bool
555 SCI_Transporter::init_local()
556 {
557  DBUG_ENTER("SCI_Transporter::init_local");
558  if(!m_initLocal) {
559  if(initLocalSegment()!=SCI_ERR_OK){
560  NdbSleep_MilliSleep(10);
561  //NDB SHOULD TERMINATE AND COMPUTER REBOOTED!
562  report_error(TE_SCI_CANNOT_INIT_LOCALSEGMENT);
563  DBUG_RETURN(false);
564  }
565  m_initLocal=true;
566  }
567  DBUG_RETURN(true);
568 }
569 
570 bool
571 SCI_Transporter::init_remote()
572 {
573  DBUG_ENTER("SCI_Transporter::init_remote");
574  sci_error_t err;
575  Uint32 offset = 0;
576  if(!m_mapped ) {
577  DBUG_PRINT("info", ("Map remote segments"));
578  for(Uint32 i=0; i < m_adapters ; i++) {
579  m_TargetSegm[i].rhm[i].remoteHandle=0;
580  SCIConnectSegment(sciAdapters[i].scidesc,
581  &(m_TargetSegm[i].rhm[i].remoteHandle),
582  m_remoteNodes[i],
583  remoteSegmentId(localNodeId, remoteNodeId),
584  i,
585  0,
586  0,
587  0,
588  0,
589  &err);
590 
591  if(err != SCI_ERR_OK) {
592  NdbSleep_MilliSleep(10);
593  DBUG_PRINT("error", ("Error connecting segment, err 0x%x", err));
594  DBUG_RETURN(false);
595  }
596  }
597  // Map the remote memory segment into program space
598  for(Uint32 i=0; i < m_adapters ; i++) {
599  m_TargetSegm[i].mappedMemory =
600  SCIMapRemoteSegment((m_TargetSegm[i].rhm[i].remoteHandle),
601  &(m_TargetSegm[i].rhm[i].map),
602  offset,
603  m_BufferSize,
604  NULL,
605  FLAGS,
606  &err);
607 
608  if(err!= SCI_ERR_OK) {
609  DBUG_PRINT("error",
610  ("Cannot map a segment to the remote node %d. Error code 0x%x",
611  m_RemoteSciNodeId, err));
612  //NDB SHOULD TERMINATE AND COMPUTER REBOOTED!
613  report_error(TE_SCI_CANNOT_MAP_REMOTESEGMENT);
614  DBUG_RETURN(false);
615  }
616  }
617  m_mapped=true;
618  setupRemoteSegment();
619  setConnected();
620  DBUG_PRINT("info", ("connected and mapped to segment, remoteNode: %d",
621  remoteNodeId));
622  DBUG_PRINT("info", ("remoteSegId: %d",
623  remoteSegmentId(localNodeId, remoteNodeId)));
624  DBUG_RETURN(true);
625  } else {
626  DBUG_RETURN(getConnectionStatus());
627  }
628 }
629 
630 bool
631 SCI_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd)
632 {
633  SocketInputStream s_input(sockfd);
634  SocketOutputStream s_output(sockfd);
635  char buf[256];
636  DBUG_ENTER("SCI_Transporter::connect_client_impl");
637  // Wait for server to create and attach
638  if (s_input.gets(buf, 256) == 0) {
639  DBUG_PRINT("error", ("No initial response from server in SCI"));
640  NDB_CLOSE_SOCKET(sockfd);
641  DBUG_RETURN(false);
642  }
643  if (!init_local()) {
644  NDB_CLOSE_SOCKET(sockfd);
645  DBUG_RETURN(false);
646  }
647 
648  // Send ok to server
649  s_output.println("sci client 1 ok");
650 
651  if (!init_remote()) {
652  NDB_CLOSE_SOCKET(sockfd);
653  DBUG_RETURN(false);
654  }
655  // Wait for ok from server
656  if (s_input.gets(buf, 256) == 0) {
657  DBUG_PRINT("error", ("No second response from server in SCI"));
658  NDB_CLOSE_SOCKET(sockfd);
659  DBUG_RETURN(false);
660  }
661  // Send ok to server
662  s_output.println("sci client 2 ok");
663 
664  NDB_CLOSE_SOCKET(sockfd);
665  DBUG_PRINT("info", ("Successfully connected client to node %d",
666  remoteNodeId));
667  DBUG_RETURN(true);
668 }
669 
670 bool
672 {
673  SocketOutputStream s_output(sockfd);
674  SocketInputStream s_input(sockfd);
675  char buf[256];
676  DBUG_ENTER("SCI_Transporter::connect_server_impl");
677 
678  if (!init_local()) {
679  NDB_CLOSE_SOCKET(sockfd);
680  DBUG_RETURN(false);
681  }
682  // Send ok to client
683  s_output.println("sci server 1 ok");
684 
685  // Wait for ok from client
686  if (s_input.gets(buf, 256) == 0) {
687  DBUG_PRINT("error", ("No response from client in SCI"));
688  NDB_CLOSE_SOCKET(sockfd);
689  DBUG_RETURN(false);
690  }
691 
692  if (!init_remote()) {
693  NDB_CLOSE_SOCKET(sockfd);
694  DBUG_RETURN(false);
695  }
696  // Send ok to client
697  s_output.println("sci server 2 ok");
698  // Wait for ok from client
699  if (s_input.gets(buf, 256) == 0) {
700  DBUG_PRINT("error", ("No second response from client in SCI"));
701  NDB_CLOSE_SOCKET(sockfd);
702  DBUG_RETURN(false);
703  }
704 
705  NDB_CLOSE_SOCKET(sockfd);
706  DBUG_PRINT("info", ("Successfully connected server to node %d",
707  remoteNodeId));
708  DBUG_RETURN(true);
709 }
710 
711 sci_error_t SCI_Transporter::createSequence(Uint32 adapterid) {
712  sci_error_t err;
713  SCICreateMapSequence((m_TargetSegm[adapterid].rhm[adapterid].map),
714  &(m_TargetSegm[adapterid].sequence),
715  SCI_FLAG_FAST_BARRIER,
716  &err);
717  return err;
718 } // createSequence()
719 
720 bool SCI_Transporter::disconnectLocal()
721 {
722  DBUG_ENTER("SCI_Transporter::disconnectLocal");
723  sci_error_t err;
724  m_ActiveAdapterId=0;
725 
729  SCIUnmapSegment(m_SourceSegm[0].lhm[0].map,0,&err);
730  if(err!=SCI_ERR_OK) {
731  report_error(TE_SCI_UNABLE_TO_UNMAP_SEGMENT);
732  DBUG_PRINT("error", ("Unable to unmap segment"));
733  DBUG_RETURN(false);
734  }
735 
736  SCIRemoveSegment((m_SourceSegm[m_ActiveAdapterId].localHandle),
737  FLAGS,
738  &err);
739 
740  if(err!=SCI_ERR_OK) {
741  report_error(TE_SCI_UNABLE_TO_REMOVE_SEGMENT);
742  DBUG_PRINT("error", ("Unable to remove segment"));
743  DBUG_RETURN(false);
744  }
745  DBUG_PRINT("info", ("Local memory segment is unmapped and removed"));
746  DBUG_RETURN(true);
747 } // disconnectLocal()
748 
749 
750 bool SCI_Transporter::disconnectRemote() {
751  DBUG_ENTER("SCI_Transporter::disconnectRemote");
752  sci_error_t err;
753  for(Uint32 i=0; i<m_adapters; i++) {
757  SCIUnmapSegment(m_TargetSegm[i].rhm[i].map,0,&err);
758  if(err!=SCI_ERR_OK) {
759  report_error(TE_SCI_UNABLE_TO_UNMAP_SEGMENT);
760  DBUG_PRINT("error", ("Unable to unmap segment"));
761  DBUG_RETURN(false);
762  }
763 
764  SCIDisconnectSegment(m_TargetSegm[i].rhm[i].remoteHandle,
765  FLAGS,
766  &err);
767  if(err!=SCI_ERR_OK) {
768  report_error(TE_SCI_UNABLE_TO_DISCONNECT_SEGMENT);
769  DBUG_PRINT("error", ("Unable to disconnect segment"));
770  DBUG_RETURN(false);
771  }
772  DBUG_PRINT("info", ("Remote memory segment is unmapped and disconnected"));
773  }
774  DBUG_RETURN(true);
775 } // disconnectRemote()
776 
777 
778 SCI_Transporter::~SCI_Transporter() {
779  DBUG_ENTER("SCI_Transporter::~SCI_Transporter");
780  // Close channel to the driver
781  doDisconnect();
782  DBUG_VOID_RETURN;
783 } // ~SCI_Transporter()
784 
786  // Termination of SCI
787  sci_error_t err;
788  DBUG_ENTER("SCI_Transporter::closeSCI");
789 
790  // Disconnect and remove remote segment
791  disconnectRemote();
792 
793  // Unmap and remove local segment
794 
795  disconnectLocal();
796 
797  // Closes an SCI virtual device
798  SCIClose(activeSCIDescriptor, FLAGS, &err);
799 
800  if(err != SCI_ERR_OK) {
801  DBUG_PRINT("error",
802  ("Cannot close SCI channel to the driver. Error code 0x%x",
803  err));
804  }
805  SCITerminate();
806  DBUG_VOID_RETURN;
807 } // closeSCI()
808 
809 enum SciStatus {
810  SCIDISCONNECT = 1,
811  SCICONNECTED = 2
812 };
813 
814 bool
816  if(*m_localStatusFlag == SCICONNECTED &&
817  (*m_remoteStatusFlag == SCICONNECTED ||
818  ((m_adapters > 1) &&
819  *m_remoteStatusFlag2 == SCICONNECTED)))
820  return true;
821  else
822  return false;
823 }
824 
825 void
826 SCI_Transporter::setConnected() {
827  *m_remoteStatusFlag = SCICONNECTED;
828  if (m_adapters > 1) {
829  *m_remoteStatusFlag2 = SCICONNECTED;
830  }
831  *m_localStatusFlag = SCICONNECTED;
832 }
833 
834 void
835 SCI_Transporter::setDisconnect() {
836  if(getLinkStatus(m_ActiveAdapterId))
837  *m_remoteStatusFlag = SCIDISCONNECT;
838  if (m_adapters > 1) {
839  if(getLinkStatus(m_StandbyAdapterId))
840  *m_remoteStatusFlag2 = SCIDISCONNECT;
841  }
842 }
843 
844 bool
846  if (*m_localStatusFlag == SCIDISCONNECT) {
847  return false;
848  }
849  else
850  return true;
851 }
852 
853 static bool init = false;
854 
855 bool
856 SCI_Transporter::initSCI() {
857  DBUG_ENTER("SCI_Transporter::initSCI");
858  if(!init){
859  sci_error_t error;
860  // Initialize SISCI library
861  SCIInitialize(0, &error);
862  if(error != SCI_ERR_OK) {
863  DBUG_PRINT("error", ("Cannot initialize SISCI library."));
864  DBUG_PRINT("error",
865  ("Inconsistency between SISCI library and SISCI driver. Error code 0x%x",
866  error));
867  DBUG_RETURN(false);
868  }
869  init = true;
870  }
871  DBUG_RETURN(true);
872 }