~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/src/mgmapi/LocalConfig.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
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 as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include "LocalConfig.hpp"
 
17
#include <NdbEnv.h>
 
18
#include <NdbConfig.h>
 
19
#include <NdbAutoPtr.hpp>
 
20
#include <NdbMem.h>
 
21
 
 
22
LocalConfig::LocalConfig(){
 
23
  error_line = 0; error_msg[0] = 0;
 
24
  _ownNodeId= 0;
 
25
}
 
26
 
 
27
bool
 
28
LocalConfig::init(const char *connectString,
 
29
                  const char *fileName)
 
30
{
 
31
  DBUG_ENTER("LocalConfig::init");
 
32
  /** 
 
33
   * Escalation:
 
34
   *  1. Check connectString
 
35
   *  2. Check given filename
 
36
   *  3. Check environment variable NDB_CONNECTSTRING
 
37
   *  4. Check Ndb.cfg in NDB_HOME
 
38
   *  5. Check Ndb.cfg in cwd
 
39
   *  6. Check defaultConnectString
 
40
   */
 
41
  
 
42
  _ownNodeId= 0;
 
43
 
 
44
  //1. Check connectString
 
45
  if(connectString != 0 && connectString[0] != 0){
 
46
    if(readConnectString(connectString, "connect string")){
 
47
      if (ids.size())
 
48
        DBUG_RETURN(true);
 
49
      // only nodeid given, continue to find hosts
 
50
    } else
 
51
      DBUG_RETURN(false);
 
52
  }
 
53
 
 
54
  //2. Check given filename
 
55
  if (fileName && strlen(fileName) > 0) {
 
56
    bool fopenError;
 
57
    if(readFile(fileName, fopenError)){
 
58
      DBUG_RETURN(true);
 
59
    }
 
60
    DBUG_RETURN(false);
 
61
  }
 
62
 
 
63
  //3. Check environment variable
 
64
  char buf[255];  
 
65
  if(NdbEnv_GetEnv("NDB_CONNECTSTRING", buf, sizeof(buf)) &&
 
66
     strlen(buf) != 0){
 
67
    if(readConnectString(buf, "NDB_CONNECTSTRING")){
 
68
      DBUG_RETURN(true);
 
69
    }
 
70
    DBUG_RETURN(false);
 
71
  }
 
72
  
 
73
  //4. Check Ndb.cfg in NDB_HOME
 
74
  {
 
75
    bool fopenError;
 
76
    char *buf2= NdbConfig_NdbCfgName(1 /*true*/);
 
77
    NdbAutoPtr<char> tmp_aptr(buf2);
 
78
    if(readFile(buf2, fopenError))
 
79
      DBUG_RETURN(true);
 
80
    if (!fopenError)
 
81
      DBUG_RETURN(false);
 
82
  }
 
83
 
 
84
  //5. Check Ndb.cfg in cwd
 
85
  {
 
86
    bool fopenError;
 
87
    char *buf2= NdbConfig_NdbCfgName(0 /*false*/);
 
88
    NdbAutoPtr<char> tmp_aptr(buf2);
 
89
    if(readFile(buf2, fopenError))
 
90
      DBUG_RETURN(true);
 
91
    if (!fopenError)
 
92
      DBUG_RETURN(false);
 
93
  }
 
94
 
 
95
  //7. Check
 
96
  {
 
97
    char buf2[256];
 
98
    BaseString::snprintf(buf2, sizeof(buf2), "host=localhost:%s", NDB_PORT);
 
99
    if(readConnectString(buf2, "default connect string"))
 
100
      DBUG_RETURN(true);
 
101
  }
 
102
 
 
103
  setError(0, "");
 
104
 
 
105
  DBUG_RETURN(false);
 
106
}
 
107
 
 
108
LocalConfig::~LocalConfig(){
 
109
}
 
110
  
 
111
void LocalConfig::setError(int lineNumber, const char * _msg) {
 
112
  error_line = lineNumber;
 
113
  strncpy(error_msg, _msg, sizeof(error_msg));
 
114
}
 
