~ubuntu-branches/ubuntu/precise/mysql-5.5/precise-201203300109

« back to all changes in this revision

Viewing changes to storage/ndb/src/mgmsrv/main.cpp

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2011-11-08 11:31:13 UTC
  • Revision ID: package-import@ubuntu.com-20111108113113-3ulw01fvi4vn8m25
Tags: upstream-5.5.17
ImportĀ upstreamĀ versionĀ 5.5.17

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 <ndb_global.h>
 
17
#include <ndb_opts.h>
 
18
 
 
19
#include "MgmtSrvr.hpp"
 
20
#include "EventLogger.hpp"
 
21
#include <Config.hpp>
 
22
#include "InitConfigFileParser.hpp"
 
23
#include <SocketServer.hpp>
 
24
#include "Services.hpp"
 
25
#include <version.h>
 
26
#include <kernel_types.h>
 
27
#include <Properties.hpp>
 
28
#include <NdbOut.hpp>
 
29
#include <NdbMain.h>
 
30
#include <NdbDaemon.h>
 
31
#include <NdbConfig.h>
 
32
#include <NdbHost.h>
 
33
#include <ndb_version.h>
 
34
#include <ConfigRetriever.hpp>
 
35
#include <mgmapi_config_parameters.h>
 
36
 
 
37
#include <NdbAutoPtr.hpp>
 
38
 
 
39
#include <ndb_mgmclient.hpp>
 
40
 
 
41
#undef DEBUG
 
42
#define DEBUG(x) ndbout << x << endl;
 
43
 
 
44
const char progname[] = "mgmtsrvr";
 
45
const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
 
46
 
 
47
// copied from mysql.cc to get readline
 
48
extern "C" {
 
49
#if defined( __WIN__)
 
50
#include <conio.h>
 
51
#else
 
52
#include <readline/readline.h>
 
53
extern "C" int add_history(const char *command); /* From readline directory */
 
54
#define HAVE_READLINE
 
55
#endif
 
56
}
 
57
 
 
58
static int 
 
59
read_and_execute(Ndb_mgmclient* com, const char * prompt, int _try_reconnect) 
 
60
{
 
61
  static char *line_read = (char *)NULL;
 
62
 
 
63
  /* If the buffer has already been allocated, return the memory
 
64
     to the free pool. */
 
65
  if (line_read)
 
66
  {
 
67
    free (line_read);
 
68
    line_read = (char *)NULL;
 
69
  }
 
70
#ifdef HAVE_READLINE
 
71
  /* Get a line from the user. */
 
72
  line_read = readline (prompt);    
 
73
  /* If the line has any text in it, save it on the history. */
 
74
  if (line_read && *line_read)
 
75
    add_history (line_read);
 
76
#else
 
77
  static char linebuffer[254];
 
78
  fputs(prompt, stdout);
 
79
  linebuffer[sizeof(linebuffer)-1]=0;
 
80
  line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin);
 
81
  if (line_read == linebuffer) {
 
82
    char *q=linebuffer;
 
83
    while (*q > 31) q++;
 
84
    *q=0;
 
85
    line_read= strdup(linebuffer);
 
86
  }
 
87
#endif
 
88
  return com->execute(line_read,_try_reconnect);
 
89
}
 
90
 
 
91
/**
 
92
 * @struct  MgmGlobals
 
93
 * @brief   Global Variables used in the management server
 
94
 *****************************************************************************/
 
95
 
 
96
/** Command line arguments  */
 
97
static int opt_daemon;   // NOT bool, bool need not be int
 
98
static int opt_non_interactive;
 
99
static int opt_interactive;
 
100
static const char * opt_config_filename= 0;
 
101
static int opt_mycnf = 0;
 
102
  
 
103
struct MgmGlobals {
 
104
  MgmGlobals();
 
105
  ~MgmGlobals();
 
106
  
 
107
  /** Stuff found in environment or in local config  */
 
108
  NodeId localNodeId;
 
109
  bool use_specific_ip;
 
110
  char * interface_name;
 
111
  short unsigned int port;
 
112
  
 
113
  /** The Mgmt Server */
 
114
  MgmtSrvr * mgmObject;
 
115
  
 
116
  /** The Socket Server */
 
117
  SocketServer * socketServer;
 
118
};
 
119
 
 
120
int g_no_nodeid_checks= 0;
 
121
int g_print_full_config;
 
122
static MgmGlobals *glob= 0;
 
123
 
 
124
/******************************************************************************
 
125
 * Function prototypes
 
126
 ******************************************************************************/
 
127
/**
 
128
 * Global variables
 
129
 */
 
130
bool g_StopServer;
 
131
bool g_RestartServer;
 
132
extern EventLogger g_eventLogger;
 
133
 
 
134
enum ndb_mgmd_options {
 
135
  OPT_INTERACTIVE = NDB_STD_OPTIONS_LAST,
 
136
  OPT_NO_NODEID_CHECKS,
 
137
  OPT_NO_DAEMON
 
138
};
 
