MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ndb_logevent.cpp
1 /*
2  Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include <ndb_global.h>
19 #include <mgmapi.h>
20 #include <mgmapi_internal.h>
21 
22 #include <NdbOut.hpp>
23 #include <Properties.hpp>
24 #include <InputStream.hpp>
25 #include <NdbTick.h>
26 
27 #include <debugger/EventLogger.hpp>
28 #include <kernel/NodeBitmask.hpp>
29 
30 #include "ndb_logevent.hpp"
31 
32 extern
33 int ndb_mgm_listen_event_internal(NdbMgmHandle, const int filter[],
34  int, NDB_SOCKET_TYPE*);
35 
37  enum ndb_logevent_handle_error code;
38  const char *msg;
39 };
40 
41 struct ndb_logevent_error_msg ndb_logevent_error_messages[]= {
42  { NDB_LEH_READ_ERROR, "Read error" },
43  { NDB_LEH_MISSING_EVENT_SPECIFIER, "Missing event specifier" },
44  { NDB_LEH_UNKNOWN_EVENT_VARIABLE, "Unknown event variable" },
45  { NDB_LEH_UNKNOWN_EVENT_TYPE, "Unknown event type" },
46  { NDB_LEH_INTERNAL_ERROR, "Unknown internal error" },
47  { NDB_LEH_NO_ERROR,0}
48 };
49 
51  NDB_SOCKET_TYPE socket;
52  enum ndb_logevent_handle_error m_error;
53 };
54 
55 /*
56  Create a new NdbLogEventHandle for reading events from
57  the same socket as the NdbMgmHandle
58 */
59 
61 ndb_mgm_create_logevent_handle_same_socket(NdbMgmHandle mh)
62 {
64  (NdbLogEventHandle)malloc(sizeof(ndb_logevent_handle));
65  if (!h)
66  return NULL;
67 
68  h->socket= _ndb_mgm_get_socket(mh);
69 
70  return h;
71 }
72 
73 extern "C"
76  const int filter[])
77 {
79  (NdbLogEventHandle)malloc(sizeof(ndb_logevent_handle));
80  if (!h)
81  return NULL;
82 
83  NDB_SOCKET_TYPE sock;
84  if(ndb_mgm_listen_event_internal(mh, filter, 1, &sock) < 0)
85  {
86  free(h);
87  return 0;
88  }
89 
90  h->socket= sock;
91 
92  return h;
93 }
94 
95 extern "C"
96 #ifdef NDB_WIN
97 SOCKET
99 {
100  return h->socket.s;
101 }
102 #else
103 int
105 {
106  return h->socket.fd;
107 }
108 #endif
109 
110 extern "C"
111 void ndb_mgm_destroy_logevent_handle(NdbLogEventHandle * h)
112 {
113  if( !h )
114  return;
115 
116  if ( *h )
117  my_socket_close((*h)->socket);
118 
119  free(*h);
120  * h = 0;
121 }
122 
123 #define ROW(a,b,c,d) \
124 { NDB_LE_ ## a, b, c, 0, offsetof(struct ndb_logevent, a.d), \
125  sizeof(((struct ndb_logevent *)0)->a.d) }
126 
127 #define ROW_FN(a,b,c,d,e) \
128 { NDB_LE_ ## a, b, c, e, offsetof(struct ndb_logevent, a.d), \
129  sizeof(((struct ndb_logevent *)0)->a.d) }
130 
131 static int ref_to_node(int ref){
132  return ref & 0xFFFF;
133 }
134 
135 struct Ndb_logevent_body_row ndb_logevent_body[]= {
136 
137  // Connection
138  ROW( Connected, "node", 1, node),
139 
140  ROW( Disconnected, "node", 1, node),
141 
142  ROW( CommunicationClosed, "node", 1, node),
143 
144  ROW( CommunicationOpened, "node", 1, node),
145 
146  ROW( ConnectedApiVersion, "node", 1, node),
147  ROW( ConnectedApiVersion, "version", 2, version),
148 
149  /* CHECKPOINT */
150 
151  ROW( GlobalCheckpointStarted, "gci", 1, gci),
152 
153  ROW( GlobalCheckpointCompleted, "gci", 1, gci),
154 
155  ROW( LocalCheckpointStarted, "lci", 1, lci),
156  ROW( LocalCheckpointStarted, "keep_gci", 2, keep_gci),
157  ROW( LocalCheckpointStarted, "restore_gci", 3, restore_gci),
158 
159  ROW( LocalCheckpointCompleted, "lci", 1, lci),
160 
161  ROW( LCPStoppedInCalcKeepGci, "data", 1, data),
162 
163  ROW( LCPFragmentCompleted, "node", 1, node),
164  ROW( LCPFragmentCompleted, "table_id", 2, table_id),
165  ROW( LCPFragmentCompleted, "fragment_id", 3, fragment_id),
166 
167  ROW( UndoLogBlocked, "acc_count", 1, acc_count),
168  ROW( UndoLogBlocked, "tup_count", 2, tup_count),
169 
170  /* STARTUP */
171  ROW( NDBStartStarted, "version", 1, version),
172 
173  ROW( NDBStartCompleted, "version", 1, version),
174 
175 // ROW( STTORRYRecieved),
176 
177  ROW( StartPhaseCompleted, "phase", 1, phase),
178  ROW( StartPhaseCompleted, "starttype", 2, starttype),
179 
180  ROW( CM_REGCONF, "own_id", 1, own_id),
181  ROW( CM_REGCONF, "president_id", 2, president_id),
182  ROW( CM_REGCONF, "dynamic_id", 3, dynamic_id),
183 
184  ROW( CM_REGREF, "own_id", 1, own_id),
185  ROW( CM_REGREF, "other_id", 2, other_id),
186  ROW( CM_REGREF, "cause", 3, cause),
187 
188  ROW( FIND_NEIGHBOURS, "own_id", 1, own_id),
189  ROW( FIND_NEIGHBOURS, "left_id", 3, left_id),
190  ROW( FIND_NEIGHBOURS, "right_id", 3, right_id),
191  ROW( FIND_NEIGHBOURS, "dynamic_id", 4, dynamic_id),
192 
193  ROW( NDBStopStarted, "stoptype", 1, stoptype),
194 
195  ROW( NDBStopCompleted, "action", 1, action),
196  ROW( NDBStopCompleted, "signum", 2, signum),
197 
198  ROW( NDBStopForced, "action", 1, action),
199  ROW( NDBStopForced, "signum", 2, signum),
200  ROW( NDBStopForced, "error", 3, error),
201  ROW( NDBStopForced, "sphase", 4, sphase),
202  ROW( NDBStopForced, "extra", 5, extra),
203 
204 // ROW( NDBStopAborted),
205 
206  ROW( StartREDOLog, "node", 1, node),
207  ROW( StartREDOLog, "keep_gci", 2, keep_gci),
208  ROW( StartREDOLog, "completed_gci", 3, completed_gci),
209  ROW( StartREDOLog, "restorable_gci", 4, restorable_gci),
210 
211  ROW( StartLog, "log_part", 1, log_part),
212  ROW( StartLog, "start_mb", 2, start_mb),
213  ROW( StartLog, "stop_mb", 3, stop_mb),
214  ROW( StartLog, "gci", 4, gci),
215 
216  ROW( UNDORecordsExecuted, "block", 1, block),
217  ROW( UNDORecordsExecuted, "data1", 2, data1),
218  ROW( UNDORecordsExecuted, "data2", 3, data2),
219  ROW( UNDORecordsExecuted, "data3", 4, data3),
220  ROW( UNDORecordsExecuted, "data4", 5, data4),
221  ROW( UNDORecordsExecuted, "data5", 6, data5),
222  ROW( UNDORecordsExecuted, "data6", 7, data6),
223  ROW( UNDORecordsExecuted, "data7", 8, data7),
224  ROW( UNDORecordsExecuted, "data8", 9, data8),
225  ROW( UNDORecordsExecuted, "data9", 10, data9),
226  ROW( UNDORecordsExecuted, "data10", 11, data10),
227 
228  /* NODERESTART */
229 // ROW( NR_CopyDict),
230 
231 // ROW( NR_CopyDistr),
232 
233  ROW( NR_CopyFragsStarted, "dest_node", 1, dest_node),
234 
235  ROW( NR_CopyFragDone, "dest_node", 1, dest_node),
236  ROW( NR_CopyFragDone, "table_id", 2, table_id),
237  ROW( NR_CopyFragDone, "fragment_id", 3, fragment_id),
238 
239  ROW( NR_CopyFragsCompleted, "dest_node", 1, dest_node),
240 
241  ROW( NodeFailCompleted, "block", 1, block), /* 0 = all */
242  ROW( NodeFailCompleted, "failed_node", 2, failed_node),
243  ROW( NodeFailCompleted, "completing_node", 3, completing_node), /* 0 = all */
244 
245  ROW( NODE_FAILREP, "failed_node", 1, failed_node),
246  ROW( NODE_FAILREP, "failure_state", 2, failure_state),
247 
248  /* TODO */
249  ROW( ArbitState, "code", 1, code),
250  ROW( ArbitState, "arbit_node", 2, arbit_node),
251  ROW( ArbitState, "ticket_0", 3, ticket_0),
252  ROW( ArbitState, "ticket_1", 4, ticket_1),
253 
254  /* TODO */
255  ROW( ArbitResult, "code", 1, code),
256  ROW( ArbitResult, "arbit_node", 2, arbit_node),
257  ROW( ArbitResult, "ticket_0", 3, ticket_0),
258  ROW( ArbitResult, "ticket_1", 4, ticket_1),
259 
260 // ROW( GCP_TakeoverStarted),
261 
262 // ROW( GCP_TakeoverCompleted),
263 
264 // ROW( LCP_TakeoverStarted),
265 
266  ROW( LCP_TakeoverCompleted, "state", 1, state),
267 
268  /* STATISTIC */
269  ROW( TransReportCounters, "trans_count", 1, trans_count),
270  ROW( TransReportCounters, "commit_count", 2, commit_count),
271  ROW( TransReportCounters, "read_count", 3, read_count),
272  ROW( TransReportCounters, "simple_read_count", 4, simple_read_count),
273  ROW( TransReportCounters, "write_count", 5, write_count),
274  ROW( TransReportCounters, "attrinfo_count", 6, attrinfo_count),
275  ROW( TransReportCounters, "conc_op_count", 7, conc_op_count),
276  ROW( TransReportCounters, "abort_count", 8, abort_count),
277  ROW( TransReportCounters, "scan_count", 9, scan_count),
278  ROW( TransReportCounters, "range_scan_count", 10, range_scan_count),
279 
280  ROW( OperationReportCounters, "ops", 1, ops),
281 
282  ROW( TableCreated, "table_id", 1, table_id),
283 
284  ROW( JobStatistic, "mean_loop_count", 1, mean_loop_count),
285 
286  ROW( SendBytesStatistic, "to_node", 1, to_node),
287  ROW( SendBytesStatistic, "mean_sent_bytes", 2, mean_sent_bytes),
288 
289  ROW( ReceiveBytesStatistic, "from_node", 1, from_node),
290  ROW( ReceiveBytesStatistic, "mean_received_bytes", 2, mean_received_bytes),
291 
292  ROW( MemoryUsage, "gth", 1, gth),
293  ROW( MemoryUsage, "page_size_bytes", 2, page_size_bytes),
294  ROW( MemoryUsage, "pages_used", 3, pages_used),
295  ROW( MemoryUsage, "pages_total", 4, pages_total),
296  ROW( MemoryUsage, "block", 5, block),
297 
298  ROW( MTSignalStatistics, "mt_deliver_thread", 1, thr_no),
299  ROW( MTSignalStatistics, "mt_prioa_count", 2, prioa_count),
300  ROW( MTSignalStatistics, "mt_prioa_size", 3, prioa_size),
301  ROW( MTSignalStatistics, "mt_priob_count", 4, priob_count),
302  ROW( MTSignalStatistics, "mt_priob_size", 5, priob_size),
303 
304  /* ERROR */
305  ROW( TransporterError, "to_node", 1, to_node),
306  ROW( TransporterError, "code", 2, code),
307 
308  ROW( TransporterWarning, "to_node", 1, to_node),
309  ROW( TransporterWarning, "code", 2, code),
310 
311  ROW( MissedHeartbeat, "node", 1, node),
312  ROW( MissedHeartbeat, "count", 2, count),
313 
314  ROW( DeadDueToHeartbeat, "node", 1, node),
315 
316  /* TODO */
317 // ROW( WarningEvent),
318 
319  /* INFO */
320  ROW( SentHeartbeat, "node", 1, node),
321 
322  ROW( CreateLogBytes, "node", 1, node),
323 
324  /* TODO */
325 // ROW( InfoEvent),
326 
327  ROW( EventBufferStatus, "usage", 1, usage),
328  ROW( EventBufferStatus, "alloc", 2, alloc),
329  ROW( EventBufferStatus, "max", 3, max),
330  ROW( EventBufferStatus, "apply_gci_l", 4, apply_gci_l),
331  ROW( EventBufferStatus, "apply_gci_h", 5, apply_gci_h),
332  ROW( EventBufferStatus, "latest_gci_l", 6, latest_gci_l),
333  ROW( EventBufferStatus, "latest_gci_h", 7, latest_gci_h),
334 
335  // Backup
336  ROW_FN( BackupStarted, "starting_node", 1, starting_node, ref_to_node),
337  ROW( BackupStarted, "backup_id", 2, backup_id),
338 
339  ROW_FN(BackupFailedToStart,"starting_node",1, starting_node, ref_to_node),
340  ROW( BackupFailedToStart, "error", 2, error),
341 
342  ROW_FN( BackupCompleted, "starting_node", 1, starting_node, ref_to_node),
343  ROW( BackupCompleted, "backup_id", 2, backup_id),
344  ROW( BackupCompleted, "start_gci", 3, start_gci),
345  ROW( BackupCompleted, "stop_gci", 4, stop_gci),
346  ROW( BackupCompleted, "n_bytes", 5, n_bytes),
347  ROW( BackupCompleted, "n_records", 6, n_records),
348  ROW( BackupCompleted, "n_log_bytes", 7, n_log_bytes),
349  ROW( BackupCompleted, "n_log_records", 8, n_log_records),
350  ROW( BackupCompleted, "n_bytes_hi", 9+NdbNodeBitmask::Size, n_bytes_hi),
351  ROW( BackupCompleted, "n_records_hi", 10+NdbNodeBitmask::Size, n_records_hi),
352  ROW( BackupCompleted, "n_log_bytes_hi", 11+NdbNodeBitmask::Size, n_log_bytes_hi),
353  ROW( BackupCompleted, "n_log_records_hi", 12+NdbNodeBitmask::Size, n_log_records_hi),
354 
355  ROW_FN( BackupStatus, "starting_node", 1, starting_node, ref_to_node),
356  ROW( BackupStatus, "backup_id", 2, backup_id),
357  ROW( BackupStatus, "n_bytes_lo", 3, n_bytes_lo),
358  ROW( BackupStatus, "n_bytes_hi", 4, n_bytes_hi),
359  ROW( BackupStatus, "n_records_lo", 5, n_records_lo),
360  ROW( BackupStatus, "n_records_hi", 6, n_records_hi),
361  ROW( BackupStatus, "n_log_bytes_lo", 7, n_log_bytes_lo),
362  ROW( BackupStatus, "n_log_bytes_hi", 8, n_log_bytes_hi),
363  ROW( BackupStatus, "n_log_records_lo", 9, n_log_records_lo),
364  ROW( BackupStatus, "n_log_records_hi",10, n_log_records_hi),
365 
366  ROW_FN( BackupAborted, "starting_node", 1, starting_node, ref_to_node),
367  ROW( BackupAborted, "backup_id", 2, backup_id),
368  ROW( BackupAborted, "error", 3, error),
369 
370  ROW( RestoreStarted, "backup_id", 1, backup_id),
371  ROW( RestoreStarted, "node_id", 2, node_id),
372 
373  ROW( RestoreMetaData, "backup_id", 1, backup_id),
374  ROW( RestoreMetaData, "node_id", 2, node_id),
375  ROW( RestoreMetaData, "n_tables", 3, n_tables),
376  ROW( RestoreMetaData, "n_tablespaces", 4, n_tablespaces),
377  ROW( RestoreMetaData, "n_logfilegroups", 5, n_logfilegroups),
378  ROW( RestoreMetaData, "n_datafiles", 6, n_datafiles),
379  ROW( RestoreMetaData, "n_undofiles", 7, n_undofiles),
380 
381  ROW( RestoreData, "backup_id", 1, backup_id),
382  ROW( RestoreData, "node_id", 2, node_id),
383  ROW( RestoreData, "n_records_lo", 3, n_records_lo),
384  ROW( RestoreData, "n_records_hi", 4, n_records_hi),
385  ROW( RestoreData, "n_bytes_lo", 5, n_bytes_lo),
386  ROW( RestoreData, "n_bytes_hi", 6, n_bytes_hi),
387 
388  ROW( RestoreLog, "backup_id", 1, backup_id),
389  ROW( RestoreLog, "node_id", 2, node_id),
390  ROW( RestoreLog, "n_records_lo", 3, n_records_lo),
391  ROW( RestoreLog, "n_records_hi", 4, n_records_hi),
392  ROW( RestoreLog, "n_bytes_lo", 5, n_bytes_lo),
393  ROW( RestoreLog, "n_bytes_hi", 6, n_bytes_hi),
394 
395  ROW( RestoreCompleted, "backup_id", 1, backup_id),
396  ROW( RestoreCompleted, "node_id", 2, node_id),
397 
398  ROW( SingleUser, "type", 1, type),
399  ROW( SingleUser, "node_id", 2, node_id),
400 
401  ROW( LogFileInitStatus, "node_id", 1, node_id ),
402  ROW( LogFileInitStatus, "total_files", 2, total_files),
403  ROW( LogFileInitStatus, "file_done", 3, file_done),
404  ROW( LogFileInitStatus, "total_mbytes", 4, total_mbytes),
405  ROW( LogFileInitStatus, "mbytes_done", 5, mbytes_done),
406 
407  { NDB_LE_ILLEGAL_TYPE, 0, 0, 0, 0, 0}
408 };
409 
411  const char *token; // token to use for text transfer
412  int offset; // offset into struct ndb_logevent
413  int size;
414 };
415 
416 #define ROW2(a,b) \
417 { a, offsetof(struct ndb_logevent, b), \
418  sizeof(((struct ndb_logevent *)0)->b) }
419 
420 struct Ndb_logevent_header_row ndb_logevent_header[]= {
421  ROW2( "type", type),
422  ROW2( "time", time),
423  ROW2( "source_nodeid", source_nodeid),
424  { 0, 0, 0 }
425 };
426 
427 static int
428 insert_row(const char * pair, Properties & p){
429  BaseString tmp(pair);
430 
431  tmp.trim(" \t\n\r");
432  Vector<BaseString> split;
433  tmp.split(split, ":=", 2);
434  if(split.size() != 2)
435  return -1;
436  p.put(split[0].trim().c_str(), split[1].trim().c_str());
437 
438  return 0;
439 }
440 
441 static
442 int memcpy_atoi(void *dst, const char *str, int sz)
443 {
444  switch (sz)
445  {
446  case 1:
447  {
448  Int8 val= atoi(str);
449  memcpy(dst,&val,sz);
450  return 0;
451  }
452  case 2:
453  {
454  Int16 val= atoi(str);
455  memcpy(dst,&val,sz);
456  return 0;
457  }
458  case 4:
459  {
460  Int32 val= atoi(str);
461  memcpy(dst,&val,sz);
462  return 0;
463  }
464  case 8:
465  {
466  Int64 val= atoi(str);
467  memcpy(dst,&val,sz);
468  return 0;
469  }
470  default:
471  {
472  return -1;
473  }
474  }
475 }
476 
477 extern "C"
479  struct ndb_logevent *dst,
480  unsigned timeout_in_milliseconds)
481 {
482  if (timeout_in_milliseconds == 0)
483  {
484  int res;
485  while ((res = ndb_logevent_get_next(h, dst, 60000))==0);
486  return res;
487  }
488 
489  SocketInputStream in(h->socket, timeout_in_milliseconds);
490 
491  /*
492  Read log event header until header received
493  or timeout expired. The MGM server will continusly
494  send <PING>'s that should be ignored.
495  */
496  char buf[1024];
497  NDB_TICKS start = NdbTick_CurrentMillisecond();
498  while(1)
499  {
500  if (in.gets(buf,sizeof(buf)) == 0)
501  {
502  h->m_error= NDB_LEH_READ_ERROR;
503  return -1;
504  }
505  if ( buf[0] == 0 )
506  {
507  // timed out
508  return 0;
509  }
510 
511  if ( strcmp("log event reply\n", buf) == 0 )
512  break;
513 
514  if ( strcmp("<PING>\n", buf) )
515  ndbout_c("skipped: %s", buf);
516 
517  if(in.timedout())
518  return 0;
519 
520  if ((NdbTick_CurrentMillisecond() - start) > timeout_in_milliseconds)
521  return 0;
522 
523  };
524 
525  /* Read name-value pairs until empty new line */
526  Properties p;
527  while (1)
528  {
529  if (in.gets(buf,sizeof(buf)) == 0)
530  {
531  h->m_error= NDB_LEH_READ_ERROR;
532  return -1;
533  }
534  if (in.timedout())
535  return 0;
536 
537  if ( buf[0] == '\n' )
538  {
539  break;
540  }
541  if (insert_row(buf,p))
542  {
543  h->m_error= NDB_LEH_READ_ERROR;
544  return -1;
545  }
546  }
547 
548  int i;
549  const char *val;
550 
551  dst->type= (enum Ndb_logevent_type)-1;
552  /* fill in header info from p*/
553  for (i= 0; ndb_logevent_header[i].token; i++)
554  {
555  if ( p.get(ndb_logevent_header[i].token, &val) == 0 )
556  {
557  ndbout_c("missing: %s\n", ndb_logevent_header[i].token);
558  h->m_error= NDB_LEH_MISSING_EVENT_SPECIFIER;
559  return -1;
560  }
561  if ( memcpy_atoi((char *)dst+ndb_logevent_header[i].offset, val,
562  ndb_logevent_header[i].size) )
563  {
564  h->m_error= NDB_LEH_INTERNAL_ERROR;
565  return -1;
566  }
567  }
568 
569  Uint32 level;
570  LogLevel::EventCategory category;
571  Logger::LoggerLevel severity;
573 
574  /* fill in rest of header info event_lookup */
575  if (EventLoggerBase::event_lookup(dst->type,category,level,severity,text_fn))
576  {
577  ndbout_c("unknown type: %d\n", dst->type);
578  h->m_error= NDB_LEH_UNKNOWN_EVENT_TYPE;
579  return -1;
580  }
581  dst->category= (enum ndb_mgm_event_category)category;
582  dst->severity= (enum ndb_mgm_event_severity)severity;
583  dst->level= level;
584 
585  /* fill in header info from p */
586  for (i= 0; ndb_logevent_body[i].token; i++)
587  {
588  if ( ndb_logevent_body[i].type == dst->type )
589  break;
590  }
591 
592  if (ndb_logevent_body[i].token)
593  {
594  do {
595 
596  if ( p.get(ndb_logevent_body[i].token, &val) == 0 )
597  {
598  h->m_error= NDB_LEH_UNKNOWN_EVENT_VARIABLE;
599  return -1;
600  }
601  if ( memcpy_atoi((char *)dst+ndb_logevent_body[i].offset, val,
602  ndb_logevent_body[i].size) )
603  {
604  h->m_error= NDB_LEH_INTERNAL_ERROR;
605  return -1;
606  }
607  } while (ndb_logevent_body[++i].type == dst->type);
608  }
609  else
610  {
611  if (!p.get("data", &val))
612  {
613  h->m_error= NDB_LEH_UNKNOWN_EVENT_VARIABLE;
614  return -1;
615  }
616  BaseString tmp(val);
617  Vector<BaseString> list;
618  tmp.split(list);
619  for (size_t j = 0; j<list.size(); j++)
620  {
621  dst->Data[j] = atoi(list[j].c_str());
622  }
623  }
624  return 1;
625 }
626 
627 extern "C"
629 {
630  return h->m_error;
631 }
632 
633 extern "C"
635 {
636  for (int i= 0; ndb_logevent_error_messages[i].msg; i++)
637  if (ndb_logevent_error_messages[i].code == h->m_error)
638  return ndb_logevent_error_messages[i].msg;
639  return "<unknown error msg>";
640 }