115
 
 
116
void LocalConfig::printError() const {
 
117
  ndbout << "Configuration error" << endl;
 
118
  if (error_line)
 
119
    ndbout << "Line: "<< error_line << ", ";
 
120
  ndbout << error_msg << endl << endl;
 
121
}
 
122
 
 
123
void LocalConfig::printUsage() const {
 
124
  ndbout << "This node needs information on how to connect"<<endl
 
125
         << "to the NDB Management Server."<<endl
 
126
         << "The information can be supplied in one of the following ways:"
 
127
         << endl;
 
128
    
 
129
  ndbout << "1. Put a Ndb.cfg file in the directory where you start"<<endl 
 
130
         << "   the node. "<< endl
 
131
         << "   Ex: Ndb.cfg" << endl
 
132
         << "   | host=localhost:"<<NDB_PORT<<endl;
 
133
    
 
134
  ndbout << "2. Use the environment variable NDB_CONNECTSTRING to "<<endl
 
135
         << "   provide this information." <<endl
 
136
         << "   Ex: " << endl
 
137
         << "   >export NDB_CONNECTSTRING=\"host=localhost:"<<NDB_PORT<<"\""
 
138
         <<endl<<endl;
 
139
}
 
140
  
 
141
const char *nodeIdTokens[] = {
 
142
  "OwnProcessId %i",
 
143
  "nodeid=%i",
 
144
  0
 
145
};
 
146
 
 
147
const char *hostNameTokens[] = {
 
148
  "host://%[^:]:%i",
 
149
  "host=%[^:]:%i",
 
150
  "mgmd=%[^:]:%i",
 
151
  "%[^:^=^ ]:%i",
 
152
  "%s %i",
 
153
  0
 
154
};
 
155
 
 
156
const char *fileNameTokens[] = {
 
157
  "file://%s",
 
158
  "file=%s",
 
159
  0
 
160
};
 
161
 
 
162
bool
 
163
LocalConfig::parseNodeId(const char * buf){
 
164
  for(int i = 0; nodeIdTokens[i] != 0; i++)
 
165
    if (sscanf(buf, nodeIdTokens[i], &_ownNodeId) == 1)
 
166
      return true;
 
167
  return false;
 
168
}
 
169
 
 
170
bool
 
171
LocalConfig::parseHostName(const char * buf){
 
172
  char tempString[1024];
 
173
  char tempString2[1024];
 
174
  int port;
 
175
  do {
 
176
    for(int i = 0; hostNameTokens[i] != 0; i++) {
 
177
      if (sscanf(buf, hostNameTokens[i], tempString, &port) == 2) {
 
178
        MgmtSrvrId mgmtSrvrId;
 
179
        mgmtSrvrId.type = MgmId_TCP;
 
180
        mgmtSrvrId.name.assign(tempString);
 
181
        mgmtSrvrId.port = port;
 
182
        ids.push_back(mgmtSrvrId);
 
183
        return true;
 
184
      }
 
185
    }
 
186
    if (buf == tempString2)
 
187
      break;
 
188
    // try to add default port to see if it works
 
189
    snprintf(tempString2, sizeof(tempString2),"%s:%s", buf, NDB_PORT);
 
190
    buf= tempString2;
 
191
  } while(1);
 
192
  return false;
 
193
}
 
194
 
 
195
bool
 
196
LocalConfig::parseFileName(const char * buf){
 
197
  char tempString[1024];
 
198
  for(int i = 0; fileNameTokens[i] != 0; i++) {
 
199
    if (sscanf(buf, fileNameTokens[i], tempString) == 1) {
 
200
      MgmtSrvrId mgmtSrvrId;
 
201
      mgmtSrvrId.type = MgmId_File;
 
202
      mgmtSrvrId.name.assign(tempString);
 
203
      ids.push_back(mgmtSrvrId);
 
204
      return true;
 
205
    }
 
206
  }
 
207
  return false;
 
208
}
 
