~ubuntu-branches/ubuntu/trusty/mariadb-5.5/trusty-proposed

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Otto Kekäläinen
  • Date: 2013-12-22 10:27:05 UTC
  • Revision ID: package-import@ubuntu.com-20131222102705-mndw7s12mz0szrcn
Tags: upstream-5.5.32
Import upstream version 5.5.32

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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
 
15
 
 
16
#include <ndb_global.h>
 
17
#include <my_sys.h>
 
18
 
 
19
#include <LocalConfig.hpp>
 
20
#include <NdbAutoPtr.hpp>
 
21
 
 
22
#include <NdbSleep.h>
 
23
#include <NdbTCP.h>
 
24
#include <mgmapi.h>
 
25
#include <mgmapi_internal.h>
 
26
#include <mgmapi_debug.h>
 
27
#include "mgmapi_configuration.hpp"
 
28
#include <socket_io.h>
 
29
#include <version.h>
 
30
 
 
31
#include <NdbOut.hpp>
 
32
#include <SocketServer.hpp>
 
33
#include <SocketClient.hpp>
 
34
#include <Parser.hpp>
 
35
#include <OutputStream.hpp>
 
36
#include <InputStream.hpp>
 
37
 
 
38
#include <base64.h>
 
39
 
 
40
#define MGM_CMD(name, fun, desc) \
 
41
 { name, \
 
42
   0, \
 
43
   ParserRow<ParserDummy>::Cmd, \
 
44
   ParserRow<ParserDummy>::String, \
 
45
   ParserRow<ParserDummy>::Optional, \
 
46
   ParserRow<ParserDummy>::IgnoreMinMax, \
 
47
   0, 0, \
 
48
   fun, \
 
49
   desc, 0 }
 
50
 
 
51
#define MGM_ARG(name, type, opt, desc) \
 
52
 { name, \
 
53
   0, \
 
54
   ParserRow<ParserDummy>::Arg, \
 
55
   ParserRow<ParserDummy>::type, \
 
56
   ParserRow<ParserDummy>::opt, \
 
57
   ParserRow<ParserDummy>::IgnoreMinMax, \
 
58
   0, 0, \
 
59
   0, \
 
60
   desc, 0 }
 
61
 
 
62
#define MGM_END() \
 
63
 { 0, \
 
64
   0, \
 
65
   ParserRow<ParserDummy>::Arg, \
 
66
   ParserRow<ParserDummy>::Int, \
 
67
   ParserRow<ParserDummy>::Optional, \
 
68
   ParserRow<ParserDummy>::IgnoreMinMax, \
 
69
   0, 0, \
 
70
   0, \
 
71
   0, 0 }
 
72
 
 
73
class ParserDummy : private SocketServer::Session 
 
74
{
 
75
public:
 
76
  ParserDummy(NDB_SOCKET_TYPE sock);
 
77
};
 
78
 
 
79
ParserDummy::ParserDummy(NDB_SOCKET_TYPE sock) : SocketServer::Session(sock) 
 
80
{
 
81
}
 
82
 
 
83
typedef Parser<ParserDummy> Parser_t;
 
84
 
 
85
#define NDB_MGM_MAX_ERR_DESC_SIZE 256
 
86
 
 
87
struct ndb_mgm_handle {
 
88
  int cfg_i;
 
89
  
 
90
  int connected;
 
91
  int last_error;
 
92
  int last_error_line;
 
93
  char last_error_desc[NDB_MGM_MAX_ERR_DESC_SIZE];
 
94
  unsigned int timeout;
 
95
 
 
96
  NDB_SOCKET_TYPE socket;
 
97
 
 
98
  LocalConfig cfg;
 
99
 
 
100
#ifdef MGMAPI_LOG
 
101
  FILE* logfile;
 
102
#endif
 
103
  FILE *errstream;
 
104
  char *m_name;
 
105
  int mgmd_version_major;
 
106
  int mgmd_version_minor;
 
107
  int mgmd_version_build;
 
108
  char * m_bindaddress;
 
109
};
 
110
 
 
111
#define SET_ERROR(h, e, s) setError(h, e, __LINE__, s)
 
112
 
 
113
static
 
114
void
 
115
setError(NdbMgmHandle h, int error, int error_line, const char * msg, ...){
 
116
 
 
117
  h->last_error = error;  \
 
118
  h->last_error_line = error_line;
 
119
 
 
120
  va_list ap;
 
121
  va_start(ap, msg);
 
122
  BaseString::vsnprintf(h->last_error_desc, sizeof(h->last_error_desc), msg, ap);
 
123
  va_end(ap);
 
124
}
 
125
 
 
126
#define CHECK_HANDLE(handle, ret) \
 
127
  if(handle == 0) { \
 
128
    SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_HANDLE, ""); \
 
129
    return ret; \
 
130
  } 
 
131
 
 
132
#define CHECK_CONNECTED(handle, ret) \
 
133
  if (handle->connected != 1) { \
 
134
    SET_ERROR(handle, NDB_MGM_SERVER_NOT_CONNECTED , ""); \
 
135
    return ret; \
 
136
  }
 
137
 
 
138
#define CHECK_REPLY(handle, reply, ret) \
 
139
  if(reply == NULL) { \
 
140
    if(!handle->last_error) \
 
141
      SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
 
142
    return ret; \
 
143
  }
 
144
 
 
145
#define DBUG_CHECK_REPLY(handle, reply, ret) \
 
146
  if (reply == NULL) { \
 
147
    if(!handle->last_error) \
 
148
      SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
 
149
    DBUG_RETURN(ret);                                    \
 
150
  }
 
151
 
 
152
#define CHECK_TIMEDOUT(in, out) \
 
153
  if(in.timedout() || out.timedout()) \
 
154
    SET_ERROR(handle, ETIMEDOUT, \
 
155
              "Time out talking to management server");
 
156
 
 
157
#define CHECK_TIMEDOUT_RET(h, in, out, ret) \
 
158
  if(in.timedout() || out.timedout()) { \
 
159
    SET_ERROR(handle, ETIMEDOUT, \
 
160
              "Time out talking to management server"); \
 
161
    ndb_mgm_disconnect_quiet(h); \
 
162
    return ret; \
 
163
  }
 
164
 
 
165
#define DBUG_CHECK_TIMEDOUT_RET(h, in, out, ret) \
 
166
  if(in.timedout() || out.timedout()) { \
 
167
    SET_ERROR(handle, ETIMEDOUT, \
 
168
              "Time out talking to management server"); \
 
169
    ndb_mgm_disconnect_quiet(h); \
 
170
    DBUG_RETURN(ret); \
 
171
  }
 
172
 
 
173
/*****************************************************************************
 
174
 * Handles
 
175
 *****************************************************************************/
 
176
 
 
177
extern "C"
 
178
NdbMgmHandle
 
179
ndb_mgm_create_handle()
 
180
{
 
181
  DBUG_ENTER("ndb_mgm_create_handle");
 
182
  NdbMgmHandle h     =
 
183
    (NdbMgmHandle)my_malloc(sizeof(ndb_mgm_handle),MYF(MY_WME));
 
184
  h->connected       = 0;
 
185
  h->last_error      = 0;
 
186
  h->last_error_line = 0;
 
187
  h->socket          = NDB_INVALID_SOCKET;
 
188
  h->timeout         = 60000;
 
189
  h->cfg_i           = -1;
 
190
  h->errstream       = stdout;
 
191
  h->m_name          = 0;
 
192
  h->m_bindaddress   = 0;
 
193
 
 
194
  strncpy(h->last_error_desc, "No error", NDB_MGM_MAX_ERR_DESC_SIZE);
 
195
 
 
196
  new (&(h->cfg)) LocalConfig;
 
197
  h->cfg.init(0, 0);
 
198
 
 
199
#ifdef MGMAPI_LOG
 
200
  h->logfile = 0;
 
201
#endif
 
202
 
 
203
  h->mgmd_version_major= -1;
 
204
  h->mgmd_version_minor= -1;
 
205
  h->mgmd_version_build= -1;
 
206
 
 
207
  DBUG_PRINT("info", ("handle: 0x%lx", (long) h));
 
208
  DBUG_RETURN(h);
 
209
}
 
210
 
 
211
extern "C"
 
212
void
 
213
ndb_mgm_set_name(NdbMgmHandle handle, const char *name)
 
214
{
 
215
  my_free(handle->m_name);
 
216
  handle->m_name= my_strdup(name, MYF(MY_WME));
 
217
}
 
218
 
 
219
extern "C"
 
220
int
 
221
ndb_mgm_set_connectstring(NdbMgmHandle handle, const char * mgmsrv)
 
222
{
 
223
  DBUG_ENTER("ndb_mgm_set_connectstring");
 
224
  DBUG_PRINT("info", ("handle: 0x%lx", (long) handle));
 
225
  handle->cfg.~LocalConfig();
 
226
  new (&(handle->cfg)) LocalConfig;
 
227
  if (!handle->cfg.init(mgmsrv, 0) ||
 
228
      handle->cfg.ids.size() == 0)
 
229
  {
 
230
    handle->cfg.~LocalConfig();
 
231
    new (&(handle->cfg)) LocalConfig;
 
232
    handle->cfg.init(0, 0); /* reset the LocalConfig */
 
233
    SET_ERROR(handle, NDB_MGM_ILLEGAL_CONNECT_STRING, mgmsrv ? mgmsrv : "");
 
234
    DBUG_RETURN(-1);
 
235
  }
 
236
  handle->cfg_i= -1;
 
237
  DBUG_RETURN(0);
 
238
}
 
239
 
 
240
extern "C"
 
241
int
 
242
ndb_mgm_set_bindaddress(NdbMgmHandle handle, const char * arg)
 
243
{
 
244
  DBUG_ENTER("ndb_mgm_set_bindaddress");
 
245
  if (handle->m_bindaddress)
 
246
    free(handle->m_bindaddress);
 
247
 
 
248
  if (arg)
 
249
    handle->m_bindaddress = strdup(arg);
 
250
  else
 
251
    handle->m_bindaddress = 0;
 
252
 
 
253
  DBUG_RETURN(0);
 
254
}
 
255
 
 
256
/**
 
257
 * Destroy a handle
 
258
 */
 
259
extern "C"
 
260
void
 
261
ndb_mgm_destroy_handle(NdbMgmHandle * handle)
 
262
{
 
263
  DBUG_ENTER("ndb_mgm_destroy_handle");
 
264
  if(!handle)
 
265
    DBUG_VOID_RETURN;
 
266
  DBUG_PRINT("info", ("handle: 0x%lx", (long) (* handle)));
 
267
  /**
 
268
   * important! only disconnect if connected
 
269
   * other code relies on this
 
270
   */
 
271
  if((* handle)->connected){
 
272
    ndb_mgm_disconnect(* handle);
 
273
  }
 
274
#ifdef MGMAPI_LOG
 
275
  if ((* handle)->logfile != 0){
 
276
    fclose((* handle)->logfile);
 
277
    (* handle)->logfile = 0;
 
278
  }
 
279
#endif
 
280
  (*handle)->cfg.~LocalConfig();
 
281
  my_free((*handle)->m_name);
 
282
  if ((*handle)->m_bindaddress)
 
283
    free((*handle)->m_bindaddress);
 
284
  my_free(* handle);
 
285
  * handle = 0;
 
286
  DBUG_VOID_RETURN;
 
287
}
 
288
 
 
289
extern "C" 
 
290
void
 
291
ndb_mgm_set_error_stream(NdbMgmHandle handle, FILE * file)
 
292
{
 
293
  handle->errstream = file;
 
294
}
 
295
 
 
296
/*****************************************************************************
 
297
 * Error handling
 
298
 *****************************************************************************/
 
299
 
 
300
/**
 
301
 * Get latest error associated with a handle
 
302
 */
 
303
extern "C"
 
304
int
 
305
ndb_mgm_get_latest_error(const NdbMgmHandle h)
 
306
{
 
307
  return h->last_error;
 
308
}
 
309
 
 
310
extern "C"
 
311
const char *
 
312
ndb_mgm_get_latest_error_desc(const NdbMgmHandle h){
 
313
  return h->last_error_desc;
 
314
}
 
315
 
 
316
extern "C"
 
317
int
 
318
ndb_mgm_get_latest_error_line(const NdbMgmHandle h)
 
319
{
 
320
  return h->last_error_line;
 
321
}
 
322
 
 
323
extern "C"
 
324
const char *
 
325
ndb_mgm_get_latest_error_msg(const NdbMgmHandle h)
 
326
{
 
327
  for (int i=0; i<ndb_mgm_noOfErrorMsgs; i++) {
 
328
    if (ndb_mgm_error_msgs[i].code == h->last_error)
 
329
      return ndb_mgm_error_msgs[i].msg;
 
330
  }
 
331
 
 
332
  return "Error"; // Unknown Error message
 
333
}
 
334
 
 
335
/*
 
336
 * Call an operation, and return the reply
 
337
 */
 
338
static const Properties *
 
339
ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
 
340
             const char *cmd, const Properties *cmd_args) 
 