139
NDB_STD_OPTS_VARS;
 
140
 
 
141
static struct my_option my_long_options[] =
 
142
{
 
143
  NDB_STD_OPTS("ndb_mgmd"),
 
144
  { "config-file", 'f', "Specify cluster configuration file",
 
145
    &opt_config_filename, &opt_config_filename, 0,
 
146
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
147
  { "print-full-config", 'P', "Print full config and exit",
 
148
    &g_print_full_config, &g_print_full_config, 0,
 
149
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
150
  { "daemon", 'd', "Run ndb_mgmd in daemon mode (default)",
 
151
    &opt_daemon, &opt_daemon, 0,
 
152
    GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
 
153
  { "interactive", OPT_INTERACTIVE,
 
154
    "Run interactive. Not supported but provided for testing purposes",
 
155
    &opt_interactive, &opt_interactive, 0,
 
156
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
157
  { "no-nodeid-checks", OPT_NO_NODEID_CHECKS,
 
158
    "Do not provide any node id checks", 
 
159
    &g_no_nodeid_checks, &g_no_nodeid_checks, 0,
 
160
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
161
  { "nodaemon", OPT_NO_DAEMON,
 
162
    "Don't run as daemon, but don't read from stdin",
 
163
    &opt_non_interactive, &opt_non_interactive, 0,
 
164
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
165
  { "mycnf", 256,
 
166
    "Read cluster config from my.cnf",
 
167
    &opt_mycnf, &opt_mycnf, 0,
 
168
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
169
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
170
};
 
171
 
 
172
static void short_usage_sub(void)
 
173
{
 
174
  printf("Usage: %s [OPTIONS]\n", my_progname);
 
175
}
 
176
static void usage()
 
177
{
 
178
  short_usage_sub();
 
179
  ndb_std_print_version();
 
180
  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
 
181
  puts("");
 
182
  my_print_help(my_long_options);
 
183
  my_print_variables(my_long_options);
 
184
}
 
185
 
 
186
/*
 
187
 *  MAIN 
 
188
 */
 
189
int main(int argc, char** argv)
 
190
{
 
191
 
 
192
  NDB_INIT(argv[0]);
 
193
 
 
194
  load_defaults("my",load_default_groups,&argc,&argv);
 
195
 
 
196
  int ho_error;
 
197
#ifndef DBUG_OFF
 
198
  opt_debug= "d:t:O,/tmp/ndb_mgmd.trace";
 
199
#endif
 
200
  if ((ho_error=handle_options(&argc, &argv, my_long_options, 
 
201
                               ndb_std_get_one_option)))
 
202
    exit(ho_error);
 
203
 
 
204
start:
 
205
  glob= new MgmGlobals;
 
206
 
 
207
  if (opt_interactive ||
 
208
      opt_non_interactive ||
 
209
      g_print_full_config) {
 
210
    opt_daemon= 0;
 
211
  }
 
212
 
 
213
  if (opt_mycnf && opt_config_filename)
 
214
  {
 
215
    ndbout_c("Both --mycnf and -f is not supported");
 
216
    return 0;
 
217
  }
 
218
 
 
219
  if (opt_mycnf == 0 && opt_config_filename == 0)
 
220
  {
 
221
    struct stat buf;
 
222
    if (stat("config.ini", &buf) != -1)
 
223
      opt_config_filename = "config.ini";
 
224
  }
 
225
  
 
226
  glob->socketServer = new SocketServer();
 
227
 
 
228
  MgmApiService * mapi = new MgmApiService();
 
229
 
 
230
  glob->mgmObject = new MgmtSrvr(glob->socketServer,
 
231
                                 opt_config_filename,
 
232
                                 opt_connect_str);
 
233
 
 
234
  if (g_print_full_config)
 
235
    goto the_end;
 
236
 
 
237
  if (glob->mgmObject->init())
 
238
    goto error_end;
 
239
 
 
240
  my_setwd(NdbConfig_get_path(0), MYF(0));
 
241
 
 
242
  glob->localNodeId= glob->mgmObject->getOwnNodeId();
 
243
  if (glob->localNodeId == 0) {
 
244
    goto error_end;
 
245
  }
 
246
 
 
247
  glob->port= glob->mgmObject->getPort();
 
248
 
 
249
  if (glob->port == 0)
 
250
    goto error_end;
 
251
 
 
252
  glob->interface_name = 0;
 
253
  glob->use_specific_ip = false;
 
254
 
 
255
  if(!glob->use_specific_ip){
 
256
    int count= 5; // no of retries for tryBind
 
257
    while(!glob->socketServer->tryBind(glob->port, glob->interface_name)){
 
258
      if (--count > 0) {
 
259
        NdbSleep_MilliSleep(1000);
 
260
        continue;
 
261
      }
 
262
      ndbout_c("Unable to setup port: %s:%d!\n"
 
263
               "Please check if the port is already used,\n"
 
264
               "(perhaps a ndb_mgmd is already running),\n"
 
265
               "and if you are executing on the correct computer", 
 
266
               (glob->interface_name ? glob->interface_name : "*"), glob->port);
 
267
      goto error_end;
 
268
    }
 
269
    free(glob->interface_name);
 
270
    glob->interface_name = 0;
 
271
  }
 
272
 
 
273
  if(!glob->socketServer->setup(mapi, &glob->port, glob->interface_name))
 
274
  {
 
275
    ndbout_c("Unable to setup management port: %d!\n"
 
276
             "Please check if the port is already used,\n"
 
277
             "(perhaps a ndb_mgmd is already running),\n"
 
278
             "and if you are executing on the correct computer", 
 
279
             glob->port);
 
280
    delete mapi;
 
281
    goto error_end;
 
282
  }
 
283
 
 
284
  if(!glob->mgmObject->check_start()){
 
285
    ndbout_c("Unable to check start management server.");
 
286
    ndbout_c("Probably caused by illegal initial configuration file.");
 
287
    goto error_end;
 
288
  }
 
289
 
 
290
  if (opt_daemon) {
 
291
    // Become a daemon
 
292
    char *lockfile= NdbConfig_PidFileName(glob->localNodeId);
 
293
    char *logfile=  NdbConfig_StdoutFileName(glob->localNodeId);
 
294
    NdbAutoPtr<char> tmp_aptr1(lockfile), tmp_aptr2(logfile);
 
295
 
 
296
    if (NdbDaemon_Make(lockfile, logfile, 0) == -1) {
 
297
      ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl;
 
298
      return 1;
 
299
    }
 
300
  }
 
301
 
 
302
#ifndef NDB_WIN32
 
303
  signal(SIGPIPE, SIG_IGN);
 
304
#endif
 
305
  {
 
306
    BaseString error_string;
 
307
    if(!glob->mgmObject->start(error_string)){
 
308
      ndbout_c("Unable to start management server.");
 
309
      ndbout_c("Probably caused by illegal initial configuration file.");
 
310
      ndbout_c(error_string.c_str());
 
311
      goto error_end;
 
312
    }
 
313
  }
 
314
 
 
315
  //glob->mgmObject->saveConfig();
 
316
  mapi->setMgm(glob->mgmObject);
 
317
 
 
318
  char msg[256];
 
319
  BaseString::snprintf(msg, sizeof(msg),
 
320
           "NDB Cluster Management Server. %s", NDB_VERSION_STRING);
 
321
  ndbout_c(msg);
 
322
  g_eventLogger.info(msg);
 
323
 
 
324
  BaseString::snprintf(msg, 256, "Id: %d, Command port: %d",
 
325
           glob->localNodeId, glob->port);
 
326
  ndbout_c(msg);
 
327
  g_eventLogger.info(msg);
 
328
  
 
329
  g_StopServer = false;
 
330
  g_RestartServer= false;
 
331
  glob->socketServer->startServer();
 
332
 
 
333
  if(opt_interactive) {
 
334
    BaseString con_str;
 
335
    if(glob->interface_name)
 
336
      con_str.appfmt("host=%s:%d", glob->interface_name, glob->port);
 
337
    else 
 
338
      con_str.appfmt("localhost:%d", glob->port);
 
339
    Ndb_mgmclient com(con_str.c_str(), 1);
 
340
    while(g_StopServer != true && read_and_execute(&com, "ndb_mgm> ", 1));
 
341
  } else 
 
342
  {
 
343
    while(g_StopServer != true)
 
344
      NdbSleep_MilliSleep(500);
 
345
  }
 
346
 
 
347
  if(g_RestartServer)
 
348
    g_eventLogger.info("Restarting server...");
 
349
  else
 
350
    g_eventLogger.info("Shutting down server...");
 
351
  glob->socketServer->stopServer();
 
352
  // We disconnect from the ConfigRetreiver mgmd when we delete glob below
 
353
  glob->socketServer->stopSessions(true);
 
354
  g_eventLogger.info("Shutdown complete");
 
355
 the_end:
 
356
  delete glob;
 
357
  if(g_RestartServer)
 
358
    goto start;
 
359
  ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
 
360
  return 0;
 
361
 error_end:
 
362
  delete glob;
 
363
  ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
 
364
  return 1;
 
365
}
 
366
 
 
367
MgmGlobals::MgmGlobals(){
 
368
  // Default values
 
369
  port = 0;
 
370
  interface_name = 0;
 
371
  socketServer = 0;
 
372
  mgmObject = 0;
 
373
}
 
374
 
 
375
MgmGlobals::~MgmGlobals(){
 
376
  if (socketServer)
 
377
    delete socketServer;
 
378
  if (mgmObject)
 
379
    delete mgmObject;
 
380
  if (interface_name)
 
381
    free(interface_name);
 
382
}