209
 
 
210
bool
 
211
LocalConfig::parseString(const char * connectString, BaseString &err){
 
212
  char * for_strtok;
 
213
  char * copy = strdup(connectString);
 
214
  NdbAutoPtr<char> tmp_aptr(copy);
 
215
 
 
216
  for (char *tok = strtok_r(copy,";,",&for_strtok); tok != 0;
 
217
       tok = strtok_r(NULL, ";,", &for_strtok)) {
 
218
    if (tok[0] == '#') continue;
 
219
 
 
220
    if (!_ownNodeId) // only one nodeid definition allowed
 
221
      if (parseNodeId(tok))
 
222
        continue;
 
223
    if (parseHostName(tok))
 
224
      continue;
 
225
    if (parseFileName(tok))
 
226
      continue;
 
227
    
 
228
    err.assfmt("Unexpected entry: \"%s\"", tok);
 
229
    return false;
 
230
  }
 
231
 
 
232
  return true;
 
233
}
 
234
 
 
235
bool LocalConfig::readFile(const char * filename, bool &fopenError)
 
236
{
 
237
  char line[1024];
 
238
  
 
239
  fopenError = false;
 
240
  
 
241
  FILE * file = fopen(filename, "r");
 
242
  if(file == 0){
 
243
    BaseString::snprintf(line, sizeof(line),
 
244
             "Unable to open local config file: %s", filename);
 
245
    setError(0, line);
 
246
    fopenError = true;
 
247
    return false;
 
248
  }
 
249
 
 
250
  BaseString theString;
 
251
 
 
252
  while(fgets(line, sizeof(line), file)){
 
253
    BaseString tmp(line);
 
254
    tmp.trim(" \t\n\r");
 
255
    if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
 
256
      theString.append(tmp);
 
257
      break;
 
258
    }
 
259
  }
 
260
  while (fgets(line, sizeof(line), file)) {
 
261
    BaseString tmp(line);
 
262
    tmp.trim(" \t\n\r");
 
263
    if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
 
264
      theString.append(";");
 
265
      theString.append(tmp);
 
266
    }
 
267
  }
 
268
  
 
269
  BaseString err;
 
270
  bool return_value = parseString(theString.c_str(), err);
 
271
 
 
272
  if (!return_value) {
 
273
    BaseString tmp;
 
274
    tmp.assfmt("Reading %s: %s", filename, err.c_str());
 
275
    setError(0, tmp.c_str());
 
276
  }
 
277
 
 
278
  fclose(file);
 
279
  return return_value;
 
280
}
 
281
 
 
282
bool
 
283
LocalConfig::readConnectString(const char * connectString,
 
284
                               const char * info){
 
285
  BaseString err;
 
286
  bool return_value = parseString(connectString, err);
 
287
  if (!return_value) {
 
288
    BaseString err2;
 
289
    err2.assfmt("Reading %d \"%s\": %s", info, connectString, err.c_str());
 
290
    setError(0,err2.c_str());
 
291
  }
 
292
  return return_value;
 
293
}
 
294
 
 
295
char *
 
296
LocalConfig::makeConnectString(char *buf, int sz)
 
297
{
 
298
  int p= BaseString::snprintf(buf,sz,"nodeid=%d", _ownNodeId);
 
299
  if (p < sz)
 
300
    for (unsigned i = 0; i < ids.size(); i++)
 
301
    {
 
302
      if (ids[i].type != MgmId_TCP)
 
303
        continue;
 
304
      int new_p= p+BaseString::snprintf(buf+p,sz-p,",%s:%d",
 
305
                                        ids[i].name.c_str(), ids[i].port);
 
306
      if (new_p < sz)
 
307
        p= new_p;
 
308
      else 
 
309
      {
 
310
        buf[p]= 0;
 
311
        break;
 
312
      }
 
313
    }
 
314
  buf[sz-1]=0;
 
315
  return buf;
 
316
}
 
317
 
 
318
template class Vector<MgmtSrvrId>;