341
{
 
342
  DBUG_ENTER("ndb_mgm_call");
 
343
  DBUG_PRINT("enter",("handle->socket: %d, cmd: %s",
 
344
                      handle->socket, cmd));
 
345
  SocketOutputStream out(handle->socket, handle->timeout);
 
346
  SocketInputStream in(handle->socket, handle->timeout);
 
347
 
 
348
  out.println(cmd);
 
349
#ifdef MGMAPI_LOG
 
350
  /** 
 
351
   * Print command to  log file
 
352
   */
 
353
  FileOutputStream f(handle->logfile);
 
354
  f.println("OUT: %s", cmd);
 
355
#endif
 
356
 
 
357
  if(cmd_args != NULL) {
 
358
    Properties::Iterator iter(cmd_args);
 
359
    const char *name;
 
360
    while((name = iter.next()) != NULL) {
 
361
      PropertiesType t;
 
362
      Uint32 val_i;
 
363
      Uint64 val_64;
 
364
      BaseString val_s;
 
365
 
 
366
      cmd_args->getTypeOf(name, &t);
 
367
      switch(t) {
 
368
      case PropertiesType_Uint32:
 
369
        cmd_args->get(name, &val_i);
 
370
        out.println("%s: %d", name, val_i);
 
371
        break;
 
372
      case PropertiesType_Uint64:
 
373
        cmd_args->get(name, &val_64);
 
374
        out.println("%s: %Ld", name, val_64);
 
375
        break;
 
376
      case PropertiesType_char:
 
377
        cmd_args->get(name, val_s);
 
378
        out.println("%s: %s", name, val_s.c_str());
 
379
        break;
 
380
      case PropertiesType_Properties:
 
381
        DBUG_PRINT("info",("Ignoring PropertiesType_Properties."));
 
382
        /* Ignore */
 
383
        break;
 
384
      default:
 
385
        DBUG_PRINT("info",("Ignoring PropertiesType: %d.",t));
 
386
      }
 
387
    }
 
388
#ifdef MGMAPI_LOG
 
389
  /** 
 
390
   * Print arguments to  log file
 
391
   */
 
392
  cmd_args->print(handle->logfile, "OUT: ");
 
393
#endif
 
394
  }
 
395
  out.println("");
 
396
 
 
397
  DBUG_CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
398
 
 
399
  Parser_t::Context ctx;
 
400
  ParserDummy session(handle->socket);
 
401
  Parser_t parser(command_reply, in, true, true, true);
 
402
 
 
403
  const Properties* p = parser.parse(ctx, session);
 
404
  if (p == NULL){
 
405
    if(!ndb_mgm_is_connected(handle)) {
 
406
      DBUG_CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
407
      DBUG_RETURN(NULL);
 
408
    }
 
409
    else
 
410
    {
 
411
      DBUG_CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
412
      if(ctx.m_status==Parser_t::Eof
 
413
         || ctx.m_status==Parser_t::NoLine)
 
414
      {
 
415
        ndb_mgm_disconnect(handle);
 
416
        DBUG_CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
417
        DBUG_RETURN(NULL);
 
418
      }
 
419
      /**
 
420
       * Print some info about why the parser returns NULL
 
421
       */
 
422
      fprintf(handle->errstream,
 
423
              "Error in mgm protocol parser. cmd: >%s< status: %d curr: %s\n",
 
424
              cmd, (Uint32)ctx.m_status,
 
425
              (ctx.m_currentToken)?ctx.m_currentToken:"NULL");
 
426
      DBUG_PRINT("info",("ctx.status: %d, ctx.m_currentToken: %s",
 
427
                         ctx.m_status, ctx.m_currentToken));
 
428
    }
 
429
  }
 
430
#ifdef MGMAPI_LOG
 
431
  else {
 
432
    /** 
 
433
     * Print reply to log file
 
434
     */
 
435
    p->print(handle->logfile, "IN: ");
 
436
  }
 
437
#endif
 
438
 
 
439
  if(p && (in.timedout() || out.timedout()))
 
440
    delete p;
 
441
  DBUG_CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
442
  DBUG_RETURN(p);
 
443
}
 
444
 
 
445
/**
 
446
 * Returns true if connected
 
447
 */
 
448
extern "C"
 
449
int ndb_mgm_is_connected(NdbMgmHandle handle)
 
450
{
 
451
  if(!handle)
 
452
    return 0;
 
453
 
 
454
  if(handle->connected)
 
455
  {
 
456
    if(Ndb_check_socket_hup(handle->socket))
 
457
    {
 
458
      handle->connected= 0;
 
459
      NDB_CLOSE_SOCKET(handle->socket);
 
460
    }
 
461
  }
 
462
  return handle->connected;
 
463
}
 
464
 
 
465
extern "C"
 
466
int ndb_mgm_set_connect_timeout(NdbMgmHandle handle, unsigned int seconds)
 
467
{
 
468
  return ndb_mgm_set_timeout(handle, seconds*1000);
 
469
  return 0;
 
470
}
 
471
 
 
472
extern "C"
 
473
int ndb_mgm_set_timeout(NdbMgmHandle handle, unsigned int timeout_ms)
 
474
{
 
475
  if(!handle)
 
476
    return -1;
 
477
 
 
478
  handle->timeout= timeout_ms;
 
479
  return 0;
 
480
}
 
481
 
 
482
extern "C"
 
483
int ndb_mgm_number_of_mgmd_in_connect_string(NdbMgmHandle handle)
 
484
{
 
485
  int count=0;
 
486
  Uint32 i;
 
487
  LocalConfig &cfg= handle->cfg;
 
488
 
 
489
  for (i = 0; i < cfg.ids.size(); i++)
 
490
  {
 
491
    if (cfg.ids[i].type != MgmId_TCP)
 
492
      continue;
 
493
    count++;
 
494
  }
 
495
  return count;
 
496
}
 
497
 
 
498
/**
 
499
 * Connect to a management server
 
500
 */
 
501
extern "C"
 
502
int
 
503
ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
 
504
                int retry_delay_in_seconds, int verbose)
 
505
{
 
506
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_connect");
 
507
  CHECK_HANDLE(handle, -1);
 
508
 
 
509
  DBUG_ENTER("ndb_mgm_connect");
 
510
#ifdef MGMAPI_LOG
 
511
  /**
 
512
  * Open the log file
 
513
  */
 
514
  char logname[64];
 
515
  BaseString::snprintf(logname, 64, "mgmapi.log");
 
516
  handle->logfile = fopen(logname, "w");
 
517
#endif
 
518
  char buf[1024];
 
519
 
 
520
  /**
 
521
   * Do connect
 
522
   */
 
523
  LocalConfig &cfg= handle->cfg;
 
524
  NDB_SOCKET_TYPE sockfd= NDB_INVALID_SOCKET;
 
525
  Uint32 i;
 
526
  SocketClient s(0, 0);
 
527
  s.set_connect_timeout((handle->timeout+999)/1000);
 
528
  if (!s.init())
 
529
  {
 
530
    fprintf(handle->errstream, 
 
531
            "Unable to create socket, "
 
532
            "while trying to connect with connect string: %s\n",
 
533
            cfg.makeConnectString(buf,sizeof(buf)));
 
534
 
 
535
    setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
 
536
            "Unable to create socket, "
 
537
            "while trying to connect with connect string: %s\n",
 
538
            cfg.makeConnectString(buf,sizeof(buf)));
 
539
    DBUG_RETURN(-1);
 
540
  }
 
541
 
 
542
  if (handle->m_bindaddress)
 
543
  {
 
544
    BaseString::snprintf(buf, sizeof(buf), handle->m_bindaddress);
 
545
    unsigned short portno = 0;
 
546
    char * port = strchr(buf, ':');
 
547
    if (port != 0)
 
548
    {
 
549
      portno = atoi(port+1);
 
550
      * port = 0;
 
551
    }
 
552
    int err;
 
553
    if ((err = s.bind(buf, portno)) != 0)
 
554
    {
 
555
      fprintf(handle->errstream, 
 
556
              "Unable to bind local address %s errno: %d, "
 
557
              "while trying to connect with connect string: %s\n",
 
558
              handle->m_bindaddress, err,
 
559
              cfg.makeConnectString(buf,sizeof(buf)));
 
560
      
 
561
      setError(handle, NDB_MGM_BIND_ADDRESS, __LINE__,
 
562
               "Unable to bind local address %s errno: %d, "
 
563
               "while trying to connect with connect string: %s\n",
 
564
               handle->m_bindaddress, err,
 
565
               cfg.makeConnectString(buf,sizeof(buf)));
 
566
      DBUG_RETURN(-1);
 
567
    }
 
568
  }
 
569
  
 
570
  while (sockfd == NDB_INVALID_SOCKET)
 
571
  {
 
572
    // do all the mgmt servers
 
573
    for (i = 0; i < cfg.ids.size(); i++)
 
574
    {
 
575
      if (cfg.ids[i].type != MgmId_TCP)
 
576
        continue;
 
577
      sockfd = s.connect(cfg.ids[i].name.c_str(), cfg.ids[i].port);
 
578
      if (sockfd != NDB_INVALID_SOCKET)
 
579
        break;
 
580
    }
 
581
    if (sockfd != NDB_INVALID_SOCKET)
 
582
      break;
 
583
#ifndef DBUG_OFF
 
584
    {
 
585
      DBUG_PRINT("info",("Unable to connect with connect string: %s",
 
586
                         cfg.makeConnectString(buf,sizeof(buf))));
 
587
    }
 
588
#endif
 
589
    if (verbose > 0) {
 
590
      fprintf(handle->errstream, 
 
591
              "Unable to connect with connect string: %s\n",
 
592
              cfg.makeConnectString(buf,sizeof(buf)));
 
593
      verbose= -1;
 
594
    }
 
595
    if (no_retries == 0) {
 
596
      setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
 
597
               "Unable to connect with connect string: %s",
 
598
               cfg.makeConnectString(buf,sizeof(buf)));
 
599
      if (verbose == -2)
 
600
        fprintf(handle->errstream, ", failed.\n");
 
601
      DBUG_RETURN(-1);
 
602
    }
 
603
    if (verbose == -1) {
 
604
      fprintf(handle->errstream, "Retrying every %d seconds", 
 
605
              retry_delay_in_seconds);
 
606
      if (no_retries > 0)
 
607
        fprintf(handle->errstream, ". Attempts left:");
 
608
      else
 
609
        fprintf(handle->errstream, ", until connected.");
 
610
      fflush(handle->errstream);
 
611
      verbose= -2;
 
612
    }
 
613
    if (no_retries > 0) {
 
614
      if (verbose == -2) {
 
615
        fprintf(handle->errstream, " %d", no_retries);
 
616
        fflush(handle->errstream);
 
617
      }
 
618
      no_retries--;
 
619
    }
 
620
    NdbSleep_SecSleep(retry_delay_in_seconds);
 
621
  }
 
622
  if (verbose == -2)
 
623
  {
 
624
    fprintf(handle->errstream, "\n");
 
625
    fflush(handle->errstream);
 
626
  }
 
627
  handle->cfg_i = i;
 
628
  
 
629
  handle->socket    = sockfd;
 
630
  handle->connected = 1;
 
631
 
 
632
  DBUG_RETURN(0);
 
633
}
 
634
 
 
635
/**
 
636
 * Only used for low level testing
 
637
 * Never to be used by end user.
 
638
 * Or anybody who doesn't know exactly what they're doing.
 
639
 */
 
640
extern "C"
 
641
int
 
642
ndb_mgm_get_fd(NdbMgmHandle handle)
 
643
{
 
644
  return handle->socket;
 
645
}
 
646
 
 
647
/**
 
648
 * Disconnect from mgm server without error checking
 
649
 * Should be used internally only.
 
650
 * e.g. on timeout, we leave NdbMgmHandle disconnected
 
651
 */
 
652
extern "C"
 
653
int
 
654
ndb_mgm_disconnect_quiet(NdbMgmHandle handle)
 
655
{
 
656
  NDB_CLOSE_SOCKET(handle->socket);
 
657
  handle->socket = NDB_INVALID_SOCKET;
 
658
  handle->connected = 0;
 
659
 
 
660
  return 0;
 
661
}
 
662
 
 
663
/**
 
664
 * Disconnect from a mgm server
 
665
 */
 
666
extern "C"
 
667
int
 
668
ndb_mgm_disconnect(NdbMgmHandle handle)
 
669
{
 
670
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_disconnect");
 
671
  CHECK_HANDLE(handle, -1);
 
672
  CHECK_CONNECTED(handle, -1);
 
673
 
 
674
  return ndb_mgm_disconnect_quiet(handle);
 
675
}
 
676
 
 
677
struct ndb_mgm_type_atoi 
 
678
{
 
679
  const char * str;
 
680
  const char * alias;
 
681
  enum ndb_mgm_node_type value;
 
682
};
 
683
 
 
684
static struct ndb_mgm_type_atoi type_values[] = 
 
685
{
 
686
  { "NDB", "ndbd", NDB_MGM_NODE_TYPE_NDB},
 
687
  { "API", "mysqld", NDB_MGM_NODE_TYPE_API },
 
688
  { "MGM", "ndb_mgmd", NDB_MGM_NODE_TYPE_MGM }
 
689
};
 
690
 
 
691
const int no_of_type_values = (sizeof(type_values) / 
 
692
                               sizeof(ndb_mgm_type_atoi));
 
693
 
 
694
extern "C"
 
695
ndb_mgm_node_type
 
696
ndb_mgm_match_node_type(const char * type)
 
697
{
 
698
  if(type == 0)
 
699
    return NDB_MGM_NODE_TYPE_UNKNOWN;
 
700
  
 
701
  for(int i = 0; i<no_of_type_values; i++)
 
702
    if(strcmp(type, type_values[i].str) == 0)
 
703
      return type_values[i].value;
 
704
    else if(strcmp(type, type_values[i].alias) == 0)
 
705
      return type_values[i].value;
 
706
  
 
707
  return NDB_MGM_NODE_TYPE_UNKNOWN;
 
708
}
 
709
 
 
710
extern "C"
 
711
const char * 
 
712
ndb_mgm_get_node_type_string(enum ndb_mgm_node_type type)
 
713
{
 
714
  for(int i = 0; i<no_of_type_values; i++)
 
715
    if(type_values[i].value == type)
 
716
      return type_values[i].str;
 
717
  return 0;
 
718
}
 
719
 
 
720
extern "C"
 
721
const char * 
 
722
ndb_mgm_get_node_type_alias_string(enum ndb_mgm_node_type type, const char** str)
 
723
{
 
724
  for(int i = 0; i<no_of_type_values; i++)
 
725
    if(type_values[i].value == type)
 
726
      {
 
727
        if (str)
 
728
          *str= type_values[i].str;
 
729
        return type_values[i].alias;
 
730
      }
 
731
  return 0;
 
732
}
 
733
 
 
734
struct ndb_mgm_status_atoi {
 
735
  const char * str;
 
736
  enum ndb_mgm_node_status value;
 
737
};
 
738
 
 
739
static struct ndb_mgm_status_atoi status_values[] = 
 
740
{
 
741
  { "UNKNOWN", NDB_MGM_NODE_STATUS_UNKNOWN },
 
742
  { "NO_CONTACT", NDB_MGM_NODE_STATUS_NO_CONTACT },
 
743
  { "NOT_STARTED", NDB_MGM_NODE_STATUS_NOT_STARTED },
 
744
  { "STARTING", NDB_MGM_NODE_STATUS_STARTING },
 
745
  { "STARTED", NDB_MGM_NODE_STATUS_STARTED },
 
746
  { "SHUTTING_DOWN", NDB_MGM_NODE_STATUS_SHUTTING_DOWN },
 
747
  { "RESTARTING", NDB_MGM_NODE_STATUS_RESTARTING },
 
748
  { "SINGLE USER MODE", NDB_MGM_NODE_STATUS_SINGLEUSER }
 
749
};
 
750
 
 
751
const int no_of_status_values = (sizeof(status_values) / 
 
752
                                 sizeof(ndb_mgm_status_atoi));
 
753
 
 
754
extern "C"
 
755
ndb_mgm_node_status
 
756
ndb_mgm_match_node_status(const char * status)
 
757
{
 
758
  if(status == 0)
 
759
    return NDB_MGM_NODE_STATUS_UNKNOWN;
 
760
  
 
761
  for(int i = 0; i<no_of_status_values; i++)
 
762
    if(strcmp(status, status_values[i].str) == 0)
 
763
      return status_values[i].value;
 
764
 
 
765
  return NDB_MGM_NODE_STATUS_UNKNOWN;
 
766
}
 
767
 
 
768
extern "C"
 
769
const char * 
 
770
ndb_mgm_get_node_status_string(enum ndb_mgm_node_status status)
 
