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