MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SHM_Transporter.unix.cpp
1 /*
2  Copyright (C) 2003-2006 MySQL AB
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 
20 #include <ndb_global.h>
21 
22 #include "SHM_Transporter.hpp"
23 #include "TransporterInternalDefinitions.hpp"
24 #include <TransporterCallback.hpp>
25 #include <NdbSleep.h>
26 #include <NdbOut.hpp>
27 
28 #include <sys/ipc.h>
29 #include <sys/shm.h>
30 
31 void SHM_Transporter::make_error_info(char info[], int sz)
32 {
33  snprintf(info,sz,"Shm key=%d sz=%d id=%d",
34  shmKey, shmSize, shmId);
35 }
36 
37 bool
38 SHM_Transporter::ndb_shm_create()
39 {
40  shmId = shmget(shmKey, shmSize, IPC_CREAT | 960);
41  if(shmId == -1) {
42  perror("shmget: ");
43  return false;
44  }
45  return true;
46 }
47 
48 bool
49 SHM_Transporter::ndb_shm_get()
50 {
51  shmId = shmget(shmKey, shmSize, 0);
52  if(shmId == -1) {
53  perror("shmget: ");
54  return false;
55  }
56  return true;
57 }
58 
59 bool
60 SHM_Transporter::ndb_shm_attach()
61 {
62  shmBuf = (char *)shmat(shmId, 0, 0);
63  if(shmBuf == 0) {
64  perror("shmat: ");
65  return false;
66  }
67  return true;
68 }
69 
70 bool
72  struct shmid_ds info;
73  const int res = shmctl(shmId, IPC_STAT, &info);
74  if(res == -1){
75  char buf[128];
76  int r= snprintf(buf, sizeof(buf),
77  "shmctl(%d, IPC_STAT) errno: %d(%s). ", shmId,
78  errno, strerror(errno));
79  make_error_info(buf+r, sizeof(buf)-r);
80  DBUG_PRINT("error",("%s", buf));
81  switch (errno)
82  {
83  case EACCES:
84  report_error(TE_SHM_IPC_PERMANENT, buf);
85  break;
86  default:
87  report_error(TE_SHM_IPC_STAT, buf);
88  break;
89  }
90  return false;
91  }
92 
93  if(info.shm_nattch != 2){
94  char buf[128];
95  make_error_info(buf, sizeof(buf));
96  report_error(TE_SHM_DISCONNECT);
97  DBUG_PRINT("error", ("Already connected to node %d",
98  remoteNodeId));
99  return false;
100  }
101  return true;
102 }
103 
104 void
106  if(_attached){
107  const int res = shmdt(shmBuf);
108  if(res == -1){
109  perror("shmdelete: ");
110  return;
111  }
112  _attached = false;
113  if(!isServer && _shmSegCreated)
114  _shmSegCreated = false;
115  }
116 
117  if(isServer && _shmSegCreated){
118  const int res = shmctl(shmId, IPC_RMID, 0);
119  if(res == -1){
120  char buf[64];
121  make_error_info(buf, sizeof(buf));
122  report_error(TE_SHM_UNABLE_TO_REMOVE_SEGMENT);
123  return;
124  }
125  _shmSegCreated = false;
126  }
127  setupBuffersDone=false;
128 }