771
{
 
772
  int i;
 
773
  for(i = 0; i<no_of_status_values; i++)
 
774
    if(status_values[i].value == status)
 
775
      return status_values[i].str;
 
776
 
 
777
  for(i = 0; i<no_of_status_values; i++)
 
778
    if(status_values[i].value == NDB_MGM_NODE_STATUS_UNKNOWN)
 
779
      return status_values[i].str;
 
780
  
 
781
  return 0;
 
782
}
 
783
 
 
784
static int
 
785
status_ackumulate(struct ndb_mgm_node_state * state,
 
786
                  const char * field,
 
787
                  const char * value)
 
788
{
 
789
  if(strcmp("type", field) == 0){
 
790
    state->node_type = ndb_mgm_match_node_type(value);
 
791
  } else if(strcmp("status", field) == 0){
 
792
    state->node_status = ndb_mgm_match_node_status(value);
 
793
  } else if(strcmp("startphase", field) == 0){
 
794
    state->start_phase = atoi(value);
 
795
  } else if(strcmp("dynamic_id", field) == 0){
 
796
    state->dynamic_id = atoi(value);
 
797
  } else if(strcmp("node_group", field) == 0){
 
798
    state->node_group = atoi(value);
 
799
  } else if(strcmp("version", field) == 0){
 
800
    state->version = atoi(value);
 
801
  } else if(strcmp("connect_count", field) == 0){
 
802
    state->connect_count = atoi(value);    
 
803
  } else if(strcmp("address", field) == 0){
 
804
    strncpy(state->connect_address, value, sizeof(state->connect_address));
 
805
    state->connect_address[sizeof(state->connect_address)-1]= 0;
 
806
  } else {
 
807
    ndbout_c("Unknown field: %s", field);
 
808
  }
 
809
  return 0;
 
810
}
 
811
 
 
812
/**
 
813
 * Compare function for qsort() that sorts ndb_mgm_node_state in
 
814
 * node_id order
 
815
 */
 
816
static int
 
817
cmp_state(const void *_a, const void *_b) 
 
818
{
 
819
  struct ndb_mgm_node_state *a, *b;
 
820
 
 
821
  a = (struct ndb_mgm_node_state *)_a;
 
822
  b = (struct ndb_mgm_node_state *)_b;
 
823
 
 
824
  if (a->node_id > b->node_id)
 
825
    return 1;
 
826
  return -1;
 
827
}
 
828
 
 
829
extern "C"
 
830
struct ndb_mgm_cluster_state * 
 
831
ndb_mgm_get_status(NdbMgmHandle handle)
 
832
{
 
833
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_status");
 
834
  CHECK_HANDLE(handle, NULL);
 
835
  CHECK_CONNECTED(handle, NULL);
 
836
 
 
837
  SocketOutputStream out(handle->socket, handle->timeout);
 
838
  SocketInputStream in(handle->socket, handle->timeout);
 
839
 
 
840
  out.println("get status");
 
841
  out.println("");
 
842
 
 
843
  CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
844
 
 
845
  char buf[1024];
 
846
  if(!in.gets(buf, sizeof(buf)))
 
847
  {
 
848
    CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
849
    SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
 
850
    return NULL;
 
851
  }
 
852
  if(strcmp("node status\n", buf) != 0) {
 
853
    CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
854
    ndbout << in.timedout() << " " << out.timedout() << buf << endl;
 
855
    SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
 
856
    return NULL;
 
857
  }
 
858
  if(!in.gets(buf, sizeof(buf)))
 
859
  {
 
860
    CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
861
    SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
 
862
    return NULL;
 
863
  }
 
864
 
 
865
  BaseString tmp(buf);
 
866
  Vector<BaseString> split;
 
867
  tmp.split(split, ":");
 
868
  if(split.size() != 2){
 
869
    CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
870
    SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
 
871
    return NULL;
 
872
  }
 
873
 
 
874
  if(!(split[0].trim() == "nodes")){
 
875
    SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
 
876
    return NULL;
 
877
  }
 
878
 
 
879
  const int noOfNodes = atoi(split[1].c_str());
 
880
 
 
881
  ndb_mgm_cluster_state *state = (ndb_mgm_cluster_state*)
 
882
    malloc(sizeof(ndb_mgm_cluster_state)+
 
883
           noOfNodes*(sizeof(ndb_mgm_node_state)+sizeof("000.000.000.000#")));
 
884
 
 
885
  if(!state)
 
886
  {
 
887
    SET_ERROR(handle, NDB_MGM_OUT_OF_MEMORY,
 
888
              "Allocating ndb_mgm_cluster_state");
 
889
    return NULL;
 
890
  }
 
891
 
 
892
  state->no_of_nodes= noOfNodes;
 
893
  ndb_mgm_node_state * ptr = &state->node_states[0];
 
894
  int nodeId = 0;
 
895
  int i;
 
896
  for (i= 0; i < noOfNodes; i++) {
 
897
    state->node_states[i].connect_address[0]= 0;
 
898
  }
 
899
  i = -1; ptr--;
 
900
  for(; i<noOfNodes; ){
 
901
    if(!in.gets(buf, sizeof(buf)))
 
902
    {
 
903
      free(state);
 
904
      if(in.timedout() || out.timedout())
 
905
        SET_ERROR(handle, ETIMEDOUT,
 
906
                  "Time out talking to management server");
 
907
      else
 
908
        SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY,
 
909
                  "Probably disconnected");
 
910
      return NULL;
 
911
    }
 
912
    tmp.assign(buf);
 
913
 
 
914
    if(tmp.trim() == ""){
 
915
      break;
 
916
    }
 
917
    
 
918
    Vector<BaseString> split2;
 
919
    tmp.split(split2, ":.", 4);
 
920
    if(split2.size() != 4)
 
921
      break;
 
922
    
 
923
    const int id = atoi(split2[1].c_str());
 
924
    if(id != nodeId){
 
925
      ptr++;
 
926
      i++;
 
927
      nodeId = id;
 
928
      ptr->node_id = id;
 
929
    }
 
930
 
 
931
    split2[3].trim(" \t\n");
 
932
 
 
933
    if(status_ackumulate(ptr,split2[2].c_str(), split2[3].c_str()) != 0) {
 
934
      break;
 
935
    }
 
936
  }
 
937
 
 
938
  if(i+1 != noOfNodes){
 
939
    free(state);
 
940
    CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 
941
    SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, "Node count mismatch");
 
942
    return NULL;
 
943
  }
 
944
 
 
945
  qsort(state->node_states, state->no_of_nodes, sizeof(state->node_states[0]),
 
946
        cmp_state);
 
947
  return state;
 
948
}
 
949
 
 
950
extern "C"
 
951
int 
 
952
ndb_mgm_enter_single_user(NdbMgmHandle handle,
 
953
                          unsigned int nodeId,
 
954
                          struct ndb_mgm_reply* /*reply*/) 
 
955
{
 
956
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_enter_single_user");
 
957
  const ParserRow<ParserDummy> enter_single_reply[] = {
 
958
    MGM_CMD("enter single user reply", NULL, ""),
 
959
    MGM_ARG("result", String, Mandatory, "Error message"),
 
960
    MGM_END()
 
961
  };
 
962
  CHECK_HANDLE(handle, -1);
 
963
  CHECK_CONNECTED(handle, -1);
 
964
 
 
965
  Properties args;
 
966
  args.put("nodeId", nodeId);
 
967
  const Properties *reply;
 
968
  reply = ndb_mgm_call(handle, enter_single_reply, "enter single user", &args);
 
969
  CHECK_REPLY(handle, reply, -1);
 
970
 
 
971
  BaseString result;
 
972
  reply->get("result", result);
 
973
  if(strcmp(result.c_str(), "Ok") != 0) {
 
974
    SET_ERROR(handle, NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE, 
 
975
              result.c_str());
 
976
    delete reply;
 
977
    return -1;
 
978
  }
 
979
 
 
980
  delete reply;
 
981
  return 0;
 
982
}
 
983
 
 
984
 
 
985
extern "C"
 
986
int 
 
987
ndb_mgm_exit_single_user(NdbMgmHandle handle, struct ndb_mgm_reply* /*reply*/) 
 
988
{
 
989
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_exit_single_user");
 
990
  const ParserRow<ParserDummy> exit_single_reply[] = {
 
991
    MGM_CMD("exit single user reply", NULL, ""),
 
992
    MGM_ARG("result", String, Mandatory, "Error message"),
 
993
    MGM_END()
 
994
  };
 
995
  CHECK_HANDLE(handle, -1);
 
996
  CHECK_CONNECTED(handle, -1);
 
997
 
 
998
  const Properties *reply;
 
999
  reply = ndb_mgm_call(handle, exit_single_reply, "exit single user", 0);
 
1000
  CHECK_REPLY(handle, reply, -1);
 
1001
 
 
1002
  const char * buf;
 
1003
  reply->get("result", &buf);
 
1004
  if(strcmp(buf,"Ok")!=0) {
 
1005
    SET_ERROR(handle, NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE, buf);
 
1006
    delete reply;    
 
1007
    return -1;
 
1008
  }
 
1009
 
 
1010
  delete reply;
 
1011
  return 0;
 
1012
}
 
1013
 
 
1014
extern "C"
 
1015
int 
 
1016
ndb_mgm_stop(NdbMgmHandle handle, int no_of_nodes, const int * node_list)
 
1017
{
 
1018
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop");
 
1019
  return ndb_mgm_stop2(handle, no_of_nodes, node_list, 0);
 
1020
}
 
1021
 
 
1022
extern "C"
 
1023
int
 
1024
ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
 
1025
              int abort)
 
1026
{
 
1027
  int disconnect;
 
1028
  return ndb_mgm_stop3(handle, no_of_nodes, node_list, abort, &disconnect);
 
1029
}
 
1030
 
 
1031
 
 
1032
extern "C"
 
1033
int
 
1034
ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
 
1035
              int abort, int *disconnect)
 
1036
{
 
1037
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop3");
 
1038
  const ParserRow<ParserDummy> stop_reply_v1[] = {
 
1039
    MGM_CMD("stop reply", NULL, ""),
 
1040
    MGM_ARG("stopped", Int, Optional, "No of stopped nodes"),
 
1041
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1042
    MGM_END()
 
1043
  };
 
1044
  const ParserRow<ParserDummy> stop_reply_v2[] = {
 
1045
    MGM_CMD("stop reply", NULL, ""),
 
1046
    MGM_ARG("stopped", Int, Optional, "No of stopped nodes"),
 
1047
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1048
    MGM_ARG("disconnect", Int, Mandatory, "Need to disconnect"),
 
1049
    MGM_END()
 
1050
  };
 
1051
 
 
1052
  CHECK_HANDLE(handle, -1);
 
1053
  CHECK_CONNECTED(handle, -1);
 
1054
 
 
1055
  if(handle->mgmd_version_build==-1)
 
1056
  {
 
1057
    char verstr[50];
 
1058
    if(!ndb_mgm_get_version(handle,
 
1059
                        &(handle->mgmd_version_major),
 
1060
                        &(handle->mgmd_version_minor),
 
1061
                        &(handle->mgmd_version_build),
 
1062
                        sizeof(verstr),
 
1063
                            verstr))
 
1064
    {
 
1065
      return -1;
 
1066
    }
 
1067
  }
 
1068
  int use_v2= ((handle->mgmd_version_major==5)
 
1069
    && (
 
1070
        (handle->mgmd_version_minor==0 && handle->mgmd_version_build>=21)
 
1071
        ||(handle->mgmd_version_minor==1 && handle->mgmd_version_build>=12)
 
1072
        ||(handle->mgmd_version_minor>1)
 
1073
        )
 
1074
               )
 
1075
    || (handle->mgmd_version_major>5);
 
1076
 
 
1077
  if(no_of_nodes < -1){
 
1078
    SET_ERROR(handle, NDB_MGM_ILLEGAL_NUMBER_OF_NODES, 
 
1079
              "Negative number of nodes requested to stop");
 
1080
    return -1;
 
1081
  }
 
1082
 
 
1083
  Uint32 stoppedNoOfNodes = 0;
 
1084
  if(no_of_nodes <= 0){
 
1085
    /**
 
1086
     * All nodes should be stopped (all or just db)
 
1087
     */
 
1088
    Properties args;
 
1089
    args.put("abort", abort);
 
1090
    if(use_v2)
 
1091
      args.put("stop", (no_of_nodes==-1)?"mgm,db":"db");
 
1092
    const Properties *reply;
 
1093
    if(use_v2)
 
1094
      reply = ndb_mgm_call(handle, stop_reply_v2, "stop all", &args);
 
1095
    else
 
1096
      reply = ndb_mgm_call(handle, stop_reply_v1, "stop all", &args);
 
1097
    CHECK_REPLY(handle, reply, -1);
 
1098
 
 
1099
    if(!reply->get("stopped", &stoppedNoOfNodes)){
 
1100
      SET_ERROR(handle, NDB_MGM_STOP_FAILED, 
 
1101
                "Could not get number of stopped nodes from mgm server");
 
1102
      delete reply;
 
1103
      return -1;
 
1104
    }
 
1105
    if(use_v2)
 
1106
      reply->get("disconnect", (Uint32*)disconnect);
 
1107
    else
 
1108
      *disconnect= 0;
 
1109
    BaseString result;
 
1110
    reply->get("result", result);
 
1111
    if(strcmp(result.c_str(), "Ok") != 0) {
 
1112
      SET_ERROR(handle, NDB_MGM_STOP_FAILED, result.c_str());
 
1113
      delete reply;
 
1114
      return -1;
 
1115
    }
 
1116
    delete reply;
 
1117
    return stoppedNoOfNodes;
 
1118
  }
 
1119
 
 
1120
  /**
 
1121
   * A list of database nodes should be stopped
 
1122
   */
 
1123
  Properties args;
 
1124
 
 
1125
  BaseString node_list_str;
 
1126
  node_list_str.assfmt("%d", node_list[0]);
 
1127
  for(int node = 1; node < no_of_nodes; node++)
 
1128
    node_list_str.appfmt(" %d", node_list[node]);
 
1129
  
 
1130
  args.put("node", node_list_str.c_str());
 
1131
  args.put("abort", abort);
 
1132
 
 
1133
  const Properties *reply;
 
1134
  if(use_v2)
 
1135
    reply = ndb_mgm_call(handle, stop_reply_v2, "stop v2", &args);
 
1136
  else
 
1137
    reply = ndb_mgm_call(handle, stop_reply_v1, "stop", &args);
 
1138
 
 
1139
  CHECK_REPLY(handle, reply, stoppedNoOfNodes);
 
1140
  if(!reply->get("stopped", &stoppedNoOfNodes)){
 
1141
    SET_ERROR(handle, NDB_MGM_STOP_FAILED, 
 
1142
              "Could not get number of stopped nodes from mgm server");
 
1143
    delete reply;
 
1144
    return -1;
 
1145
  }
 
1146
  if(use_v2)
 
1147
    reply->get("disconnect", (Uint32*)disconnect);
 
1148
  else
 
1149
    *disconnect= 0;
 
1150
  BaseString result;
 
1151
  reply->get("result", result);
 
1152
  if(strcmp(result.c_str(), "Ok") != 0) {
 
1153
    SET_ERROR(handle, NDB_MGM_STOP_FAILED, result.c_str());
 
1154
    delete reply;
 
1155
    return -1;
 
1156
  }
 
1157
  delete reply;
 
1158
  return stoppedNoOfNodes;
 
1159
}
 
1160
 
 
1161
extern "C"
 
1162
int
 
1163
ndb_mgm_restart(NdbMgmHandle handle, int no_of_nodes, const int *node_list) 
 
1164
{
 
1165
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart");
 
1166
  return ndb_mgm_restart2(handle, no_of_nodes, node_list, 0, 0, 0);
 
1167
}
 
1168
 
 
1169
extern "C"
 
1170
int
 
1171
ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
 
1172
                 int initial, int nostart, int abort)
 
1173
{
 
1174
  int disconnect;
 
1175
 
 
1176
  return ndb_mgm_restart3(handle, no_of_nodes, node_list, initial, nostart,
 
1177
                          abort, &disconnect);
 
1178
}
 
1179
 
 
1180
extern "C"
 
1181
int
 
1182
ndb_mgm_restart3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
 
1183
                 int initial, int nostart, int abort, int *disconnect)
 
1184
{
 
1185
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart3");
 
1186
  Uint32 restarted = 0;
 
1187
  const ParserRow<ParserDummy> restart_reply_v1[] = {
 
1188
    MGM_CMD("restart reply", NULL, ""),
 
1189
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1190
    MGM_ARG("restarted", Int, Optional, "No of restarted nodes"),
 
1191
    MGM_END()
 
1192
  };
 
1193
  const ParserRow<ParserDummy> restart_reply_v2[] = {
 
1194
    MGM_CMD("restart reply", NULL, ""),
 
1195
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1196
    MGM_ARG("restarted", Int, Optional, "No of restarted nodes"),
 
1197
    MGM_ARG("disconnect", Int, Optional, "Disconnect to apply"),
 
1198
    MGM_END()
 
1199
  };
 
1200
 
 
1201
  CHECK_HANDLE(handle, -1);
 
1202
  CHECK_CONNECTED(handle, -1);
 
1203
 
 
1204
  if(handle->mgmd_version_build==-1)
 
1205
  {
 
1206
    char verstr[50];
 
1207
    if(!ndb_mgm_get_version(handle,
 
1208
                        &(handle->mgmd_version_major),
 
1209
                        &(handle->mgmd_version_minor),
 
1210
                        &(handle->mgmd_version_build),
 
1211
                        sizeof(verstr),
 
1212
                            verstr))
 
1213
    {
 
1214
      return -1;
 
1215
    }
 
1216
  }
 
1217
  int use_v2= ((handle->mgmd_version_major==5)
 
1218
    && (
 
1219
        (handle->mgmd_version_minor==0 && handle->mgmd_version_build>=21)
 
1220
        ||(handle->mgmd_version_minor==1 && handle->mgmd_version_build>=12)
 
1221
        ||(handle->mgmd_version_minor>1)
 
1222
        )
 
1223
               )
 
1224
    || (handle->mgmd_version_major>5);
 
1225
 
 
1226
  if(no_of_nodes < 0){
 
1227
    SET_ERROR(handle, NDB_MGM_RESTART_FAILED, 
 
1228
              "Restart requested of negative number of nodes");
 
1229
    return -1;
 
1230
  }
 
1231
  
 
1232
  if(no_of_nodes == 0) {
 
1233
    Properties args;    
 
1234
    args.put("abort", abort);
 
1235
    args.put("initialstart", initial);
 
1236
    args.put("nostart", nostart);
 
1237
    const Properties *reply;
 
1238
    const int timeout = handle->timeout;
 
1239
    handle->timeout= 5*60*1000; // 5 minutes
 
1240
    reply = ndb_mgm_call(handle, restart_reply_v1, "restart all", &args);
 
1241
    handle->timeout= timeout;
 
1242
    CHECK_REPLY(handle, reply, -1);
 
1243
 
 
1244
    BaseString result;
 
1245
    reply->get("result", result);
 
1246
    if(strcmp(result.c_str(), "Ok") != 0) {
 
1247
      SET_ERROR(handle, NDB_MGM_RESTART_FAILED, result.c_str());
 
1248
      delete reply;
 
1249
      return -1;
 
1250
    }
 
1251
    if(!reply->get("restarted", &restarted)){
 
1252
      SET_ERROR(handle, NDB_MGM_RESTART_FAILED, 
 
1253
                "Could not get restarted number of nodes from mgm server");
 
1254
      delete reply;
 
1255
      return -1;
 
1256
    }
 
1257
    delete reply;
 
1258
    return restarted;
 
1259
  }      
 
1260
 
 
1261
  BaseString node_list_str;
 
1262
  node_list_str.assfmt("%d", node_list[0]);
 
1263
  for(int node = 1; node < no_of_nodes; node++)
 
1264
    node_list_str.appfmt(" %d", node_list[node]);
 
1265
 
 
1266
  Properties args;
 
1267
  
 
1268
  args.put("node", node_list_str.c_str());
 
1269
  args.put("abort", abort);
 
1270
  args.put("initialstart", initial);
 
1271
  args.put("nostart", nostart);
 
1272
 
 
1273
  const Properties *reply;
 
1274
  const int timeout = handle->timeout;
 
1275
  handle->timeout= 5*60*1000; // 5 minutes
 
1276
  if(use_v2)
 
1277
    reply = ndb_mgm_call(handle, restart_reply_v2, "restart node v2", &args);
 
1278
  else
 
1279
    reply = ndb_mgm_call(handle, restart_reply_v1, "restart node", &args);
 
1280
  handle->timeout= timeout;
 
1281
  if(reply != NULL) {
 
1282
    BaseString result;
 
1283
    reply->get("result", result);
 
1284
    if(strcmp(result.c_str(), "Ok") != 0) {
 
1285
      SET_ERROR(handle, NDB_MGM_RESTART_FAILED, result.c_str());
 
1286
      delete reply;
 
1287
      return -1;
 
1288
    }
 
1289
    reply->get("restarted", &restarted);
 
1290
    if(use_v2)
 
1291
      reply->get("disconnect", (Uint32*)disconnect);
 
1292
    else
 
1293
      *disconnect= 0;
 
1294
    delete reply;
 
1295
  } 
 
1296
  
 
1297
  return restarted;
 
1298
}
 
1299
 
 
1300
static const char *clusterlog_severity_names[]=
 
1301
  { "enabled", "debug", "info", "warning", "error", "critical", "alert" };
 
1302
 
 
1303
struct ndb_mgm_event_severities 
 
1304
{
 
1305
  const char* name;
 
1306
  enum ndb_mgm_event_severity severity;
 
1307
} clusterlog_severities[] = {
 
1308
  { clusterlog_severity_names[0], NDB_MGM_EVENT_SEVERITY_ON },
 
1309
  { clusterlog_severity_names[1], NDB_MGM_EVENT_SEVERITY_DEBUG },
 
1310
  { clusterlog_severity_names[2], NDB_MGM_EVENT_SEVERITY_INFO },
 
1311
  { clusterlog_severity_names[3], NDB_MGM_EVENT_SEVERITY_WARNING },
 
1312
  { clusterlog_severity_names[4], NDB_MGM_EVENT_SEVERITY_ERROR },
 
1313
  { clusterlog_severity_names[5], NDB_MGM_EVENT_SEVERITY_CRITICAL },
 
1314
  { clusterlog_severity_names[6], NDB_MGM_EVENT_SEVERITY_ALERT },
 
1315
  { "all",                        NDB_MGM_EVENT_SEVERITY_ALL },
 
1316
  { 0,                            NDB_MGM_ILLEGAL_EVENT_SEVERITY },
 
1317
};
 
1318
 
 
1319
extern "C"
 
1320
ndb_mgm_event_severity
 
1321
ndb_mgm_match_event_severity(const char * name)
 
1322
{
 
1323
  if(name == 0)
 
1324
    return NDB_MGM_ILLEGAL_EVENT_SEVERITY;
 
1325
  
 
1326
  for(int i = 0; clusterlog_severities[i].name !=0 ; i++)
 
1327
    if(strcasecmp(name, clusterlog_severities[i].name) == 0)
 
1328
      return clusterlog_severities[i].severity;
 
1329
 
 
1330
  return NDB_MGM_ILLEGAL_EVENT_SEVERITY;
 
1331
}
 
1332
 
 
1333
extern "C"
 
1334
const char * 
 
1335
ndb_mgm_get_event_severity_string(enum ndb_mgm_event_severity severity)
 
1336
{
 
1337
  int i= (int)severity;
 
1338
  if (i >= 0 && i < (int)NDB_MGM_EVENT_SEVERITY_ALL)
 
1339
    return clusterlog_severity_names[i];
 
1340
  for(i = (int)NDB_MGM_EVENT_SEVERITY_ALL; clusterlog_severities[i].name != 0; i++)
 
1341
    if(clusterlog_severities[i].severity == severity)
 
1342
      return clusterlog_severities[i].name;
 
1343
  return 0;
 
1344
}
 
1345
 
 
1346
extern "C"
 
1347
int
 
1348
ndb_mgm_get_clusterlog_severity_filter(NdbMgmHandle handle, 
 
1349
                                       struct ndb_mgm_severity* severity,
 
1350
                                       unsigned int severity_size) 
 
1351
{
 
1352
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_clusterlog_severity_filter");
 
1353
  const ParserRow<ParserDummy> getinfo_reply[] = {
 
1354
    MGM_CMD("clusterlog", NULL, ""),
 
1355
    MGM_ARG(clusterlog_severity_names[0], Int, Mandatory, ""),
 
1356
    MGM_ARG(clusterlog_severity_names[1], Int, Mandatory, ""),
 
1357
    MGM_ARG(clusterlog_severity_names[2], Int, Mandatory, ""),
 
1358
    MGM_ARG(clusterlog_severity_names[3], Int, Mandatory, ""),
 
1359
    MGM_ARG(clusterlog_severity_names[4], Int, Mandatory, ""),
 
1360
    MGM_ARG(clusterlog_severity_names[5], Int, Mandatory, ""),
 
1361
    MGM_ARG(clusterlog_severity_names[6], Int, Mandatory, ""),
 
1362
  };
 
1363
  CHECK_HANDLE(handle, -1);
 
1364
  CHECK_CONNECTED(handle, -1);
 
1365
 
 
1366
  Properties args;
 
1367
  const Properties *reply;
 
1368
  reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args);
 
1369
  CHECK_REPLY(handle, reply, -1);
 
1370
  
 
1371
  for(unsigned int i=0; i < severity_size; i++) {
 
1372
    reply->get(clusterlog_severity_names[severity[i].category], &severity[i].value);
 
1373
  }
 
1374
  return severity_size;
 
1375
}
 
1376
 
 
1377
extern "C"
 
1378
const unsigned int *
 
1379
ndb_mgm_get_clusterlog_severity_filter_old(NdbMgmHandle handle) 
 
1380
{
 
1381
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_clusterlog_severity_filter");
 
1382
  static unsigned int enabled[(int)NDB_MGM_EVENT_SEVERITY_ALL]=
 
1383
    {0,0,0,0,0,0,0};
 
1384
  const ParserRow<ParserDummy> getinfo_reply[] = {
 
1385
    MGM_CMD("clusterlog", NULL, ""),
 
1386
    MGM_ARG(clusterlog_severity_names[0], Int, Mandatory, ""),
 
1387
    MGM_ARG(clusterlog_severity_names[1], Int, Mandatory, ""),
 
1388
    MGM_ARG(clusterlog_severity_names[2], Int, Mandatory, ""),
 
1389
    MGM_ARG(clusterlog_severity_names[3], Int, Mandatory, ""),
 
1390
    MGM_ARG(clusterlog_severity_names[4], Int, Mandatory, ""),
 
1391
    MGM_ARG(clusterlog_severity_names[5], Int, Mandatory, ""),
 
1392
    MGM_ARG(clusterlog_severity_names[6], Int, Mandatory, ""),
 
1393
  };
 
1394
  CHECK_HANDLE(handle, NULL);
 
1395
  CHECK_CONNECTED(handle, NULL);
 
1396
 
 
1397
  Properties args;
 
1398
  const Properties *reply;
 
1399
  reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args);
 
1400
  CHECK_REPLY(handle, reply, NULL);
 
1401
  
 
1402
  for(int i=0; i < (int)NDB_MGM_EVENT_SEVERITY_ALL; i++) {
 
1403
    reply->get(clusterlog_severity_names[i], &enabled[i]);
 
1404
  }
 
1405
  return enabled;
 
1406
}
 
1407
 
 
1408
extern "C"
 
1409
int 
 
1410
ndb_mgm_set_clusterlog_severity_filter(NdbMgmHandle handle, 
 
1411
                                       enum ndb_mgm_event_severity severity,
 
1412
                                       int enable,
 
1413
                                       struct ndb_mgm_reply* /*reply*/) 
 
1414
{
 
1415
  SET_ERROR(handle, NDB_MGM_NO_ERROR,
 
1416
            "Executing: ndb_mgm_set_clusterlog_severity_filter");
 
1417
  const ParserRow<ParserDummy> filter_reply[] = {
 
1418
    MGM_CMD("set logfilter reply", NULL, ""),
 
1419
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1420
    MGM_END()
 
1421
  };
 
1422
  int retval = -1;
 
1423
  CHECK_HANDLE(handle, -1);
 
1424
  CHECK_CONNECTED(handle, -1);
 
1425
 
 
1426
  Properties args;
 
1427
  args.put("level", severity);
 
1428
  args.put("enable", enable);
 
1429
  
 
1430
  const Properties *reply;
 
1431
  reply = ndb_mgm_call(handle, filter_reply, "set logfilter", &args);
 
1432
  CHECK_REPLY(handle, reply, retval);
 
1433
 
 
1434
  BaseString result;
 
1435
  reply->get("result", result);
 
1436
 
 
1437
  if (strcmp(result.c_str(), "1") == 0)
 
1438
    retval = 1;
 
1439
  else if (strcmp(result.c_str(), "0") == 0)
 
1440
    retval = 0;
 
1441
  else
 
1442
  {
 
1443
    SET_ERROR(handle, EINVAL, result.c_str());
 
1444
  }
 
1445
  delete reply;
 
1446
  return retval;
 
1447
}
 
1448
 
 
1449
struct ndb_mgm_event_categories 
 
1450
{
 
1451
  const char* name;
 
1452
  enum ndb_mgm_event_category category;
 
1453
} categories[] = {
 
1454
  { "STARTUP", NDB_MGM_EVENT_CATEGORY_STARTUP },
 
1455
  { "SHUTDOWN", NDB_MGM_EVENT_CATEGORY_SHUTDOWN },
 
1456
  { "STATISTICS", NDB_MGM_EVENT_CATEGORY_STATISTIC },
 
1457
  { "NODERESTART", NDB_MGM_EVENT_CATEGORY_NODE_RESTART },
 
1458
  { "CONNECTION", NDB_MGM_EVENT_CATEGORY_CONNECTION },
 
1459
  { "CHECKPOINT", NDB_MGM_EVENT_CATEGORY_CHECKPOINT },
 
1460
  { "DEBUG", NDB_MGM_EVENT_CATEGORY_DEBUG },
 
1461
  { "INFO", NDB_MGM_EVENT_CATEGORY_INFO },
 
1462
  { "ERROR", NDB_MGM_EVENT_CATEGORY_ERROR },
 
1463
  { "BACKUP", NDB_MGM_EVENT_CATEGORY_BACKUP },
 
1464
  { "CONGESTION", NDB_MGM_EVENT_CATEGORY_CONGESTION },
 
1465
  { 0, NDB_MGM_ILLEGAL_EVENT_CATEGORY }
 
1466
};
 
1467
 
 
1468
extern "C"
 
1469
ndb_mgm_event_category
 
1470
ndb_mgm_match_event_category(const char * status)
 
1471
{
 
1472
  if(status == 0)
 
1473
    return NDB_MGM_ILLEGAL_EVENT_CATEGORY;
 
1474
  
 
1475
  for(int i = 0; categories[i].name !=0 ; i++)
 
1476
    if(strcmp(status, categories[i].name) == 0)
 
1477
      return categories[i].category;
 
1478
 
 
1479
  return NDB_MGM_ILLEGAL_EVENT_CATEGORY;
 
1480
}
 
1481
 
 
1482
extern "C"
 
1483
const char * 
 
1484
ndb_mgm_get_event_category_string(enum ndb_mgm_event_category status)
 
1485
{
 
1486
  int i;
 
1487
  for(i = 0; categories[i].name != 0; i++)
 
1488
    if(categories[i].category == status)
 
1489
      return categories[i].name;
 
1490
  
 
1491
  return 0;
 
1492
}
 
1493
 
 
1494
static const char *clusterlog_names[]=
 
1495
  { "startup", "shutdown", "statistics", "checkpoint", "noderestart", "connection", "info", "warning", "error", "congestion", "debug", "backup" };
 
1496
 
 
1497
extern "C"
 
1498
int
 
1499
ndb_mgm_get_clusterlog_loglevel(NdbMgmHandle handle, 
 
1500
                                struct ndb_mgm_loglevel* loglevel,
 
1501
                                unsigned int loglevel_size)
 
1502
{
 
1503
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_clusterlog_loglevel");
 
1504
  int loglevel_count = loglevel_size;
 
1505
  const ParserRow<ParserDummy> getloglevel_reply[] = {
 
1506
    MGM_CMD("get cluster loglevel", NULL, ""),
 
1507
    MGM_ARG(clusterlog_names[0], Int, Mandatory, ""),
 
1508
    MGM_ARG(clusterlog_names[1], Int, Mandatory, ""),
 
1509
    MGM_ARG(clusterlog_names[2], Int, Mandatory, ""),
 
1510
    MGM_ARG(clusterlog_names[3], Int, Mandatory, ""),
 
1511
    MGM_ARG(clusterlog_names[4], Int, Mandatory, ""),
 
1512
    MGM_ARG(clusterlog_names[5], Int, Mandatory, ""),
 
1513
    MGM_ARG(clusterlog_names[6], Int, Mandatory, ""),
 
1514
    MGM_ARG(clusterlog_names[7], Int, Mandatory, ""),
 
1515
    MGM_ARG(clusterlog_names[8], Int, Mandatory, ""),
 
1516
    MGM_ARG(clusterlog_names[9], Int, Mandatory, ""),
 
1517
    MGM_ARG(clusterlog_names[10], Int, Mandatory, ""),
 
1518
    MGM_ARG(clusterlog_names[11], Int, Mandatory, ""),
 
1519
  };
 
1520
  CHECK_HANDLE(handle, -1);
 
1521
  CHECK_CONNECTED(handle, -1);
 
1522
 
 
1523
  Properties args;
 
1524
  const Properties *reply;
 
1525
  reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args);
 
1526
  CHECK_REPLY(handle, reply, -1);
 
1527
 
 
1528
  for(int i=0; i < loglevel_count; i++) {
 
1529
    reply->get(clusterlog_names[loglevel[i].category], &loglevel[i].value);
 
1530
  }
 
1531
  return loglevel_count;
 
1532
}
 
1533
 
 
1534
extern "C"
 
1535
const unsigned int *
 
1536
ndb_mgm_get_clusterlog_loglevel_old(NdbMgmHandle handle)
 
1537
{
 
1538
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_clusterlog_loglevel");
 
1539
  int loglevel_count = CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1 ;
 
1540
  static unsigned int loglevel[CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1] = {0,0,0,0,0,0,0,0,0,0,0,0};
 
1541
  const ParserRow<ParserDummy> getloglevel_reply[] = {
 
1542
    MGM_CMD("get cluster loglevel", NULL, ""),
 
1543
    MGM_ARG(clusterlog_names[0], Int, Mandatory, ""),
 
1544
    MGM_ARG(clusterlog_names[1], Int, Mandatory, ""),
 
1545
    MGM_ARG(clusterlog_names[2], Int, Mandatory, ""),
 
1546
    MGM_ARG(clusterlog_names[3], Int, Mandatory, ""),
 
1547
    MGM_ARG(clusterlog_names[4], Int, Mandatory, ""),
 
1548
    MGM_ARG(clusterlog_names[5], Int, Mandatory, ""),
 
1549
    MGM_ARG(clusterlog_names[6], Int, Mandatory, ""),
 
1550
    MGM_ARG(clusterlog_names[7], Int, Mandatory, ""),
 
1551
    MGM_ARG(clusterlog_names[8], Int, Mandatory, ""),
 
1552
    MGM_ARG(clusterlog_names[9], Int, Mandatory, ""),
 
1553
    MGM_ARG(clusterlog_names[10], Int, Mandatory, ""),
 
1554
    MGM_ARG(clusterlog_names[11], Int, Mandatory, ""),
 
1555
  };
 
1556
  CHECK_HANDLE(handle, NULL);
 
1557
  CHECK_CONNECTED(handle, NULL);
 
1558
 
 
1559
  Properties args;
 
1560
  const Properties *reply;
 
1561
  reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args);
 
1562
  CHECK_REPLY(handle, reply, NULL);
 
1563
 
 
1564
  for(int i=0; i < loglevel_count; i++) {
 
1565
    reply->get(clusterlog_names[i], &loglevel[i]);
 
1566
  }
 
1567
  return loglevel;
 
1568
}
 
1569
 
 
1570
extern "C"
 
1571
int 
 
1572
ndb_mgm_set_clusterlog_loglevel(NdbMgmHandle handle, int nodeId,
 
1573
                                enum ndb_mgm_event_category cat,
 
1574
                                int level,
 
1575
                                struct ndb_mgm_reply* /*reply*/) 
 
1576
{
 
1577
  SET_ERROR(handle, NDB_MGM_NO_ERROR, 
 
1578
            "Executing: ndb_mgm_set_clusterlog_loglevel");
 
1579
  const ParserRow<ParserDummy> clusterlog_reply[] = {
 
1580
    MGM_CMD("set cluster loglevel reply", NULL, ""),
 
1581
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1582
    MGM_END()
 
1583
  };
 
1584
  CHECK_HANDLE(handle, -1);
 
1585
  CHECK_CONNECTED(handle, -1);
 
1586
 
 
1587
  Properties args;
 
1588
  args.put("node", nodeId);
 
1589
  args.put("category", cat);
 
1590
  args.put("level", level);
 
1591
  
 
1592
  const Properties *reply;
 
1593
  reply = ndb_mgm_call(handle, clusterlog_reply, 
 
1594
                       "set cluster loglevel", &args);
 
1595
  CHECK_REPLY(handle, reply, -1);
 
1596
  
 
1597
  DBUG_ENTER("ndb_mgm_set_clusterlog_loglevel");
 
1598
  DBUG_PRINT("enter",("node=%d, category=%d, level=%d", nodeId, cat, level));
 
1599
 
 
1600
  BaseString result;
 
1601
  reply->get("result", result);
 
1602
  if(strcmp(result.c_str(), "Ok") != 0) {
 
1603
    SET_ERROR(handle, EINVAL, result.c_str());
 
1604
    delete reply;
 
1605
    DBUG_RETURN(-1);
 
1606
  }
 
1607
  delete reply;
 
1608
  DBUG_RETURN(0);
 
1609
}
 
1610
 
 
1611
extern "C"
 
1612
int 
 
1613
ndb_mgm_set_loglevel_node(NdbMgmHandle handle, int nodeId,
 
1614
                          enum ndb_mgm_event_category category,
 
1615
                          int level,
 
1616
                          struct ndb_mgm_reply* /*reply*/) 
 
1617
{
 
1618
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_set_loglevel_node");
 
1619
  const ParserRow<ParserDummy> loglevel_reply[] = {
 
1620
    MGM_CMD("set loglevel reply", NULL, ""),
 
1621
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1622
    MGM_END()
 
1623
  };
 
1624
  CHECK_HANDLE(handle, -1);
 
1625
  CHECK_CONNECTED(handle, -1);
 
1626
 
 
1627
  Properties args;
 
1628
  args.put("node", nodeId);
 
1629
  args.put("category", category);
 
1630
  args.put("level", level);
 
1631
  const Properties *reply;
 
1632
  reply = ndb_mgm_call(handle, loglevel_reply, "set loglevel", &args);
 
1633
  CHECK_REPLY(handle, reply, -1);
 
1634
 
 
1635
  BaseString result;
 
1636
  reply->get("result", result);
 
1637
  if(strcmp(result.c_str(), "Ok") != 0) {
 
1638
    SET_ERROR(handle, EINVAL, result.c_str());
 
1639
    delete reply;
 
1640
    return -1;
 
1641
  }
 
1642
 
 
1643
  delete reply;
 
1644
  return 0;
 
1645
}
 
1646
 
 
1647
int
 
1648
ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[],
 
1649
                              int parsable)
 
1650
{
 
1651
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_listen_event");
 
1652
  const ParserRow<ParserDummy> stat_reply[] = {
 
1653
    MGM_CMD("listen event", NULL, ""),
 
1654
    MGM_ARG("result", Int, Mandatory, "Error message"),
 
1655
    MGM_ARG("msg", String, Optional, "Error message"),
 
1656
    MGM_END()
 
1657
  };
 
1658
  CHECK_HANDLE(handle, -1);
 
1659
 
 
1660
  const char *hostname= ndb_mgm_get_connected_host(handle);
 
1661
  int port= ndb_mgm_get_connected_port(handle);
 
1662
  SocketClient s(hostname, port);
 
1663
  const NDB_SOCKET_TYPE sockfd = s.connect();
 
1664
  if (sockfd == NDB_INVALID_SOCKET) {
 
1665
    setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
 
1666
             "Unable to connect to");
 
1667
    return -1;
 
1668
  }
 
1669
 
 
1670
  Properties args;
 
1671
 
 
1672
  if (parsable)
 
1673
    args.put("parsable", parsable);
 
1674
  {
 
1675
    BaseString tmp;
 
1676
    for(int i = 0; filter[i] != 0; i += 2){
 
1677
      tmp.appfmt("%d=%d ", filter[i+1], filter[i]);
 
1678
    }
 
1679
    args.put("filter", tmp.c_str());
 
1680
  }
 
1681
 
 
1682
  int tmp = handle->socket;
 
1683
  handle->socket = sockfd;
 
1684
 
 
1685
  const Properties *reply;
 
1686
  reply = ndb_mgm_call(handle, stat_reply, "listen event", &args);
 
1687
 
 
1688
  handle->socket = tmp;
 
1689
 
 
1690
  if(reply == NULL) {
 
1691
    close(sockfd);
 
1692
    CHECK_REPLY(handle, reply, -1);
 
1693
  }
 
1694
  delete reply;
 
1695
  return sockfd;
 
1696
}
 
1697
 
 
1698
extern "C"
 
1699
int
 
1700
ndb_mgm_listen_event(NdbMgmHandle handle, const int filter[])
 
1701
{
 
1702
  return ndb_mgm_listen_event_internal(handle,filter,0);
 
1703
}
 
1704
 
 
1705
extern "C"
 
1706
int 
 
1707
ndb_mgm_dump_state(NdbMgmHandle handle, int nodeId, const int * _args,
 
1708
                   int _num_args, struct ndb_mgm_reply* /* reply */) 
 
1709
{
 
1710
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_dump_state");
 
1711
  const ParserRow<ParserDummy> dump_state_reply[] = {
 
1712
    MGM_CMD("dump state reply", NULL, ""),
 
1713
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1714
    MGM_END()
 
1715
  };
 
1716
  CHECK_HANDLE(handle, -1);
 
1717
  CHECK_CONNECTED(handle, -1);
 
1718
 
 
1719
  char buf[256];
 
1720
  buf[0] = 0;
 
1721
  for (int i = 0; i < _num_args; i++){
 
1722
    unsigned n = strlen(buf);
 
1723
    if (n + 20 > sizeof(buf)) {
 
1724
      SET_ERROR(handle, NDB_MGM_USAGE_ERROR, "arguments too long");
 
1725
      return -1;
 
1726
    }
 
1727
    sprintf(buf + n, "%s%d", i ? " " : "", _args[i]);
 
1728
  }
 
1729
 
 
1730
  Properties args;
 
1731
  args.put("node", nodeId);
 
1732
  args.put("args", buf);
 
1733
 
 
1734
  const Properties *prop;
 
1735
  prop = ndb_mgm_call(handle, dump_state_reply, "dump state", &args);
 
1736
  CHECK_REPLY(handle, prop, -1);
 
1737
 
 
1738
  BaseString result;
 
1739
  prop->get("result", result);
 
1740
  if(strcmp(result.c_str(), "Ok") != 0) {
 
1741
    SET_ERROR(handle, EINVAL, result.c_str());
 
1742
    delete prop;
 
1743
    return -1;
 
1744
  }
 
1745
 
 
1746
  delete prop;
 
1747
  return 0;
 
1748
}
 
1749
 
 
1750
extern "C"
 
1751
int 
 
1752
ndb_mgm_start_signallog(NdbMgmHandle handle, int nodeId, 
 
1753
                        struct ndb_mgm_reply* reply) 
 
1754
{
 
1755
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_start_signallog");
 
1756
  const ParserRow<ParserDummy> start_signallog_reply[] = {
 
1757
    MGM_CMD("start signallog reply", NULL, ""),
 
1758
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1759
    MGM_END()
 
1760
  };
 
1761
  int retval = -1;
 
1762
  CHECK_HANDLE(handle, -1);
 
1763
  CHECK_CONNECTED(handle, -1);
 
1764
 
 
1765
  Properties args;
 
1766
  args.put("node", nodeId);
 
1767
 
 
1768
  const Properties *prop;
 
1769
  prop = ndb_mgm_call(handle,
 
1770
                       start_signallog_reply,
 
1771
                       "start signallog",
 
1772
                       &args);
 
1773
  CHECK_REPLY(handle, prop, -1);
 
1774
 
 
1775
  if(prop != NULL) {
 
1776
    BaseString result;
 
1777
    prop->get("result", result);
 
1778
    if(strcmp(result.c_str(), "Ok") == 0) {
 
1779
      retval = 0;
 
1780
    } else {
 
1781
      SET_ERROR(handle, EINVAL, result.c_str());
 
1782
      retval = -1;
 
1783
    }
 
1784
    delete prop;
 
1785
  }
 
1786
 
 
1787
  return retval;
 
1788
}
 
1789
 
 
1790
extern "C"
 
1791
int 
 
1792
ndb_mgm_stop_signallog(NdbMgmHandle handle, int nodeId,
 
1793
                       struct ndb_mgm_reply* reply) 
 
1794
{
 
1795
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop_signallog");
 
1796
  const ParserRow<ParserDummy> stop_signallog_reply[] = {
 
1797
    MGM_CMD("stop signallog reply", NULL, ""),
 
1798
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1799
    MGM_END()
 
1800
  };
 
1801
  int retval = -1;
 
1802
  CHECK_HANDLE(handle, -1);
 
1803
  CHECK_CONNECTED(handle, -1);
 
1804
  
 
1805
  Properties args;
 
1806
  args.put("node", nodeId);
 
1807
 
 
1808
  const Properties *prop;
 
1809
  prop = ndb_mgm_call(handle, stop_signallog_reply, "stop signallog", &args);
 
1810
  CHECK_REPLY(handle, prop, -1);
 
1811
 
 
1812
  if(prop != NULL) {
 
1813
    BaseString result;
 
1814
    prop->get("result", result);
 
1815
    if(strcmp(result.c_str(), "Ok") == 0) {
 
1816
      retval = 0;
 
1817
    } else {
 
1818
      SET_ERROR(handle, EINVAL, result.c_str());
 
1819
      retval = -1;
 
1820
    }
 
1821
    delete prop;
 
1822
  }
 
1823
 
 
1824
  return retval;
 
1825
}
 
1826
 
 
1827
struct ndb_mgm_signal_log_modes 
 
1828
{
 
1829
  const char* name;
 
1830
  enum ndb_mgm_signal_log_mode mode;
 
1831
};
 
1832
 
 
1833
extern "C"
 
1834
int 
 
1835
ndb_mgm_log_signals(NdbMgmHandle handle, int nodeId, 
 
1836
                    enum ndb_mgm_signal_log_mode mode, 
 
1837
                    const char* blockNames,
 
1838
                    struct ndb_mgm_reply* reply) 
 
1839
{
 
1840
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_log_signals");
 
1841
  const ParserRow<ParserDummy> stop_signallog_reply[] = {
 
1842
    MGM_CMD("log signals reply", NULL, ""),
 
1843
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1844
    MGM_END()
 
1845
  };
 
1846
  int retval = -1;
 
1847
  CHECK_HANDLE(handle, -1);
 
1848
  CHECK_CONNECTED(handle, -1);
 
1849
 
 
1850
  Properties args;
 
1851
  args.put("node", nodeId);
 
1852
  args.put("blocks", blockNames);
 
1853
 
 
1854
  switch(mode) {
 
1855
  case NDB_MGM_SIGNAL_LOG_MODE_IN:
 
1856
    args.put("in", (Uint32)1);
 
1857
    args.put("out", (Uint32)0);
 
1858
    break;
 
1859
  case NDB_MGM_SIGNAL_LOG_MODE_OUT:
 
1860
    args.put("in", (Uint32)0);
 
1861
    args.put("out", (Uint32)1);
 
1862
    break;
 
1863
  case NDB_MGM_SIGNAL_LOG_MODE_INOUT:
 
1864
    args.put("in", (Uint32)1);
 
1865
    args.put("out", (Uint32)1);
 
1866
    break;
 
1867
  case NDB_MGM_SIGNAL_LOG_MODE_OFF:
 
1868
    args.put("in", (Uint32)0);
 
1869
    args.put("out", (Uint32)0);
 
1870
    break;
 
1871
  }
 
1872
 
 
1873
  const Properties *prop;
 
1874
  prop = ndb_mgm_call(handle, stop_signallog_reply, "log signals", &args);
 
1875
  CHECK_REPLY(handle, prop, -1);
 
1876
 
 
1877
  if(prop != NULL) {
 
1878
    BaseString result;
 
1879
    prop->get("result", result);
 
1880
    if(strcmp(result.c_str(), "Ok") == 0) {
 
1881
      retval = 0;
 
1882
    } else {
 
1883
      SET_ERROR(handle, EINVAL, result.c_str());
 
1884
      retval = -1;
 
1885
    }
 
1886
    delete prop;
 
1887
  }
 
1888
 
 
1889
  return retval;
 
1890
}
 
1891
 
 
1892
extern "C"
 
1893
int 
 
1894
ndb_mgm_set_trace(NdbMgmHandle handle, int nodeId, int traceNumber,
 
1895
                  struct ndb_mgm_reply* reply) 
 
1896
{
 
1897
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_set_trace");
 
1898
  const ParserRow<ParserDummy> set_trace_reply[] = {
 
1899
    MGM_CMD("set trace reply", NULL, ""),
 
1900
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1901
    MGM_END()
 
1902
  };
 
1903
  int retval = -1;
 
1904
  CHECK_HANDLE(handle, -1);
 
1905
  CHECK_CONNECTED(handle, -1);
 
1906
 
 
1907
  Properties args;
 
1908
  args.put("node", nodeId);
 
1909
  args.put("trace", traceNumber);
 
1910
 
 
1911
  const Properties *prop;
 
1912
  prop = ndb_mgm_call(handle, set_trace_reply, "set trace", &args);
 
1913
  CHECK_REPLY(handle, prop, -1);
 
1914
 
 
1915
  if(prop != NULL) {
 
1916
    BaseString result;
 
1917
    prop->get("result", result);
 
1918
    if(strcmp(result.c_str(), "Ok") == 0) {
 
1919
      retval = 0;
 
1920
    } else {
 
1921
      SET_ERROR(handle, EINVAL, result.c_str());
 
1922
      retval = -1;
 
1923
    }
 
1924
    delete prop;
 
1925
  }
 
1926
 
 
1927
  return retval;
 
1928
}
 
1929
 
 
1930
extern "C"
 
1931
int 
 
1932
ndb_mgm_insert_error(NdbMgmHandle handle, int nodeId, int errorCode,
 
1933
                     struct ndb_mgm_reply* reply) 
 
1934
{
 
1935
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_insert_error");
 
1936
  const ParserRow<ParserDummy> insert_error_reply[] = {
 
1937
    MGM_CMD("insert error reply", NULL, ""),
 
1938
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1939
    MGM_END()
 
1940
  };
 
1941
  int retval = -1;
 
1942
  CHECK_HANDLE(handle, -1);
 
1943
  CHECK_CONNECTED(handle, -1);
 
1944
 
 
1945
  Properties args;
 
1946
  args.put("node", nodeId);
 
1947
  args.put("error", errorCode);
 
1948
 
 
1949
  const Properties *prop;
 
1950
  prop = ndb_mgm_call(handle, insert_error_reply, "insert error", &args);
 
1951
  CHECK_REPLY(handle, prop, -1);
 
1952
 
 
1953
  if(prop != NULL) {
 
1954
    BaseString result;
 
1955
    prop->get("result", result);
 
1956
    if(strcmp(result.c_str(), "Ok") == 0) {
 
1957
      retval = 0;
 
1958
    } else {
 
1959
      SET_ERROR(handle, EINVAL, result.c_str());
 
1960
      retval = -1;
 
1961
    }
 
1962
    delete prop;
 
1963
  }
 
1964
 
 
1965
  return retval;
 
1966
}
 
1967
 
 
1968
extern "C"
 
1969
int 
 
1970
ndb_mgm_start(NdbMgmHandle handle, int no_of_nodes, const int * node_list)
 
1971
{
 
1972
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_start");
 
1973
  const ParserRow<ParserDummy> start_reply[] = {
 
1974
    MGM_CMD("start reply", NULL, ""),
 
1975
    MGM_ARG("started", Int, Optional, "No of started nodes"),
 
1976
    MGM_ARG("result", String, Mandatory, "Error message"),
 
1977
    MGM_END()
 
1978
  };
 
1979
  int started = 0;
 
1980
  CHECK_HANDLE(handle, -1);
 
1981
  CHECK_CONNECTED(handle, -1);
 
1982
 
 
1983
  if(no_of_nodes < 0){
 
1984
    SET_ERROR(handle, EINVAL, "");
 
1985
    return -1;
 
1986
  }
 
1987
 
 
1988
  if(no_of_nodes == 0){
 
1989
    Properties args;
 
1990
    const Properties *reply;
 
1991
    reply = ndb_mgm_call(handle, start_reply, "start all", &args);
 
1992
    CHECK_REPLY(handle, reply, -1);
 
1993
 
 
1994
    Uint32 count = 0;
 
1995
    if(!reply->get("started", &count)){
 
1996
      delete reply;
 
1997
      return -1;
 
1998
    }
 
1999
    delete reply;
 
2000
    return count;
 
2001
  }
 
2002
 
 
2003
  for(int node = 0; node < no_of_nodes; node++) {
 
2004
    Properties args;
 
2005
    args.put("node", node_list[node]);
 
2006
 
 
2007
    const Properties *reply;
 
2008
    reply = ndb_mgm_call(handle, start_reply, "start", &args);
 
2009
 
 
2010
    if(reply != NULL) {
 
2011
      BaseString result;
 
2012
      reply->get("result", result);
 
2013
      if(strcmp(result.c_str(), "Ok") == 0) {
 
2014
        started++;
 
2015
      } else {
 
2016
        SET_ERROR(handle, EINVAL, result.c_str());
 
2017
        delete reply;
 
2018
        return -1;
 
2019
      }
 
2020
    }
 
2021
    delete reply;
 
2022
  }
 
2023
 
 
2024
  return started;
 
2025
}
 
2026
 
 
2027
/*****************************************************************************
 
2028
 * Backup
 
2029
 *****************************************************************************/
 
2030
extern "C"
 
2031
int 
 
2032
ndb_mgm_start_backup(NdbMgmHandle handle, int wait_completed,
 
2033
                     unsigned int* _backup_id,
 
2034
                     struct ndb_mgm_reply* /*reply*/) 
 
2035
{
 
2036
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_start_backup");
 
2037
  const ParserRow<ParserDummy> start_backup_reply[] = {
 
2038
    MGM_CMD("start backup reply", NULL, ""),
 
2039
    MGM_ARG("result", String, Mandatory, "Error message"),
 
2040
    MGM_ARG("id", Int, Optional, "Id of the started backup"),
 
2041
    MGM_END()
 
2042
  };
 
2043
  CHECK_HANDLE(handle, -1);
 
2044
  CHECK_CONNECTED(handle, -1);
 
2045
 
 
2046
  Properties args;
 
2047
  args.put("completed", wait_completed);
 
2048
  const Properties *reply;
 
2049
  { // start backup can take some time, set timeout high
 
2050
    Uint64 old_timeout= handle->timeout;
 
2051
    if (wait_completed == 2)
 
2052
      handle->timeout= 48*60*60*1000; // 48 hours
 
2053
    else if (wait_completed == 1)
 
2054
      handle->timeout= 10*60*1000; // 10 minutes
 
2055
    reply = ndb_mgm_call(handle, start_backup_reply, "start backup", &args);
 
2056
    handle->timeout= old_timeout;
 
2057
  }
 
2058
  CHECK_REPLY(handle, reply, -1);
 
2059
 
 
2060
  BaseString result;
 
2061
  reply->get("result", result);
 
2062
  reply->get("id", _backup_id);
 
2063
  if(strcmp(result.c_str(), "Ok") != 0) {
 
2064
    SET_ERROR(handle, NDB_MGM_COULD_NOT_START_BACKUP, result.c_str());
 
2065
    delete reply;
 
2066
    return -1;
 
2067
  }
 
2068
 
 
2069
  delete reply;
 
2070
  return 0;
 
2071
}
 
2072
 
 
2073
extern "C"
 
2074
int
 
2075
ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId,
 
2076
                     struct ndb_mgm_reply* /*reply*/) 
 
2077
{
 
2078
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_abort_backup");
 
2079
  const ParserRow<ParserDummy> stop_backup_reply[] = {
 
2080
    MGM_CMD("abort backup reply", NULL, ""),
 
2081
    MGM_ARG("result", String, Mandatory, "Error message"),    
 
2082
    MGM_END()
 
2083
  };
 
2084
  CHECK_HANDLE(handle, -1);
 
2085
  CHECK_CONNECTED(handle, -1);
 
2086
  
 
2087
  Properties args;
 
2088
  args.put("id", backupId);
 
2089
 
 
2090
  const Properties *prop;
 
2091
  prop = ndb_mgm_call(handle, stop_backup_reply, "abort backup", &args);
 
2092
  CHECK_REPLY(handle, prop, -1);
 
2093
 
 
2094
  const char * buf;
 
2095
  prop->get("result", &buf);
 
2096
  if(strcmp(buf,"Ok")!=0) {
 
2097
    SET_ERROR(handle, NDB_MGM_COULD_NOT_ABORT_BACKUP, buf);
 
2098
    delete prop;    
 
2099
    return -1;
 
2100
  }
 
2101
 
 
2102
  delete prop;
 
2103
  return 0;
 
2104
}
 
2105
 
 
2106
extern "C"
 
2107
struct ndb_mgm_configuration *
 
2108
ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
 
2109
  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_configuration");
 
2110
  CHECK_HANDLE(handle, 0);
 
2111
  CHECK_CONNECTED(handle, 0);
 
2112
 
 
2113
  Properties args;
 
2114
  args.put("version", version);
 
2115
 
 
2116
  const ParserRow<ParserDummy> reply[] = {
 
2117
    MGM_CMD("get config reply", NULL, ""),
 
2118
    MGM_ARG("result", String, Mandatory, "Error message"),    
 
2119
    MGM_ARG("Content-Length", Int, Optional, "Content length in bytes"),
 
2120
    MGM_ARG("Content-Type", String, Optional, "Type (octet-stream)"),
 
2121
    MGM_ARG("Content-Transfer-Encoding", String, Optional, "Encoding(base64)"),
 
2122
    MGM_END()
 
2123
  };
 
2124
  
 
2125
  const Properties *prop;
 
2126
  prop = ndb_mgm_call(handle, reply, "get config", &args);
 
2127
  CHECK_REPLY(handle, prop, 0);
 
2128
  
 
2129
  do {
 
2130
    const char * buf;
 
2131
    if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
 
2132
      fprintf(handle->errstream, "ERROR Message: %s\n\n", buf);
 
2133
      break;
 
2134
    }
 
2135
 
 
2136
    buf = "<Unspecified>";
 
2137
    if(!prop->get("Content-Type", &buf) || 
 
2138
       strcmp(buf, "ndbconfig/octet-stream") != 0){
 
2139
      fprintf(handle->errstream, "Unhandled response type: %s\n", buf);
 
2140
      break;
 
2141
    }
 
2142
 
 
2143
    buf = "<Unspecified>";
 
2144
    if(!prop->get("Content-Transfer-Encoding", &buf) 
 
2145
       || strcmp(buf, "base64") != 0){
 
2146
      fprintf(handle->errstream, "Unhandled encoding: %s\n", buf);
 
2147
      break;
 
2148
    }
 
2149
 
 
2150
    buf = "<Content-Length Unspecified>";
 
2151
    Uint32 len = 0;
 
2152
    if(!prop->get("Content-Length", &len)){
 
2153
      fprintf(handle->errstream, "Invalid response: %s\n\n", buf);
 
2154
      break;
 
2155
    }
 
2156
 
 
2157
    len += 1; // Trailing \n
 
2158
        
 
2159
    char* buf64 = new char[len];
 
2160
    int read = 0;
 
2161
    size_t start = 0;
 
2162
    do {
 
2163
      if((read = read_socket(handle->socket, handle->timeout,
 
2164
                             &buf64[start], len-start)) < 1){
 
2165
        delete[] buf64;
 
2166
        buf64 = 0;
 
2167
        if(read==0)
 
2168
          SET_ERROR(handle, ETIMEDOUT, "Timeout reading packed config");
 
2169
        else
 
2170
          SET_ERROR(handle, errno, "Error reading packed config");
 
2171
        ndb_mgm_disconnect_quiet(handle);
 
2172
        break;
 
2173
      }
 
2174
      start += read;
 
2175
    } while(start < len);
 
2176
    if(buf64 == 0)
 
2177
      break;
 
2178
 
 
2179
    void *tmp_data = malloc(base64_needed_decoded_length((size_t) (len - 1)));
 
2180
    const int res = base64_decode(buf64, len-1, tmp_data, NULL);
 
2181
    delete[] buf64;
 
2182
    UtilBuffer tmp;
 
2183
    tmp.append((void *) tmp_data, res);
 
2184
    free(tmp_data);
 
2185
    if (res < 0)
 
2186
    {
 
2187
      fprintf(handle->errstream, "Failed to decode buffer\n");
 
2188
      break;
 
2189
    }
 
2190
 
 
2191
    ConfigValuesFactory cvf;
 
2192
    const int res2 = cvf.unpack(tmp);
 
2193
    if(!res2){
 
2194
      fprintf(handle->errstream, "Failed to unpack buffer\n");
 
2195
      break;
 
2196
    }
 
2197
 
 
2198
    delete prop;
 
2199
    return (ndb_mgm_configuration*)cvf.getConfigValues();
 
2200
  } while(0);
 
2201
 
 
2202
  delete prop;
 
2203
  return 0;
 
2204
}
 
2205
 
 
2206
extern "C"
 
2207
void
 
2208
ndb_mgm_destroy_configuration(struct ndb_mgm_configuration *cfg)
 
2209
{
 
2210
  if (cfg) {
 
2211
    ((ConfigValues *)cfg)->~ConfigValues();
 
2212
    free((void *)cfg);
 
2213
  }
 
2214
}
 
2215
 
 
2216
extern "C"
 
2217
int
 
2218
ndb_mgm_set_configuration_nodeid(NdbMgmHandle handle, int nodeid)
 
2219
{
 
2220
  CHECK_HANDLE(handle, -1);
 
2221
  handle->cfg._ownNodeId= nodeid;
 
2222
  return 0;
 
2223
}
 
2224
 
 
2225
extern "C"
 
2226
int
 
2227
ndb_mgm_get_configuration_nodeid(NdbMgmHandle handle)
 
2228
{
 
2229
  CHECK_HANDLE(handle, 0);
 
2230
  return handle->cfg._ownNodeId;
 
2231
}
 
2232
 
 
2233
extern "C"
 
2234
int ndb_mgm_get_connected_port(NdbMgmHandle handle)
 
2235
{
 
2236
  if (handle->cfg_i >= 0)
 
2237
    return handle->cfg.ids[handle->cfg_i].port;
 
2238
  else
 
2239
    return 0;
 
2240
}
 
2241
 
 
2242
extern "C"
 
2243
const char *ndb_mgm_get_connected_host(NdbMgmHandle handle)
 
2244
{
 
2245
  if (handle->cfg_i >= 0)
 
2246
    return handle->cfg.ids[handle->cfg_i].name.c_str();
 
2247
  else
 
2248
    return 0;
 
2249
}
 
2250
 
 
2251
extern "C"
 
2252
const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz)
 
2253
{
 
2254
  return handle->cfg.makeConnectString(buf,buf_sz);
 
2255
}
 
2256
 
 
2257
extern "C"
 
2258
int
 
2259
ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype,
 
2260
                     int log_event)
 
2261
{
 
2262
  CHECK_HANDLE(handle, 0);
 
2263
  CHECK_CONNECTED(handle, 0);
 
2264
  union { long l; char c[sizeof(long)]; } endian_check;
 
2265
 
 
2266
  endian_check.l = 1;
 
2267
 
 
2268
  int nodeid= handle->cfg._ownNodeId;
 
2269
 
 
2270
  Properties args;
 
2271
  args.put("version", version);
 
2272
  args.put("nodetype", nodetype);
 
2273
  args.put("nodeid", nodeid);
 
2274
  args.put("user", "mysqld");
 
2275
  args.put("password", "mysqld");
 
2276
  args.put("public key", "a public key");
 
2277
  args.put("endian", (endian_check.c[sizeof(long)-1])?"big":"little");
 
2278
  if (handle->m_name)
 
2279
    args.put("name", handle->m_name);
 
2280
  args.put("log_event", log_event);
 
2281
 
 
2282
  const ParserRow<ParserDummy> reply[]= {
 
2283
    MGM_CMD("get nodeid reply", NULL, ""),
 
2284
      MGM_ARG("error_code", Int, Optional, "Error code"),
 
2285
      MGM_ARG("nodeid", Int, Optional, "Error message"),
 
2286
      MGM_ARG("result", String, Mandatory, "Error message"),
 
2287
    MGM_END()
 
2288
  };
 
2289
  
 
2290
  const Properties *prop;
 
2291
  prop= ndb_mgm_call(handle, reply, "get nodeid", &args);
 
2292
  CHECK_REPLY(handle, prop, -1);
 
2293
 
 
2294
  nodeid= -1;
 
2295
  do {
 
2296
    const char * buf;
 
2297
    if (!prop->get("result", &buf) || strcmp(buf, "Ok") != 0)
 
2298
    {
 
2299
      const char *hostname= ndb_mgm_get_connected_host(handle);
 
2300
      unsigned port=  ndb_mgm_get_connected_port(handle);
 
2301
      BaseString err;
 
2302
      Uint32 error_code= NDB_MGM_ALLOCID_ERROR;
 
2303
      err.assfmt("Could not alloc node id at %s port %d: %s",
 
2304
                 hostname, port, buf);
 
2305
      prop->get("error_code", &error_code);
 
2306
      setError(handle, error_code, __LINE__, err.c_str());
 
2307
      break;
 
2308
    }
 
2309
    Uint32 _nodeid;
 
2310
    if(!prop->get("nodeid", &_nodeid) != 0){
 
2311
      fprintf(handle->errstream, "ERROR Message: <nodeid Unspecified>\n");
 
2312
      break;
 
2313
    }
 
2314
    nodeid= _nodeid;
 
2315
  }while(0);
 
2316
 
 
2317
  delete prop;
 
2318
  return nodeid;
 
2319
}
 
2320
 
 
2321
extern "C"
 
2322
int
 
2323
ndb_mgm_set_int_parameter(NdbMgmHandle handle,
 
2324
                          int node, 
 
2325
                          int param,
 
2326
                          unsigned value,
 
2327
                          struct ndb_mgm_reply*){
 
2328
  CHECK_HANDLE(handle, 0);
 
2329
  CHECK_CONNECTED(handle, 0);
 
2330
  
 
2331
  Properties args;
 
2332
  args.put("node", node);
 
2333
  args.put("param", param);
 
2334
  args.put("value", value);
 
2335
  
 
2336
  const ParserRow<ParserDummy> reply[]= {
 
2337
    MGM_CMD("set parameter reply", NULL, ""),
 
2338
    MGM_ARG("result", String, Mandatory, "Error message"),
 
2339
    MGM_END()
 
2340
  };
 
2341
  
 
2342
  const Properties *prop;
 
2343
  prop= ndb_mgm_call(handle, reply, "set parameter", &args);
 
2344
  CHECK_REPLY(handle, prop, -1);
 
2345
 
 
2346
  int res= -1;
 
2347
  do {
 
2348
    const char * buf;
 
2349
    if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
 
2350
      fprintf(handle->errstream, "ERROR Message: %s\n", buf);
 
2351
      break;
 
2352
    }
 
2353
    res= 0;
 
2354
  } while(0);
 
2355
  
 
2356
  delete prop;
 
2357
  return res;
 
2358
}
 
2359
 
 
2360
extern "C"
 
2361
int 
 
2362
ndb_mgm_set_int64_parameter(NdbMgmHandle handle,
 
2363
                            int node, 
 
2364
                            int param,
 
2365
                            unsigned long long value,
 
2366
                            struct ndb_mgm_reply*){
 
2367
  CHECK_HANDLE(handle, 0);
 
2368
  CHECK_CONNECTED(handle, 0);
 
2369
  
 
2370
  Properties args;
 
2371
  args.put("node", node);
 
2372
  args.put("param", param);
 
2373
  args.put("value", value);
 
2374
  
 
2375
  const ParserRow<ParserDummy> reply[]= {
 
2376
    MGM_CMD("set parameter reply", NULL, ""),
 
2377
    MGM_ARG("result", String, Mandatory, "Error message"),
 
2378
    MGM_END()
 
2379
  };
 
2380
  
 
2381
  const Properties *prop;
 
2382
  prop= ndb_mgm_call(handle, reply, "set parameter", &args);
 
2383
  CHECK_REPLY(handle, prop, 0);
 
2384
 
 
2385
  if(prop == NULL) {
 
2386
    SET_ERROR(handle, EIO, "Unable set parameter");
 
2387
    return -1;
 
2388
  }
 
2389
 
 
2390
  int res= -1;
 
2391
  do {
 
2392
    const char * buf;
 
2393
    if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
 
2394
      fprintf(handle->errstream, "ERROR Message: %s\n", buf);
 
2395
      break;
 
2396
    }
 
2397
    res= 0;
 
2398
  } while(0);
 
2399
  
 
2400
  delete prop;
 
2401
  return res;
 
2402
}
 
2403
 
 
2404
extern "C"
 
2405
int
 
2406
ndb_mgm_set_string_parameter(NdbMgmHandle handle,
 
2407
                             int node, 
 
2408
                             int param,
 
2409
                             const char * value,
 
2410
                             struct ndb_mgm_reply*){
 
2411
  CHECK_HANDLE(handle, 0);
 
2412
  CHECK_CONNECTED(handle, 0);
 
2413
  
 
2414
  Properties args;
 
2415
  args.put("node", node);
 
2416
  args.put("parameter", param);
 
2417
  args.put("value", value);
 
2418
  
 
2419
  const ParserRow<ParserDummy> reply[]= {
 
2420
    MGM_CMD("set parameter reply", NULL, ""),
 
2421
    MGM_ARG("result", String, Mandatory, "Error message"),
 
2422
    MGM_END()
 
2423
  };
 
2424
  
 
2425
  const Properties *prop;
 
2426
  prop= ndb_mgm_call(handle, reply, "set parameter", &args);
 
2427
  CHECK_REPLY(handle, prop, 0);
 
2428
  
 
2429
  if(prop == NULL) {
 
2430
    SET_ERROR(handle, EIO, "Unable set parameter");
 
2431
    return -1;
 
2432
  }
 
2433
 
 
2434
  int res= -1;
 
2435
  do {
 
2436
    const char * buf;
 
2437
    if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
 
2438
      fprintf(handle->errstream, "ERROR Message: %s\n", buf);
 
2439
      break;
 
2440
    }
 
2441
    res= 0;
 
2442
  } while(0);
 
2443
  
 
2444
  delete prop;
 
2445
  return res;
 
2446
}
 
2447
 
 
2448
extern "C"
 
2449
int
 
2450
ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **purged){
 
2451
  CHECK_HANDLE(handle, 0);
 
2452
  CHECK_CONNECTED(handle, 0);
 
2453
  
 
2454
  Properties args;
 
2455
  
 
2456
  const ParserRow<ParserDummy> reply[]= {
 
2457
    MGM_CMD("purge stale sessions reply", NULL, ""),
 
2458
    MGM_ARG("purged", String, Optional, ""),
 
2459
    MGM_ARG("result", String, Mandatory, "Error message"),
 
2460
    MGM_END()
 
2461
  };
 
2462
  
 
2463
  const Properties *prop;
 
2464
  prop= ndb_mgm_call(handle, reply, "purge stale sessions", &args);
 
2465
  CHECK_REPLY(handle, prop, -1);
 
2466
 
 
2467
  if(prop == NULL) {
 
2468
    SET_ERROR(handle, EIO, "Unable to purge stale sessions");
 
2469
    return -1;
 
2470
  }
 
2471
 
 
2472
  int res= -1;
 
2473
  do {
 
2474
    const char * buf;
 
2475
    if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
 
2476
      fprintf(handle->errstream, "ERROR Message: %s\n", buf);
 
2477
      break;
 
2478
    }
 
2479
    if (purged) {
 
2480
      if (prop->get("purged", &buf))
 
2481
        *purged= strdup(buf);
 
2482
      else
 
2483
        *purged= 0;
 
2484
    }
 
2485
    res= 0;
 
2486
  } while(0);
 
2487
  delete prop;
 
2488
  return res;
 
2489
}
 
2490
 
 
2491
extern "C"
 
2492
int
 
2493
ndb_mgm_check_connection(NdbMgmHandle handle){
 
2494
  CHECK_HANDLE(handle, 0);
 
2495
  CHECK_CONNECTED(handle, 0);
 
2496
  SocketOutputStream out(handle->socket, handle->timeout);
 
2497
  SocketInputStream in(handle->socket, handle->timeout);
 
2498
  char buf[32];
 
2499
  if (out.println("check connection"))
 
2500
    goto ndb_mgm_check_connection_error;
 
2501
 
 
2502
  if (out.println(""))
 
2503
    goto ndb_mgm_check_connection_error;
 
2504
 
 
2505
  in.gets(buf, sizeof(buf));
 
2506
  if(strcmp("check connection reply\n", buf))
 
2507
    goto ndb_mgm_check_connection_error;
 
2508
 
 
2509
  in.gets(buf, sizeof(buf));
 
2510
  if(strcmp("result: Ok\n", buf))
 
2511
    goto ndb_mgm_check_connection_error;
 
2512
 
 
2513
  in.gets(buf, sizeof(buf));
 
2514
  if(strcmp("\n", buf))
 
2515
    goto ndb_mgm_check_connection_error;
 
2516
 
 
2517
  return 0;
 
2518
 
 
2519
ndb_mgm_check_connection_error:
 
2520
  ndb_mgm_disconnect(handle);
 
2521
  return -1;
 
2522
}
 
2523
 
 
2524
extern "C"
 
2525
int
 
2526
ndb_mgm_set_connection_int_parameter(NdbMgmHandle handle,
 
2527
                                     int node1,
 
2528
                                     int node2,
 
2529
                                     int param,
 
2530
                                     int value,
 
2531
                                     struct ndb_mgm_reply* mgmreply){
 
2532
  CHECK_HANDLE(handle, 0);
 
2533
  CHECK_CONNECTED(handle, 0);
 
2534
  DBUG_ENTER("ndb_mgm_set_connection_int_parameter");
 
2535
  
 
2536
  Properties args;
 
2537
  args.put("node1", node1);
 
2538
  args.put("node2", node2);
 
2539
  args.put("param", param);
 
2540
  args.put("value", (Uint32)value);
 
2541
  
 
2542
  const ParserRow<ParserDummy> reply[]= {
 
2543
    MGM_CMD("set connection parameter reply", NULL, ""),
 
2544
    MGM_ARG("message", String, Mandatory, "Error Message"),
 
2545
    MGM_ARG("result", String, Mandatory, "Status Result"),
 
2546
    MGM_END()
 
2547
  };
 
2548
  
 
2549
  const Properties *prop;
 
2550
  prop= ndb_mgm_call(handle, reply, "set connection parameter", &args);
 
2551
  DBUG_CHECK_REPLY(handle, prop, -1);
 
2552
 
 
2553
  int res= -1;
 
2554
  do {
 
2555
    const char * buf;
 
2556
    if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
 
2557
      fprintf(handle->errstream, "ERROR Message: %s\n", buf);
 
2558
      break;
 
2559
    }
 
2560
    res= 0;
 
2561
  } while(0);
 
2562
  
 
2563
  delete prop;
 
2564
  DBUG_RETURN(res);
 
2565
}
 
2566
 
 
2567
extern "C"
 
2568
int
 
2569
ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle,
 
2570
                                     int node1,
 
2571
                                     int node2,
 
2572
                                     int param,
 
2573
                                     int *value,
 
2574
                                     struct ndb_mgm_reply* mgmreply){
 
2575
  CHECK_HANDLE(handle, -1);
 
2576
  CHECK_CONNECTED(handle, -2);
 
2577
  DBUG_ENTER("ndb_mgm_get_connection_int_parameter");
 
2578
  
 
2579
  Properties args;
 
2580
  args.put("node1", node1);
 
2581
  args.put("node2", node2);
 
2582
  args.put("param", param);
 
2583
 
 
2584
  const ParserRow<ParserDummy> reply[]= {
 
2585
    MGM_CMD("get connection parameter reply", NULL, ""),
 
2586
    MGM_ARG("value", Int, Mandatory, "Current Value"),
 
2587
    MGM_ARG("result", String, Mandatory, "Result"),
 
2588
    MGM_END()
 
2589
  };
 
2590
  
 
2591
  const Properties *prop;
 
2592
  prop = ndb_mgm_call(handle, reply, "get connection parameter", &args);
 
2593
  DBUG_CHECK_REPLY(handle, prop, -3);
 
2594
 
 
2595
  int res= -1;
 
2596
  do {
 
2597
    const char * buf;
 
2598
    if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
 
2599
      fprintf(handle->errstream, "ERROR Message: %s\n", buf);
 
2600
      break;
 
2601
    }
 
2602
    res= 0;
 
2603
  } while(0);
 
2604
 
 
2605
  if(!prop->get("value",(Uint32*)value)){
 
2606
    fprintf(handle->errstream, "Unable to get value\n");
 
2607
    res = -4;
 
2608
  }
 
2609
 
 
2610
  delete prop;
 
2611
  DBUG_RETURN(res);
 
2612
}
 
2613
 
 
2614
extern "C"
 
2615
NDB_SOCKET_TYPE
 
2616
ndb_mgm_convert_to_transporter(NdbMgmHandle *handle)
 
2617
{
 
2618
  NDB_SOCKET_TYPE s;
 
2619
 
 
2620
  CHECK_HANDLE((*handle), NDB_INVALID_SOCKET);
 
2621
  CHECK_CONNECTED((*handle), NDB_INVALID_SOCKET);
 
2622
 
 
2623
  (*handle)->connected= 0;   // we pretend we're disconnected
 
2624
  s= (*handle)->socket;
 
2625
 
 
2626
  SocketOutputStream s_output(s, (*handle)->timeout);
 
2627
  s_output.println("transporter connect");
 
2628
  s_output.println("");
 
2629
 
 
2630
  ndb_mgm_destroy_handle(handle); // set connected=0, so won't disconnect
 
2631
 
 
2632
  return s;
 
2633
}
 
2634
 
 
2635
extern "C"
 
2636
Uint32
 
2637
ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle)
 
2638
{
 
2639
  Uint32 nodeid=0;
 
2640
 
 
2641
  CHECK_HANDLE(handle, 0);
 
2642
  CHECK_CONNECTED(handle, 0);
 
2643
  DBUG_ENTER("ndb_mgm_get_mgmd_nodeid");
 
2644
  
 
2645
  Properties args;
 
2646
 
 
2647
  const ParserRow<ParserDummy> reply[]= {
 
2648
    MGM_CMD("get mgmd nodeid reply", NULL, ""),
 
2649
    MGM_ARG("nodeid", Int, Mandatory, "Node ID"),
 
2650
    MGM_END()
 
2651
  };
 
2652
  
 
2653
  const Properties *prop;
 
2654
  prop = ndb_mgm_call(handle, reply, "get mgmd nodeid", &args);
 
2655
  DBUG_CHECK_REPLY(handle, prop, 0);
 
2656
 
 
2657
  if(!prop->get("nodeid",&nodeid)){
 
2658
    fprintf(handle->errstream, "Unable to get value\n");
 
2659
    return 0;
 
2660
  }
 
2661
 
 
2662
  delete prop;
 
2663
  DBUG_RETURN(nodeid);
 
2664
}
 
2665
 
 
2666
extern "C"
 
2667
int ndb_mgm_report_event(NdbMgmHandle handle, Uint32 *data, Uint32 length)
 
2668
{
 
2669
  CHECK_HANDLE(handle, 0);
 
2670
  CHECK_CONNECTED(handle, 0);
 
2671
  DBUG_ENTER("ndb_mgm_report_event");
 
2672
 
 
2673
  Properties args;
 
2674
  args.put("length", length);
 
2675
  BaseString data_string;
 
2676
 
 
2677
  for (int i = 0; i < (int) length; i++)
 
2678
    data_string.appfmt(" %lu", (ulong) data[i]);
 
2679
 
 
2680
  args.put("data", data_string.c_str());
 
2681
 
 
2682
  const ParserRow<ParserDummy> reply[]= {
 
2683
    MGM_CMD("report event reply", NULL, ""),
 
2684
    MGM_ARG("result", String, Mandatory, "Result"),
 
2685
    MGM_END()
 
2686
  };
 
2687
  
 
2688
  const Properties *prop;
 
2689
  prop = ndb_mgm_call(handle, reply, "report event", &args);
 
2690
  DBUG_CHECK_REPLY(handle, prop, -1);
 
2691
 
 
2692
  DBUG_RETURN(0);
 
2693
}
 
2694
 
 
2695
extern "C"
 
2696
int ndb_mgm_end_session(NdbMgmHandle handle)
 
2697
{
 
2698
  CHECK_HANDLE(handle, 0);
 
2699
  CHECK_CONNECTED(handle, 0);
 
2700
  DBUG_ENTER("ndb_mgm_end_session");
 
2701
 
 
2702
  SocketOutputStream s_output(handle->socket, handle->timeout);
 
2703
  s_output.println("end session");
 
2704
  s_output.println("");
 
2705
 
 
2706
  SocketInputStream in(handle->socket, handle->timeout);
 
2707
  char buf[32];
 
2708
  in.gets(buf, sizeof(buf));
 
2709
  CHECK_TIMEDOUT_RET(handle, in, s_output, -1);
 
2710
 
 
2711
  DBUG_RETURN(0);
 
2712
}
 
2713
 
 
2714
extern "C"
 
2715
int ndb_mgm_get_version(NdbMgmHandle handle,
 
2716
                        int *major, int *minor, int *build, int len, char* str)
 
2717
{
 
2718
  DBUG_ENTER("ndb_mgm_get_version");
 
2719
  CHECK_HANDLE(handle, 0);
 
2720
  CHECK_CONNECTED(handle, 0);
 
2721
 
 
2722
  Properties args;
 
2723
 
 
2724
  const ParserRow<ParserDummy> reply[]= {
 
2725
    MGM_CMD("version", NULL, ""),
 
2726
    MGM_ARG("id", Int, Mandatory, "ID"),
 
2727
    MGM_ARG("major", Int, Mandatory, "Major"),
 
2728
    MGM_ARG("minor", Int, Mandatory, "Minor"),
 
2729
    MGM_ARG("string", String, Mandatory, "String"),
 
2730
    MGM_END()
 
2731
  };
 
2732
 
 
2733
  const Properties *prop;
 
2734
  prop = ndb_mgm_call(handle, reply, "get version", &args);
 
2735
  CHECK_REPLY(handle, prop, 0);
 
2736
 
 
2737
  Uint32 id;
 
2738
  if(!prop->get("id",&id)){
 
2739
    fprintf(handle->errstream, "Unable to get value\n");
 
2740
    return 0;
 
2741
  }
 
2742
  *build= getBuild(id);
 
2743
 
 
2744
  if(!prop->get("major",(Uint32*)major)){
 
2745
    fprintf(handle->errstream, "Unable to get value\n");
 
2746
    return 0;
 
2747
  }
 
2748
 
 
2749
  if(!prop->get("minor",(Uint32*)minor)){
 
2750
    fprintf(handle->errstream, "Unable to get value\n");
 
2751
    return 0;
 
2752
  }
 
2753
 
 
2754
  BaseString result;
 
2755
  if(!prop->get("string", result)){
 
2756
    fprintf(handle->errstream, "Unable to get value\n");
 
2757
    return 0;
 
2758
  }
 
2759
 
 
2760
  strncpy(str, result.c_str(), len);
 
2761
 
 
2762
  delete prop;
 
2763
  DBUG_RETURN(1);
 
2764
}
 
2765
 
 
2766
extern "C"
 
2767
Uint64
 
2768
ndb_mgm_get_session_id(NdbMgmHandle handle)
 
2769
{
 
2770
  Uint64 session_id=0;
 
2771
 
 
2772
  DBUG_ENTER("ndb_mgm_get_session_id");
 
2773
  CHECK_HANDLE(handle, 0);
 
2774
  CHECK_CONNECTED(handle, 0);
 
2775
  
 
2776
  Properties args;
 
2777
 
 
2778
  const ParserRow<ParserDummy> reply[]= {
 
2779
    MGM_CMD("get session id reply", NULL, ""),
 
2780
    MGM_ARG("id", Int, Mandatory, "Node ID"),
 
2781
    MGM_END()
 
2782
  };
 
2783
  
 
2784
  const Properties *prop;
 
2785
  prop = ndb_mgm_call(handle, reply, "get session id", &args);
 
2786
  CHECK_REPLY(handle, prop, 0);
 
2787
 
 
2788
  if(!prop->get("id",&session_id)){
 
2789
    fprintf(handle->errstream, "Unable to get session id\n");
 
2790
    return 0;
 
2791
  }
 
2792
 
 
2793
  delete prop;
 
2794
  DBUG_RETURN(session_id);
 
2795
}
 
2796
 
 
2797
extern "C"
 
2798
int
 
2799
ndb_mgm_get_session(NdbMgmHandle handle, Uint64 id,
 
2800
                    struct NdbMgmSession *s, int *len)
 
2801
{
 
2802
  int retval= 0;
 
2803
  DBUG_ENTER("ndb_mgm_get_session");
 
2804
  CHECK_HANDLE(handle, 0);
 
2805
  CHECK_CONNECTED(handle, 0);
 
2806
 
 
2807
  Properties args;
 
2808
  args.put("id", id);
 
2809
 
 
2810
  const ParserRow<ParserDummy> reply[]= {
 
2811
    MGM_CMD("get session reply", NULL, ""),
 
2812
    MGM_ARG("id", Int, Mandatory, "Node ID"),
 
2813
    MGM_ARG("m_stopSelf", Int, Optional, "m_stopSelf"),
 
2814
    MGM_ARG("m_stop", Int, Optional, "stop session"),
 
2815
    MGM_ARG("nodeid", Int, Optional, "allocated node id"),
 
2816
    MGM_ARG("parser_buffer_len", Int, Optional, "waiting in buffer"),
 
2817
    MGM_ARG("parser_status", Int, Optional, "parser status"),
 
2818
    MGM_END()
 
2819
  };
 
2820
 
 
2821
  const Properties *prop;
 
2822
  prop = ndb_mgm_call(handle, reply, "get session", &args);
 
2823
  CHECK_REPLY(handle, prop, 0);
 
2824
 
 
2825
  Uint64 r_id;
 
2826
  int rlen= 0;
 
2827
 
 
2828
  if(!prop->get("id",&r_id)){
 
2829
    fprintf(handle->errstream, "Unable to get session id\n");
 
2830
    goto err;
 
2831
  }
 
2832
 
 
2833
  s->id= r_id;
 
2834
  rlen+=sizeof(s->id);
 
2835
 
 
2836
  if(prop->get("m_stopSelf",&(s->m_stopSelf)))
 
2837
    rlen+=sizeof(s->m_stopSelf);
 
2838
  else
 
2839
    goto err;
 
2840
 
 
2841
  if(prop->get("m_stop",&(s->m_stop)))
 
2842
    rlen+=sizeof(s->m_stop);
 
2843
  else
 
2844
    goto err;
 
2845
 
 
2846
  if(prop->get("nodeid",&(s->nodeid)))
 
2847
    rlen+=sizeof(s->nodeid);
 
2848
  else
 
2849
    goto err;
 
2850
 
 
2851
  if(prop->get("parser_buffer_len",&(s->parser_buffer_len)))
 
2852
  {
 
2853
    rlen+=sizeof(s->parser_buffer_len);
 
2854
    if(prop->get("parser_status",&(s->parser_status)))
 
2855
      rlen+=sizeof(s->parser_status);
 
2856
  }
 
2857
 
 
2858
  *len= rlen;
 
2859
  retval= 1;
 
2860
 
 
2861
err:
 
2862
  delete prop;
 
2863
  DBUG_RETURN(retval);
 
2864
}
 
2865
 
 
2866
template class Vector<const ParserRow<ParserDummy>*>;