mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / ndb / src / mgmsrv / Services.cpp
blobdb9d11c8a72d259c63a97d8986bf9e6cf1c6dd55
1 /* Copyright (c) 2003-2007 MySQL AB
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.
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.
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 */
16 #include <ndb_global.h>
17 #include <ctype.h>
19 #include <uucode.h>
20 #include <socket_io.h>
21 #include <util/version.h>
22 #include <mgmapi.h>
23 #include <EventLogger.hpp>
24 #include <signaldata/SetLogLevelOrd.hpp>
25 #include <LogLevel.hpp>
26 #include <BaseString.hpp>
28 #include <ConfigValues.hpp>
29 #include <mgmapi_configuration.hpp>
30 #include <Vector.hpp>
31 #include "Services.hpp"
32 #include "../mgmapi/ndb_logevent.hpp"
34 #include <base64.h>
35 #include <ndberror.h>
37 extern bool g_StopServer;
38 extern bool g_RestartServer;
39 extern EventLogger g_eventLogger;
41 static const unsigned int MAX_READ_TIMEOUT = 1000 ;
42 static const unsigned int MAX_WRITE_TIMEOUT = 100 ;
44 /**
45 const char * name;
46 const char * realName;
47 const Type type;
48 const ArgType argType;
49 const ArgRequired argRequired;
50 const ArgMinMax argMinMax;
51 const int minVal;
52 const int maxVal;
53 void (T::* function)(const class Properties & args);
54 const char * description;
57 #define MGM_CMD(name, fun, desc) \
58 { name, \
59 0, \
60 ParserRow<MgmApiSession>::Cmd, \
61 ParserRow<MgmApiSession>::String, \
62 ParserRow<MgmApiSession>::Optional, \
63 ParserRow<MgmApiSession>::IgnoreMinMax, \
64 0, 0, \
65 fun, \
66 desc, 0 }
68 #define MGM_ARG(name, type, opt, desc) \
69 { name, \
70 0, \
71 ParserRow<MgmApiSession>::Arg, \
72 ParserRow<MgmApiSession>::type, \
73 ParserRow<MgmApiSession>::opt, \
74 ParserRow<MgmApiSession>::IgnoreMinMax, \
75 0, 0, \
76 0, \
77 desc, 0 }
79 #define MGM_ARG2(name, type, opt, min, max, desc) \
80 { name, \
81 0, \
82 ParserRow<MgmApiSession>::Arg, \
83 ParserRow<MgmApiSession>::type, \
84 ParserRow<MgmApiSession>::opt, \
85 ParserRow<MgmApiSession>::IgnoreMinMax, \
86 min, max, \
87 0, \
88 desc, 0 }
90 #define MGM_END() \
91 { 0, \
92 0, \
93 ParserRow<MgmApiSession>::Arg, \
94 ParserRow<MgmApiSession>::Int, \
95 ParserRow<MgmApiSession>::Optional, \
96 ParserRow<MgmApiSession>::IgnoreMinMax, \
97 0, 0, \
98 0, \
99 0, 0 }
101 #define MGM_CMD_ALIAS(name, realName, fun) \
102 { name, \
103 realName, \
104 ParserRow<MgmApiSession>::CmdAlias, \
105 ParserRow<MgmApiSession>::Int, \
106 ParserRow<MgmApiSession>::Optional, \
107 ParserRow<MgmApiSession>::IgnoreMinMax, \
108 0, 0, \
109 0, \
110 0, 0 }
112 #define MGM_ARG_ALIAS(name, realName, fun) \
113 { name, \
114 realName, \
115 ParserRow<MgmApiSession>::ArgAlias, \
116 ParserRow<MgmApiSession>::Int, \
117 ParserRow<MgmApiSession>::Optional, \
118 ParserRow<MgmApiSession>::IgnoreMinMax, \
119 0, 0, \
120 0, \
121 0, 0 }
123 const
124 ParserRow<MgmApiSession> commands[] = {
125 MGM_CMD("get config", &MgmApiSession::getConfig, ""),
126 MGM_ARG("version", Int, Mandatory, "Configuration version number"),
127 MGM_ARG("node", Int, Optional, "Node ID"),
129 MGM_CMD("get nodeid", &MgmApiSession::get_nodeid, ""),
130 MGM_ARG("version", Int, Mandatory, "Configuration version number"),
131 MGM_ARG("nodetype", Int, Mandatory, "Node type"),
132 MGM_ARG("transporter", String, Optional, "Transporter type"),
133 MGM_ARG("nodeid", Int, Optional, "Node ID"),
134 MGM_ARG("user", String, Mandatory, "Password"),
135 MGM_ARG("password", String, Mandatory, "Password"),
136 MGM_ARG("public key", String, Mandatory, "Public key"),
137 MGM_ARG("endian", String, Optional, "Endianness"),
138 MGM_ARG("name", String, Optional, "Name of connection"),
139 MGM_ARG("timeout", Int, Optional, "Timeout in seconds"),
140 MGM_ARG("log_event", Int, Optional, "Log failure in cluster log"),
142 MGM_CMD("get version", &MgmApiSession::getVersion, ""),
144 MGM_CMD("get status", &MgmApiSession::getStatus, ""),
146 MGM_CMD("get info clusterlog", &MgmApiSession::getInfoClusterLog, ""),
147 MGM_CMD("get cluster loglevel", &MgmApiSession::getClusterLogLevel, ""),
149 MGM_CMD("restart node", &MgmApiSession::restart_v1, ""),
150 MGM_ARG("node", String, Mandatory, "Nodes to restart"),
151 MGM_ARG("initialstart", Int, Optional, "Initial start"),
152 MGM_ARG("nostart", Int, Optional, "No start"),
153 MGM_ARG("abort", Int, Optional, "Abort"),
155 MGM_CMD("restart node v2", &MgmApiSession::restart_v2, ""),
156 MGM_ARG("node", String, Mandatory, "Nodes to restart"),
157 MGM_ARG("initialstart", Int, Optional, "Initial start"),
158 MGM_ARG("nostart", Int, Optional, "No start"),
159 MGM_ARG("abort", Int, Optional, "Abort"),
161 MGM_CMD("restart all", &MgmApiSession::restartAll, ""),
162 MGM_ARG("initialstart", Int, Optional, "Initial start"),
163 MGM_ARG("nostart", Int, Optional, "No start"),
164 MGM_ARG("abort", Int, Optional, "Abort"),
166 MGM_CMD("insert error", &MgmApiSession::insertError, ""),
167 MGM_ARG("node", Int, Mandatory, "Node to receive error"),
168 MGM_ARG("error", Int, Mandatory, "Errorcode to insert"),
170 MGM_CMD("set trace", &MgmApiSession::setTrace, ""),
171 MGM_ARG("node", Int, Mandatory, "Node"),
172 MGM_ARG("trace", Int, Mandatory, "Trace number"),
174 MGM_CMD("log signals", &MgmApiSession::logSignals, ""),
175 MGM_ARG("node", Int, Mandatory, "Node"),
176 MGM_ARG("blocks", String, Mandatory, "Blocks (space separated)"),
177 MGM_ARG("in", Int, Mandatory, "Log input signals"),
178 MGM_ARG("out", Int, Mandatory, "Log output signals"),
180 MGM_CMD("start signallog", &MgmApiSession::startSignalLog, ""),
181 MGM_ARG("node", Int, Mandatory, "Node"),
183 MGM_CMD("stop signallog", &MgmApiSession::stopSignalLog, ""),
184 MGM_ARG("node", Int, Mandatory, "Node"),
186 MGM_CMD("dump state", &MgmApiSession::dumpState, ""),
187 MGM_ARG("node", Int, Mandatory ,"Node"),
188 MGM_ARG("args", String, Mandatory, "Args(space separated int's)"),
190 MGM_CMD("start backup", &MgmApiSession::startBackup, ""),
191 MGM_ARG("completed", Int, Optional ,"Wait until completed"),
193 MGM_CMD("abort backup", &MgmApiSession::abortBackup, ""),
194 MGM_ARG("id", Int, Mandatory, "Backup id"),
196 MGM_CMD("stop", &MgmApiSession::stop_v1, ""),
197 MGM_ARG("node", String, Mandatory, "Node"),
198 MGM_ARG("abort", Int, Mandatory, "Node"),
200 MGM_CMD("stop v2", &MgmApiSession::stop_v2, ""),
201 MGM_ARG("node", String, Mandatory, "Node"),
202 MGM_ARG("abort", Int, Mandatory, "Node"),
204 MGM_CMD("stop all", &MgmApiSession::stopAll, ""),
205 MGM_ARG("abort", Int, Mandatory, "Node"),
206 MGM_ARG("stop", String, Optional, "MGM/DB or both"),
208 MGM_CMD("enter single user", &MgmApiSession::enterSingleUser, ""),
209 MGM_ARG("nodeId", Int, Mandatory, "Node"),
211 MGM_CMD("exit single user", &MgmApiSession::exitSingleUser, ""),
214 MGM_CMD("start", &MgmApiSession::start, ""),
215 MGM_ARG("node", Int, Mandatory, "Node"),
217 MGM_CMD("start all", &MgmApiSession::startAll, ""),
219 MGM_CMD("bye", &MgmApiSession::bye, ""),
221 MGM_CMD("end session", &MgmApiSession::endSession, ""),
223 MGM_CMD("set loglevel", &MgmApiSession::setLogLevel, ""),
224 MGM_ARG("node", Int, Mandatory, "Node"),
225 MGM_ARG("category", Int, Mandatory, "Event category"),
226 MGM_ARG("level", Int, Mandatory, "Log level (0-15)"),
228 MGM_CMD("set cluster loglevel", &MgmApiSession::setClusterLogLevel, ""),
229 MGM_ARG("node", Int, Mandatory, "Node"),
230 MGM_ARG("category", Int, Mandatory, "Event category"),
231 MGM_ARG("level", Int, Mandatory, "Log level (0-15)"),
233 MGM_CMD("set logfilter", &MgmApiSession::setLogFilter, ""),
234 MGM_ARG("level", Int, Mandatory, "Severety level"),
235 MGM_ARG("enable", Int, Mandatory, "1=disable, 0=enable, -1=toggle"),
237 MGM_CMD("set parameter", &MgmApiSession::setParameter, ""),
238 MGM_ARG("node", String, Mandatory, "Node"),
239 MGM_ARG("parameter", String, Mandatory, "Parameter"),
240 MGM_ARG("value", String, Mandatory, "Value"),
242 MGM_CMD("set connection parameter",
243 &MgmApiSession::setConnectionParameter, ""),
244 MGM_ARG("node1", String, Mandatory, "Node1 ID"),
245 MGM_ARG("node2", String, Mandatory, "Node2 ID"),
246 MGM_ARG("param", String, Mandatory, "Parameter"),
247 MGM_ARG("value", String, Mandatory, "Value"),
249 MGM_CMD("get connection parameter",
250 &MgmApiSession::getConnectionParameter, ""),
251 MGM_ARG("node1", String, Mandatory, "Node1 ID"),
252 MGM_ARG("node2", String, Mandatory, "Node2 ID"),
253 MGM_ARG("param", String, Mandatory, "Parameter"),
255 MGM_CMD("listen event", &MgmApiSession::listen_event, ""),
256 MGM_ARG("node", Int, Optional, "Node"),
257 MGM_ARG("parsable", Int, Optional, "Parsable"),
258 MGM_ARG("filter", String, Mandatory, "Event category"),
260 MGM_CMD("purge stale sessions", &MgmApiSession::purge_stale_sessions, ""),
262 MGM_CMD("check connection", &MgmApiSession::check_connection, ""),
264 MGM_CMD("transporter connect", &MgmApiSession::transporter_connect, ""),
266 MGM_CMD("get mgmd nodeid", &MgmApiSession::get_mgmd_nodeid, ""),
268 MGM_CMD("report event", &MgmApiSession::report_event, ""),
269 MGM_ARG("length", Int, Mandatory, "Length"),
270 MGM_ARG("data", String, Mandatory, "Data"),
272 MGM_CMD("list sessions", &MgmApiSession::listSessions, ""),
274 MGM_CMD("get session id", &MgmApiSession::getSessionId, ""),
276 MGM_CMD("get session", &MgmApiSession::getSession, ""),
277 MGM_ARG("id", Int, Mandatory, "SessionID"),
279 MGM_END()
282 struct PurgeStruct
284 NodeBitmask free_nodes;/* free nodes as reported
285 * by ndbd in apiRegReqConf
287 BaseString *str;
288 NDB_TICKS tick;
291 #define ERROR_INSERTED(x) (g_errorInsert == x || m_errorInsert == x)
293 #define SLEEP_ERROR_INSERTED(x) if(ERROR_INSERTED(x)){NdbSleep_SecSleep(10);}
295 MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock, Uint64 session_id)
296 : SocketServer::Session(sock), m_mgmsrv(mgm)
298 DBUG_ENTER("MgmApiSession::MgmApiSession");
299 m_input = new SocketInputStream(sock, 30000);
300 m_output = new SocketOutputStream(sock, 30000);
301 m_parser = new Parser_t(commands, *m_input, true, true, true);
302 m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv);
303 m_stopSelf= 0;
304 m_ctx= NULL;
305 m_session_id= session_id;
306 m_mutex= NdbMutex_Create();
307 m_errorInsert= 0;
308 DBUG_VOID_RETURN;
311 MgmApiSession::~MgmApiSession()
313 DBUG_ENTER("MgmApiSession::~MgmApiSession");
314 if (m_input)
315 delete m_input;
316 if (m_output)
317 delete m_output;
318 if (m_parser)
319 delete m_parser;
320 if (m_allocated_resources)
321 delete m_allocated_resources;
322 if(m_socket != NDB_INVALID_SOCKET)
324 NDB_CLOSE_SOCKET(m_socket);
325 m_socket= NDB_INVALID_SOCKET;
327 if(m_stopSelf < 0)
328 g_RestartServer= true;
329 if(m_stopSelf)
330 g_StopServer= true;
331 NdbMutex_Destroy(m_mutex);
332 DBUG_VOID_RETURN;
335 void
336 MgmApiSession::runSession()
338 DBUG_ENTER("MgmApiSession::runSession");
340 Parser_t::Context ctx;
341 ctx.m_mutex= m_mutex;
342 m_ctx= &ctx;
343 bool stop= false;
344 while(!stop) {
345 NdbMutex_Lock(m_mutex);
347 m_input->reset_timeout();
348 m_output->reset_timeout();
350 m_parser->run(ctx, *this);
352 if(ctx.m_currentToken == 0)
354 NdbMutex_Unlock(m_mutex);
355 break;
358 switch(ctx.m_status) {
359 case Parser_t::UnknownCommand:
360 break;
361 default:
362 break;
365 stop= m_stop;
366 NdbMutex_Unlock(m_mutex);
369 NdbMutex_Lock(m_mutex);
370 m_ctx= NULL;
371 if(m_socket != NDB_INVALID_SOCKET)
373 NDB_CLOSE_SOCKET(m_socket);
374 m_socket= NDB_INVALID_SOCKET;
376 NdbMutex_Unlock(m_mutex);
377 DBUG_VOID_RETURN;
380 static Properties *
381 backward(const char * base, const Properties* reply){
382 Properties * ret = new Properties();
383 Properties::Iterator it(reply);
384 for(const char * name = it.first(); name != 0; name=it.next()){
385 PropertiesType type;
386 reply->getTypeOf(name, &type);
387 switch(type){
388 case PropertiesType_Uint32:{
389 Uint32 val;
390 reply->get(name, &val);
391 ret->put(name, val);
393 break;
394 case PropertiesType_char:
396 const char * val;
397 reply->get(name, &val);
398 ret->put(name, val);
399 if(!strcmp(name, "Type") && !strcmp(val, "DB")){
400 ret->put("NoOfDiskBufferPages", (unsigned)0);
401 ret->put("NoOfDiskFiles", (unsigned)0);
402 ret->put("NoOfDiskClusters", (unsigned)0);
403 ret->put("NoOfFreeDiskClusters", (unsigned)0);
404 ret->put("NoOfDiskClustersPerDiskFile", (unsigned)0);
405 ret->put("NoOfConcurrentCheckpointsDuringRestart", (unsigned)1);
406 ret->put("NoOfConcurrentCheckpointsAfterRestart", (unsigned)1);
407 ret->put("NoOfConcurrentProcessesHandleTakeover", (unsigned)1);
410 break;
411 case PropertiesType_Properties:
413 const Properties * recurse;
414 reply->get(name, &recurse);
415 Properties * val = backward(name, recurse);
416 ret->put(name, val);
418 break;
419 case PropertiesType_Uint64:
420 break;
423 return ret;
426 void
427 MgmApiSession::get_nodeid(Parser_t::Context &,
428 const class Properties &args)
430 const char *cmd= "get nodeid reply";
431 Uint32 version, nodeid= 0, nodetype= 0xff;
432 Uint32 timeout= 20; // default seconds timeout
433 const char * transporter;
434 const char * user;
435 const char * password;
436 const char * public_key;
437 const char * endian= NULL;
438 const char * name= NULL;
439 Uint32 log_event= 1;
440 bool log_event_version;
441 union { long l; char c[sizeof(long)]; } endian_check;
443 args.get("version", &version);
444 args.get("nodetype", &nodetype);
445 args.get("transporter", &transporter);
446 args.get("nodeid", &nodeid);
447 args.get("user", &user);
448 args.get("password", &password);
449 args.get("public key", &public_key);
450 args.get("endian", &endian);
451 args.get("name", &name);
452 args.get("timeout", &timeout);
453 /* for backwards compatability keep track if client uses new protocol */
454 log_event_version= args.get("log_event", &log_event);
456 endian_check.l = 1;
457 if(endian
458 && strcmp(endian,(endian_check.c[sizeof(long)-1])?"big":"little")!=0) {
459 m_output->println(cmd);
460 m_output->println("result: Node does not have the same endianness as the management server.");
461 m_output->println("");
462 return;
465 bool compatible;
466 switch (nodetype) {
467 case NODE_TYPE_MGM:
468 case NODE_TYPE_API:
469 compatible = ndbCompatible_mgmt_api(NDB_VERSION, version);
470 break;
471 case NODE_TYPE_DB:
472 compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version);
473 break;
474 default:
475 m_output->println(cmd);
476 m_output->println("result: unknown nodetype %d", nodetype);
477 m_output->println("");
478 return;
481 struct sockaddr_in addr;
482 SOCKET_SIZE_TYPE addrlen= sizeof(addr);
483 int r = getpeername(m_socket, (struct sockaddr*)&addr, &addrlen);
484 if (r != 0 ) {
485 m_output->println(cmd);
486 m_output->println("result: getpeername(%d) failed, err= %d", m_socket, r);
487 m_output->println("");
488 return;
491 NodeId tmp= nodeid;
492 if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){
493 BaseString error_string;
494 int error_code;
495 NDB_TICKS tick= 0;
496 /* only report error on second attempt as not to clog the cluster log */
497 while (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype,
498 (struct sockaddr*)&addr, &addrlen,
499 error_code, error_string,
500 tick == 0 ? 0 : log_event))
502 /* NDB_MGM_ALLOCID_CONFIG_MISMATCH is a non retriable error */
503 if (tick == 0 && error_code != NDB_MGM_ALLOCID_CONFIG_MISMATCH)
505 // attempt to free any timed out reservations
506 tick= NdbTick_CurrentMillisecond();
507 struct PurgeStruct ps;
508 m_mgmsrv.get_connected_nodes(ps.free_nodes);
509 // invert connected_nodes to get free nodes
510 ps.free_nodes.bitXORC(NodeBitmask());
511 ps.str= 0;
512 ps.tick= tick;
513 m_mgmsrv.get_socket_server()->
514 foreachSession(stop_session_if_timed_out,&ps);
515 m_mgmsrv.get_socket_server()->checkSessions();
516 error_string = "";
517 continue;
519 const char *alias;
520 const char *str;
521 alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)
522 nodetype, &str);
523 m_output->println(cmd);
524 m_output->println("result: %s", error_string.c_str());
525 /* only use error_code protocol if client knows about it */
526 if (log_event_version)
527 m_output->println("error_code: %d", error_code);
528 m_output->println("");
529 return;
533 #if 0
534 if (!compatible){
535 m_output->println(cmd);
536 m_output->println("result: incompatible version mgmt 0x%x and node 0x%x",
537 NDB_VERSION, version);
538 m_output->println("");
539 return;
541 #endif
543 m_output->println(cmd);
544 m_output->println("nodeid: %u", tmp);
545 m_output->println("result: Ok");
546 m_output->println("");
547 m_allocated_resources->reserve_node(tmp, timeout*1000);
549 if (name)
550 g_eventLogger.info("Node %d: %s", tmp, name);
552 return;
555 void
556 MgmApiSession::getConfig(Parser_t::Context &,
557 const class Properties &args)
559 Uint32 version, node = 0;
561 args.get("version", &version);
562 args.get("node", &node);
564 const Config *conf = m_mgmsrv.getConfig();
565 if(conf == NULL) {
566 m_output->println("get config reply");
567 m_output->println("result: Could not fetch configuration");
568 m_output->println("");
569 return;
572 if(node != 0){
573 bool compatible;
574 switch (m_mgmsrv.getNodeType(node)) {
575 case NDB_MGM_NODE_TYPE_NDB:
576 compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version);
577 break;
578 case NDB_MGM_NODE_TYPE_API:
579 case NDB_MGM_NODE_TYPE_MGM:
580 compatible = ndbCompatible_mgmt_api(NDB_VERSION, version);
581 break;
582 default:
583 m_output->println("get config");
584 m_output->println("result: unrecognignized node type");
585 m_output->println("");
586 return;
589 if (!compatible){
590 m_output->println("get config");
591 m_output->println("result: incompatible version mgmt 0x%x and node 0x%x",
592 NDB_VERSION, version);
593 m_output->println("");
594 return;
598 NdbMutex_Lock(m_mgmsrv.m_configMutex);
599 const ConfigValues * cfg = &conf->m_configValues->m_config;
601 UtilBuffer src;
602 cfg->pack(src);
603 NdbMutex_Unlock(m_mgmsrv.m_configMutex);
605 char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length()));
606 (void) base64_encode(src.get_data(), src.length(), tmp_str);
608 SLEEP_ERROR_INSERTED(1);
610 m_output->println("get config reply");
611 m_output->println("result: Ok");
612 m_output->println("Content-Length: %d", strlen(tmp_str));
613 m_output->println("Content-Type: ndbconfig/octet-stream");
614 SLEEP_ERROR_INSERTED(2);
615 m_output->println("Content-Transfer-Encoding: base64");
616 m_output->println("");
617 if(ERROR_INSERTED(3))
619 int l= strlen(tmp_str);
620 tmp_str[l/2]='\0';
621 m_output->println(tmp_str);
622 NdbSleep_SecSleep(10);
624 m_output->println(tmp_str);
626 free(tmp_str);
627 return;
630 void
631 MgmApiSession::insertError(Parser<MgmApiSession>::Context &,
632 Properties const &args) {
633 Uint32 node = 0, error = 0;
634 int result= 0;
636 args.get("node", &node);
637 args.get("error", &error);
639 if(node==m_mgmsrv.getOwnNodeId()
640 && error < MGM_ERROR_MAX_INJECT_SESSION_ONLY)
642 m_errorInsert= error;
643 if(error==0)
644 g_errorInsert= error;
646 else
648 result= m_mgmsrv.insertError(node, error);
651 m_output->println("insert error reply");
652 if(result != 0)
653 m_output->println("result: %s", get_error_text(result));
654 else
655 m_output->println("result: Ok");
656 m_output->println("");
659 void
660 MgmApiSession::setTrace(Parser<MgmApiSession>::Context &,
661 Properties const &args) {
662 Uint32 node = 0, trace = 0;
664 args.get("node", &node);
665 args.get("trace", &trace);
667 int result = m_mgmsrv.setTraceNo(node, trace);
669 m_output->println("set trace reply");
670 if(result != 0)
671 m_output->println("result: %s", get_error_text(result));
672 else
673 m_output->println("result: Ok");
674 m_output->println("");
677 void
678 MgmApiSession::getVersion(Parser<MgmApiSession>::Context &,
679 Properties const &) {
680 m_output->println("version");
681 m_output->println("id: %d", NDB_VERSION);
682 m_output->println("major: %d", getMajor(NDB_VERSION));
683 m_output->println("minor: %d", getMinor(NDB_VERSION));
684 m_output->println("string: %s", NDB_VERSION_STRING);
685 m_output->println("");
688 void
689 MgmApiSession::startBackup(Parser<MgmApiSession>::Context &,
690 Properties const &args) {
691 DBUG_ENTER("MgmApiSession::startBackup");
692 unsigned backupId;
693 Uint32 completed= 2;
694 int result;
696 args.get("completed", &completed);
698 result = m_mgmsrv.startBackup(backupId, completed);
700 m_output->println("start backup reply");
701 if(result != 0)
703 m_output->println("result: %s", get_error_text(result));
705 else{
706 m_output->println("result: Ok");
707 if (completed)
708 m_output->println("id: %d", backupId);
710 m_output->println("");
711 DBUG_VOID_RETURN;
714 void
715 MgmApiSession::abortBackup(Parser<MgmApiSession>::Context &,
716 Properties const &args) {
717 Uint32 id = 0;
719 args.get("id", &id);
721 int result = m_mgmsrv.abortBackup(id);
723 m_output->println("abort backup reply");
724 if(result != 0)
725 m_output->println("result: %s", get_error_text(result));
726 else
727 m_output->println("result: Ok");
728 m_output->println("");
731 /*****************************************************************************/
733 void
734 MgmApiSession::dumpState(Parser<MgmApiSession>::Context &,
735 Properties const &args) {
736 Uint32 node;
737 BaseString args_str;
739 args.get("node", &node);
740 args.get("args", args_str);
742 int result = m_mgmsrv.dumpState(node, args_str.c_str());
743 m_output->println("dump state reply");
744 if(result != 0)
745 m_output->println("result: %s", get_error_text(result));
746 else
747 m_output->println("result: Ok");
748 m_output->println("");
752 void
753 MgmApiSession::bye(Parser<MgmApiSession>::Context &,
754 Properties const &) {
755 m_stop = true;
758 void
759 MgmApiSession::endSession(Parser<MgmApiSession>::Context &,
760 Properties const &) {
761 if(m_allocated_resources)
762 delete m_allocated_resources;
764 m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv);
766 SLEEP_ERROR_INSERTED(4);
767 m_output->println("end session reply");
770 void
771 MgmApiSession::getClusterLogLevel(Parser<MgmApiSession>::Context & , Properties const &) {
772 const char* names[] = { "startup",
773 "shutdown",
774 "statistics",
775 "checkpoint",
776 "noderestart",
777 "connection",
778 "info",
779 "warning",
780 "error",
781 "congestion",
782 "debug",
783 "backup" };
785 int loglevel_count = (CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1) ;
786 LogLevel::EventCategory category;
788 m_output->println("get cluster loglevel");
789 for(int i = 0; i < loglevel_count; i++) {
790 category = (LogLevel::EventCategory) i;
791 m_output->println("%s: %d", names[i], m_mgmsrv.m_event_listner[0].m_logLevel.getLogLevel(category));
793 m_output->println("");
796 void
797 MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
798 Properties const &args) {
799 const char *reply= "set cluster loglevel reply";
800 Uint32 node, level, cat;
801 BaseString errorString;
802 DBUG_ENTER("MgmApiSession::setClusterLogLevel");
803 args.get("node", &node);
804 args.get("category", &cat);
805 args.get("level", &level);
807 DBUG_PRINT("enter",("node=%d, category=%d, level=%d", node, cat, level));
809 if(level > NDB_MGM_MAX_LOGLEVEL) {
810 m_output->println(reply);
811 m_output->println("result: Invalid loglevel %d", level);
812 m_output->println("");
813 DBUG_VOID_RETURN;
816 LogLevel::EventCategory category=
817 (LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL);
819 m_mgmsrv.m_event_listner.lock();
820 if (m_mgmsrv.m_event_listner[0].m_logLevel.setLogLevel(category,level))
822 m_output->println(reply);
823 m_output->println("result: Invalid category %d", category);
824 m_output->println("");
825 m_mgmsrv.m_event_listner.unlock();
826 DBUG_VOID_RETURN;
828 m_mgmsrv.m_event_listner.unlock();
831 LogLevel tmp;
832 m_mgmsrv.m_event_listner.update_max_log_level(tmp);
835 m_output->println(reply);
836 m_output->println("result: Ok");
837 m_output->println("");
838 DBUG_VOID_RETURN;
841 void
842 MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &,
843 Properties const &args) {
844 Uint32 node = 0, level = 0, cat;
845 BaseString errorString;
846 SetLogLevelOrd logLevel;
847 logLevel.clear();
848 args.get("node", &node);
849 args.get("category", &cat);
850 args.get("level", &level);
852 if(level > NDB_MGM_MAX_LOGLEVEL) {
853 m_output->println("set loglevel reply");
854 m_output->println("result: Invalid loglevel", errorString.c_str());
855 m_output->println("");
856 return;
859 LogLevel::EventCategory category=
860 (LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL);
863 LogLevel ll;
864 ll.setLogLevel(category,level);
865 m_mgmsrv.m_event_listner.update_max_log_level(ll);
868 m_output->println("set loglevel reply");
869 m_output->println("result: Ok");
870 m_output->println("");
873 void
874 MgmApiSession::stopSignalLog(Parser<MgmApiSession>::Context &,
875 Properties const &args) {
876 Uint32 node;
878 args.get("node", &node);
880 int result = m_mgmsrv.stopSignalTracing(node);
882 m_output->println("stop signallog");
883 if(result != 0)
884 m_output->println("result: %s", get_error_text(result));
885 else
886 m_output->println("result: Ok");
887 m_output->println("");
890 void
891 MgmApiSession::restart_v1(Parser<MgmApiSession>::Context &,
892 Properties const &args) {
893 restart(args,1);
896 void
897 MgmApiSession::restart_v2(Parser<MgmApiSession>::Context &,
898 Properties const &args) {
899 restart(args,2);
902 void
903 MgmApiSession::restart(Properties const &args, int version) {
904 Uint32
905 nostart = 0,
906 initialstart = 0,
907 abort = 0;
908 char *nodes_str;
909 Vector<NodeId> nodes;
911 args.get("initialstart", &initialstart);
912 args.get("nostart", &nostart);
913 args.get("abort", &abort);
914 args.get("node", (const char **)&nodes_str);
916 char *p, *last;
917 for((p = strtok_r(nodes_str, " ", &last));
919 (p = strtok_r(NULL, " ", &last))) {
920 nodes.push_back(atoi(p));
923 int restarted = 0;
924 int result= m_mgmsrv.restartNodes(nodes,
925 &restarted,
926 nostart != 0,
927 initialstart != 0,
928 abort != 0,
929 &m_stopSelf);
931 m_output->println("restart reply");
932 if(result != 0){
933 m_output->println("result: %d-%s", result, get_error_text(result));
934 } else
935 m_output->println("result: Ok");
936 m_output->println("restarted: %d", restarted);
937 if(version>1)
938 m_output->println("disconnect: %d", (m_stopSelf)?1:0);
939 m_output->println("");
942 void
943 MgmApiSession::restartAll(Parser<MgmApiSession>::Context &,
944 Properties const &args)
946 Uint32 nostart = 0;
947 Uint32 initialstart = 0;
948 Uint32 abort = 0;
950 args.get("initialstart", &initialstart);
951 args.get("abort", &abort);
952 args.get("nostart", &nostart);
954 int count = 0;
955 int result = m_mgmsrv.restartDB(nostart, initialstart, abort, &count);
957 m_output->println("restart reply");
958 if(result != 0)
959 m_output->println("result: %s", get_error_text(result));
960 else
961 m_output->println("result: Ok");
962 m_output->println("restarted: %d", count);
963 m_output->println("");
966 static void
967 printNodeStatus(OutputStream *output,
968 MgmtSrvr &mgmsrv,
969 enum ndb_mgm_node_type type) {
970 NodeId nodeId = 0;
971 while(mgmsrv.getNextNodeId(&nodeId, type)) {
972 enum ndb_mgm_node_status status;
973 Uint32 startPhase = 0,
974 version = 0,
975 dynamicId = 0,
976 nodeGroup = 0,
977 connectCount = 0;
978 bool system;
979 const char *address= NULL;
980 mgmsrv.status(nodeId, &status, &version, &startPhase,
981 &system, &dynamicId, &nodeGroup, &connectCount,
982 &address);
983 output->println("node.%d.type: %s",
984 nodeId,
985 ndb_mgm_get_node_type_string(type));
986 output->println("node.%d.status: %s",
987 nodeId,
988 ndb_mgm_get_node_status_string(status));
989 output->println("node.%d.version: %d", nodeId, version);
990 output->println("node.%d.startphase: %d", nodeId, startPhase);
991 output->println("node.%d.dynamic_id: %d", nodeId, dynamicId);
992 output->println("node.%d.node_group: %d", nodeId, nodeGroup);
993 output->println("node.%d.connect_count: %d", nodeId, connectCount);
994 output->println("node.%d.address: %s", nodeId, address ? address : "");
999 void
1000 MgmApiSession::getStatus(Parser<MgmApiSession>::Context &,
1001 Properties const &) {
1002 int noOfNodes = 0;
1004 NodeId nodeId = 0;
1005 while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
1006 noOfNodes++;
1008 nodeId = 0;
1009 while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_API)){
1010 noOfNodes++;
1012 nodeId = 0;
1013 while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM)){
1014 noOfNodes++;
1016 SLEEP_ERROR_INSERTED(5);
1017 m_output->println("node status");
1018 SLEEP_ERROR_INSERTED(6);
1019 m_output->println("nodes: %d", noOfNodes);
1020 m_mgmsrv.updateStatus();
1021 SLEEP_ERROR_INSERTED(7);
1022 printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_NDB);
1023 printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_MGM);
1024 SLEEP_ERROR_INSERTED(8);
1025 printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_API);
1026 SLEEP_ERROR_INSERTED(9);
1028 nodeId = 0;
1030 m_output->println("");
1033 void
1034 MgmApiSession::getInfoClusterLog(Parser<MgmApiSession>::Context &,
1035 Properties const &) {
1036 const char* names[] = { "enabled",
1037 "debug",
1038 "info",
1039 "warning",
1040 "error",
1041 "critical",
1042 "alert" };
1044 m_output->println("clusterlog");
1045 for(int i = 0; i < 7; i++) {
1046 m_output->println("%s: %d",
1047 names[i], m_mgmsrv.isEventLogFilterEnabled(i));
1049 m_output->println("");
1052 void
1053 MgmApiSession::stop_v1(Parser<MgmApiSession>::Context &,
1054 Properties const &args) {
1055 stop(args,1);
1058 void
1059 MgmApiSession::stop_v2(Parser<MgmApiSession>::Context &,
1060 Properties const &args) {
1061 stop(args,2);
1064 void
1065 MgmApiSession::stop(Properties const &args, int version) {
1066 Uint32 abort;
1067 char *nodes_str;
1068 Vector<NodeId> nodes;
1070 args.get("node", (const char **)&nodes_str);
1071 if(nodes_str == NULL)
1073 m_output->println("stop reply");
1074 m_output->println("result: empty node list");
1075 m_output->println("");
1076 return;
1078 args.get("abort", &abort);
1080 char *p, *last;
1081 for((p = strtok_r(nodes_str, " ", &last));
1083 (p = strtok_r(NULL, " ", &last))) {
1084 nodes.push_back(atoi(p));
1087 int stopped= 0;
1088 int result= 0;
1089 if (nodes.size())
1090 result= m_mgmsrv.stopNodes(nodes, &stopped, abort != 0, &m_stopSelf);
1092 m_output->println("stop reply");
1093 if(result != 0)
1094 m_output->println("result: %s", get_error_text(result));
1095 else
1096 m_output->println("result: Ok");
1097 m_output->println("stopped: %d", stopped);
1098 if(version>1)
1099 m_output->println("disconnect: %d", (m_stopSelf)?1:0);
1100 m_output->println("");
1103 void
1104 MgmApiSession::stopAll(Parser<MgmApiSession>::Context &,
1105 Properties const &args) {
1106 int stopped[2] = {0,0};
1107 Uint32 abort;
1108 args.get("abort", &abort);
1110 BaseString stop;
1111 const char* tostop= "db";
1112 int ver=1;
1113 if (args.get("stop", stop))
1115 tostop= stop.c_str();
1116 ver= 2;
1119 int result= 0;
1120 if(strstr(tostop,"db"))
1121 result= m_mgmsrv.shutdownDB(&stopped[0], abort != 0);
1122 if(!result && strstr(tostop,"mgm"))
1123 result= m_mgmsrv.shutdownMGM(&stopped[1], abort!=0, &m_stopSelf);
1125 m_output->println("stop reply");
1126 if(result != 0)
1127 m_output->println("result: %s", get_error_text(result));
1128 else
1129 m_output->println("result: Ok");
1130 m_output->println("stopped: %d", stopped[0]+stopped[1]);
1131 if(ver >1)
1132 m_output->println("disconnect: %d", (m_stopSelf)?1:0);
1133 m_output->println("");
1136 void
1137 MgmApiSession::enterSingleUser(Parser<MgmApiSession>::Context &,
1138 Properties const &args) {
1139 int stopped = 0;
1140 Uint32 nodeId = 0;
1141 int result= 0;
1142 args.get("nodeId", &nodeId);
1144 result = m_mgmsrv.enterSingleUser(&stopped, nodeId);
1145 m_output->println("enter single user reply");
1146 if(result != 0) {
1147 m_output->println("result: %s", get_error_text(result));
1149 else {
1150 m_output->println("result: Ok");
1152 m_output->println("");
1155 void
1156 MgmApiSession::exitSingleUser(Parser<MgmApiSession>::Context &,
1157 Properties const &args) {
1158 int stopped = 0;
1159 int result = m_mgmsrv.exitSingleUser(&stopped, false);
1160 m_output->println("exit single user reply");
1161 if(result != 0)
1162 m_output->println("result: %s", get_error_text(result));
1163 else
1164 m_output->println("result: Ok");
1165 m_output->println("");
1169 void
1170 MgmApiSession::startSignalLog(Parser<MgmApiSession>::Context &,
1171 Properties const &args) {
1172 Uint32 node;
1174 args.get("node", &node);
1176 int result = m_mgmsrv.startSignalTracing(node);
1178 m_output->println("start signallog reply");
1179 if(result != 0)
1180 m_output->println("result: %s", get_error_text(result));
1181 else
1182 m_output->println("result: Ok");
1183 m_output->println("");
1186 void
1187 MgmApiSession::logSignals(Parser<MgmApiSession>::Context &,
1188 Properties const &args) {
1189 Uint32 node = 0, in = 0, out = 0;
1190 // BaseString blocks;
1191 BaseString blockList;
1192 char * blockName;
1193 args.get("node", &node);
1194 args.get("in", &in);
1195 args.get("out", &out);
1196 args.get("blocks", blockList);
1197 // fast fix - pekka
1198 char buf[200];
1199 BaseString::snprintf(buf, 200, "%s", blockList.c_str());
1200 Vector<BaseString> blocks;
1202 blockName=strtok(buf,"|");
1203 while( blockName != NULL)
1205 blocks.push_back(blockName);
1206 blockName=strtok(NULL,"|");
1210 if(in > 1 || out > 1)
1211 return; /* Invalid arguments */
1213 const MgmtSrvr::LogMode modes[] = {
1214 MgmtSrvr::Off,
1215 MgmtSrvr::Out,
1216 MgmtSrvr::In,
1217 MgmtSrvr::InOut,
1219 MgmtSrvr::LogMode mode = modes[in<<1 | out];
1221 int result = m_mgmsrv.setSignalLoggingMode(node, mode, blocks);
1223 m_output->println("log signals reply");
1224 if(result != 0)
1225 m_output->println("result: %s", get_error_text(result));
1226 else
1227 m_output->println("result: Ok");
1228 m_output->println("");
1231 void
1232 MgmApiSession::start(Parser<MgmApiSession>::Context &,
1233 Properties const &args) {
1234 Uint32 node;
1236 args.get("node", &node);
1238 int result = m_mgmsrv.start(node);
1240 m_output->println("start reply");
1241 if(result != 0)
1242 m_output->println("result: %s", get_error_text(result));
1243 else
1244 m_output->println("result: Ok");
1245 m_output->println("");
1248 void
1249 MgmApiSession::startAll(Parser<MgmApiSession>::Context &,
1250 Properties const &) {
1251 NodeId node = 0;
1252 int started = 0;
1254 while(m_mgmsrv.getNextNodeId(&node, NDB_MGM_NODE_TYPE_NDB))
1255 if(m_mgmsrv.start(node) == 0)
1256 started++;
1258 m_output->println("start reply");
1259 m_output->println("result: Ok");
1260 m_output->println("started: %d", started);
1261 m_output->println("");
1264 void
1265 MgmApiSession::setLogFilter(Parser_t::Context &ctx,
1266 const class Properties &args) {
1267 Uint32 severity;
1268 Uint32 enable;
1270 args.get("level", &severity);
1271 args.get("enable", &enable);
1273 int result = m_mgmsrv.setEventLogFilter(severity, enable);
1275 m_output->println("set logfilter reply");
1276 m_output->println("result: %d", result);
1277 m_output->println("");
1280 #ifdef NOT_USED
1282 static NdbOut&
1283 operator<<(NdbOut& out, const LogLevel & ll)
1285 out << "[LogLevel: ";
1286 for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++)
1287 out << ll.getLogLevel((LogLevel::EventCategory)i) << " ";
1288 out << "]";
1289 return out;
1291 #endif
1293 void
1294 Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId){
1296 Uint32 threshold;
1297 LogLevel::EventCategory cat;
1298 Logger::LoggerLevel severity;
1299 EventLoggerBase::EventTextFunction textF;
1300 int i, n;
1301 DBUG_ENTER("Ndb_mgmd_event_service::log");
1302 DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId));
1304 if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity,textF))
1305 DBUG_VOID_RETURN;
1307 char m_text[512];
1308 EventLogger::getText(m_text, sizeof(m_text),
1309 textF, theData, nodeId);
1311 BaseString str("log event reply\n");
1312 str.appfmt("type=%d\n", eventType);
1313 str.appfmt("time=%d\n", 0);
1314 str.appfmt("source_nodeid=%d\n", nodeId);
1315 for (i= 0; ndb_logevent_body[i].token; i++)
1317 if ( ndb_logevent_body[i].type != eventType)
1318 continue;
1319 int val= theData[ndb_logevent_body[i].index];
1320 if (ndb_logevent_body[i].index_fn)
1321 val= (*(ndb_logevent_body[i].index_fn))(val);
1322 str.appfmt("%s=%d\n",ndb_logevent_body[i].token, val);
1323 if(strcmp(ndb_logevent_body[i].token,"error") == 0)
1325 int m_text_len= strlen(m_text);
1326 if(sizeof(m_text)-m_text_len-3 > 0)
1328 BaseString::snprintf(m_text+m_text_len, 4 , " - ");
1329 ndb_error_string(val, m_text+(m_text_len+3), sizeof(m_text)-m_text_len-3);
1334 Vector<NDB_SOCKET_TYPE> copy;
1335 m_clients.lock();
1336 for(i = m_clients.size() - 1; i >= 0; i--)
1338 if(threshold <= m_clients[i].m_logLevel.getLogLevel(cat))
1340 if(m_clients[i].m_socket==NDB_INVALID_SOCKET)
1341 continue;
1343 SocketOutputStream out(m_clients[i].m_socket);
1345 int r;
1346 if (m_clients[i].m_parsable)
1347 r= out.println(str.c_str());
1348 else
1349 r= out.println(m_text);
1351 if (r<0)
1353 copy.push_back(m_clients[i].m_socket);
1354 m_clients.erase(i, false);
1358 m_clients.unlock();
1360 if ((n= (int)copy.size()))
1362 for(i= 0; i < n; i++)
1363 NDB_CLOSE_SOCKET(copy[i]);
1365 LogLevel tmp; tmp.clear();
1366 m_clients.lock();
1367 for(i= m_clients.size() - 1; i >= 0; i--)
1368 tmp.set_max(m_clients[i].m_logLevel);
1369 m_clients.unlock();
1370 update_log_level(tmp);
1372 DBUG_VOID_RETURN;
1375 void
1376 Ndb_mgmd_event_service::update_max_log_level(const LogLevel &log_level)
1378 LogLevel tmp = log_level;
1379 m_clients.lock();
1380 for(int i = m_clients.size() - 1; i >= 0; i--)
1381 tmp.set_max(m_clients[i].m_logLevel);
1382 m_clients.unlock();
1383 update_log_level(tmp);
1386 void
1387 Ndb_mgmd_event_service::update_log_level(const LogLevel &tmp)
1389 m_logLevel = tmp;
1390 EventSubscribeReq req;
1391 req = tmp;
1392 // send update to all nodes
1393 req.blockRef = 0;
1394 m_mgmsrv->m_log_level_requests.push_back(req);
1397 void
1398 Ndb_mgmd_event_service::check_listeners()
1400 int i, n= 0;
1401 DBUG_ENTER("Ndb_mgmd_event_service::check_listeners");
1402 m_clients.lock();
1403 for(i= m_clients.size() - 1; i >= 0; i--)
1405 if(m_clients[i].m_socket==NDB_INVALID_SOCKET)
1406 continue;
1408 SocketOutputStream out(m_clients[i].m_socket);
1410 DBUG_PRINT("info",("%d %d",i,m_clients[i].m_socket));
1412 if(out.println("<PING>") < 0)
1414 NDB_CLOSE_SOCKET(m_clients[i].m_socket);
1415 m_clients.erase(i, false);
1416 n=1;
1419 if (n)
1421 LogLevel tmp; tmp.clear();
1422 for(i= m_clients.size() - 1; i >= 0; i--)
1423 tmp.set_max(m_clients[i].m_logLevel);
1424 update_log_level(tmp);
1426 m_clients.unlock();
1427 DBUG_VOID_RETURN;
1430 void
1431 Ndb_mgmd_event_service::add_listener(const Event_listener& client)
1433 DBUG_ENTER("Ndb_mgmd_event_service::add_listener");
1434 DBUG_PRINT("enter",("client.m_socket: %d", client.m_socket));
1436 check_listeners();
1438 m_clients.push_back(client);
1439 update_max_log_level(client.m_logLevel);
1441 DBUG_VOID_RETURN;
1444 void
1445 Ndb_mgmd_event_service::stop_sessions(){
1446 m_clients.lock();
1447 for(int i = m_clients.size() - 1; i >= 0; i--){
1448 if(m_clients[i].m_socket != NDB_INVALID_SOCKET){
1449 NDB_CLOSE_SOCKET(m_clients[i].m_socket);
1450 m_clients.erase(i);
1453 m_clients.unlock();
1456 void
1457 MgmApiSession::setParameter(Parser_t::Context &,
1458 Properties const &args) {
1459 BaseString node, param, value;
1460 args.get("node", node);
1461 args.get("parameter", param);
1462 args.get("value", value);
1464 BaseString result;
1465 int ret = m_mgmsrv.setDbParameter(atoi(node.c_str()),
1466 atoi(param.c_str()),
1467 value.c_str(),
1468 result);
1470 m_output->println("set parameter reply");
1471 m_output->println("message: %s", result.c_str());
1472 m_output->println("result: %d", ret);
1473 m_output->println("");
1476 void
1477 MgmApiSession::setConnectionParameter(Parser_t::Context &ctx,
1478 Properties const &args) {
1479 BaseString node1, node2, param, value;
1480 args.get("node1", node1);
1481 args.get("node2", node2);
1482 args.get("param", param);
1483 args.get("value", value);
1485 BaseString result;
1486 int ret = m_mgmsrv.setConnectionDbParameter(atoi(node1.c_str()),
1487 atoi(node2.c_str()),
1488 atoi(param.c_str()),
1489 atoi(value.c_str()),
1490 result);
1492 m_output->println("set connection parameter reply");
1493 m_output->println("message: %s", result.c_str());
1494 m_output->println("result: %s", (ret>0)?"Ok":"Failed");
1495 m_output->println("");
1498 void
1499 MgmApiSession::getConnectionParameter(Parser_t::Context &ctx,
1500 Properties const &args) {
1501 BaseString node1, node2, param;
1502 int value = 0;
1504 args.get("node1", node1);
1505 args.get("node2", node2);
1506 args.get("param", param);
1508 BaseString result;
1509 int ret = m_mgmsrv.getConnectionDbParameter(atoi(node1.c_str()),
1510 atoi(node2.c_str()),
1511 atoi(param.c_str()),
1512 &value,
1513 result);
1515 m_output->println("get connection parameter reply");
1516 m_output->println("value: %d", value);
1517 m_output->println("result: %s", (ret>0)?"Ok":result.c_str());
1518 m_output->println("");
1521 void
1522 MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx,
1523 Properties const & args) {
1524 Uint32 parsable= 0;
1525 BaseString node, param, value;
1526 args.get("node", node);
1527 args.get("filter", param);
1528 args.get("parsable", &parsable);
1530 int result = 0;
1531 BaseString msg;
1533 Ndb_mgmd_event_service::Event_listener le;
1534 le.m_parsable = parsable;
1535 le.m_socket = m_socket;
1537 Vector<BaseString> list;
1538 param.trim();
1539 param.split(list, " ,");
1540 for(size_t i = 0; i<list.size(); i++){
1541 Vector<BaseString> spec;
1542 list[i].trim();
1543 list[i].split(spec, "=:");
1544 if(spec.size() != 2){
1545 msg.appfmt("Invalid filter specification: >%s< >%s< %d",
1546 param.c_str(), list[i].c_str(), spec.size());
1547 result = -1;
1548 goto done;
1551 spec[0].trim().ndb_toupper();
1552 int category = ndb_mgm_match_event_category(spec[0].c_str());
1553 if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){
1554 category = atoi(spec[0].c_str());
1555 if(category < NDB_MGM_MIN_EVENT_CATEGORY ||
1556 category > NDB_MGM_MAX_EVENT_CATEGORY){
1557 msg.appfmt("Unknown category: >%s<", spec[0].c_str());
1558 result = -1;
1559 goto done;
1563 int level = atoi(spec[1].c_str());
1564 if(level < 0 || level > NDB_MGM_MAX_LOGLEVEL){
1565 msg.appfmt("Invalid level: >%s<", spec[1].c_str());
1566 result = -1;
1567 goto done;
1569 category -= CFG_MIN_LOGLEVEL;
1570 le.m_logLevel.setLogLevel((LogLevel::EventCategory)category, level);
1573 if(list.size() == 0){
1574 msg.appfmt("Empty filter specification");
1575 result = -1;
1576 goto done;
1579 done:
1580 m_output->println("listen event");
1581 m_output->println("result: %d", result);
1582 if(result != 0)
1583 m_output->println("msg: %s", msg.c_str());
1584 m_output->println("");
1586 if(result==0)
1588 m_mgmsrv.m_event_listner.add_listener(le);
1589 m_stop = true;
1590 m_socket = NDB_INVALID_SOCKET;
1594 void
1595 MgmApiSession::stop_session_if_not_connected(SocketServer::Session *_s, void *data)
1597 MgmApiSession *s= (MgmApiSession *)_s;
1598 struct PurgeStruct &ps= *(struct PurgeStruct *)data;
1599 if (s->m_allocated_resources->is_reserved(ps.free_nodes))
1601 if (ps.str)
1602 ps.str->appfmt(" %d", s->m_allocated_resources->get_nodeid());
1603 s->stopSession();
1607 void
1608 MgmApiSession::stop_session_if_timed_out(SocketServer::Session *_s, void *data)
1610 MgmApiSession *s= (MgmApiSession *)_s;
1611 struct PurgeStruct &ps= *(struct PurgeStruct *)data;
1612 if (s->m_allocated_resources->is_reserved(ps.free_nodes) &&
1613 s->m_allocated_resources->is_timed_out(ps.tick))
1615 s->stopSession();
1619 void
1620 MgmApiSession::purge_stale_sessions(Parser_t::Context &ctx,
1621 const class Properties &args)
1623 struct PurgeStruct ps;
1624 BaseString str;
1625 ps.str = &str;
1627 m_mgmsrv.get_connected_nodes(ps.free_nodes);
1628 ps.free_nodes.bitXORC(NodeBitmask()); // invert connected_nodes to get free nodes
1630 m_mgmsrv.get_socket_server()->foreachSession(stop_session_if_not_connected,&ps);
1631 m_mgmsrv.get_socket_server()->checkSessions();
1633 m_output->println("purge stale sessions reply");
1634 if (str.length() > 0)
1635 m_output->println("purged:%s",str.c_str());
1636 m_output->println("result: Ok");
1637 m_output->println("");
1640 void
1641 MgmApiSession::check_connection(Parser_t::Context &ctx,
1642 const class Properties &args)
1644 SLEEP_ERROR_INSERTED(1);
1645 m_output->println("check connection reply");
1646 SLEEP_ERROR_INSERTED(2);
1647 m_output->println("result: Ok");
1648 SLEEP_ERROR_INSERTED(3);
1649 m_output->println("");
1652 void
1653 MgmApiSession::transporter_connect(Parser_t::Context &ctx,
1654 Properties const &args)
1656 m_mgmsrv.transporter_connect(m_socket);
1658 m_stop= true;
1659 m_stopped= true; // force a stop (no closing socket)
1660 m_socket= NDB_INVALID_SOCKET; // so nobody closes it
1663 void
1664 MgmApiSession::get_mgmd_nodeid(Parser_t::Context &ctx,
1665 Properties const &args)
1667 m_output->println("get mgmd nodeid reply");
1668 m_output->println("nodeid:%u",m_mgmsrv.getOwnNodeId());
1669 SLEEP_ERROR_INSERTED(1);
1671 m_output->println("");
1674 void
1675 MgmApiSession::report_event(Parser_t::Context &ctx,
1676 Properties const &args)
1678 Uint32 length;
1679 const char *data_string;
1680 Uint32 data[25];
1682 args.get("length", &length);
1683 args.get("data", &data_string);
1685 BaseString tmp(data_string);
1686 Vector<BaseString> item;
1687 tmp.split(item, " ");
1688 for (int i = 0; (Uint32) i < length ; i++)
1690 sscanf(item[i].c_str(), "%u", data+i);
1693 m_mgmsrv.eventReport(data);
1694 m_output->println("report event reply");
1695 m_output->println("result: ok");
1696 m_output->println("");
1699 void
1700 MgmApiSession::list_session(SocketServer::Session *_s, void *data)
1702 MgmApiSession *s= (MgmApiSession *)_s;
1703 MgmApiSession *lister= (MgmApiSession*) data;
1705 if(s!=lister)
1706 NdbMutex_Lock(s->m_mutex);
1708 Uint64 id= s->m_session_id;
1709 lister->m_output->println("session: %llu",id);
1710 lister->m_output->println("session.%llu.m_stopSelf: %d",id,s->m_stopSelf);
1711 lister->m_output->println("session.%llu.m_stop: %d",id,s->m_stop);
1712 lister->m_output->println("session.%llu.allocated.nodeid: %d",id,s->m_allocated_resources->get_nodeid());
1713 if(s->m_ctx)
1715 int l= strlen(s->m_ctx->m_tokenBuffer);
1716 char *buf= (char*) malloc(2*l+1);
1717 char *b= buf;
1718 for(int i=0; i<l;i++)
1719 if(s->m_ctx->m_tokenBuffer[i]=='\n')
1721 *b++='\\';
1722 *b++='n';
1724 else
1726 *b++= s->m_ctx->m_tokenBuffer[i];
1728 *b= '\0';
1730 lister->m_output->println("session.%llu.parser.buffer.len: %u",id,l);
1731 lister->m_output->println("session.%llu.parser.buffer: %s",id,buf);
1732 lister->m_output->println("session.%llu.parser.status: %d",id,s->m_ctx->m_status);
1734 free(buf);
1737 if(s!=lister)
1738 NdbMutex_Unlock(s->m_mutex);
1741 void
1742 MgmApiSession::listSessions(Parser_t::Context &ctx,
1743 Properties const &args) {
1744 m_mgmsrv.get_socket_server()->foreachSession(list_session,(void*)this);
1746 m_output->println("");
1749 void
1750 MgmApiSession::getSessionId(Parser_t::Context &ctx,
1751 Properties const &args) {
1752 m_output->println("get session id reply");
1753 m_output->println("id: %llu",m_session_id);
1754 m_output->println("");
1757 struct get_session_param {
1758 MgmApiSession *l;
1759 Uint64 id;
1760 int found;
1763 void
1764 MgmApiSession::get_session(SocketServer::Session *_s, void *data)
1766 struct get_session_param *p= (struct get_session_param*)data;
1767 MgmApiSession *s= (MgmApiSession *)_s;
1769 if(s!=p->l)
1770 NdbMutex_Lock(s->m_mutex);
1772 if(p->id != s->m_session_id)
1774 if(s!=p->l)
1775 NdbMutex_Unlock(s->m_mutex);
1776 return;
1779 p->found= true;
1780 p->l->m_output->println("id: %llu",s->m_session_id);
1781 p->l->m_output->println("m_stopSelf: %d",s->m_stopSelf);
1782 p->l->m_output->println("m_stop: %d",s->m_stop);
1783 p->l->m_output->println("nodeid: %d",s->m_allocated_resources->get_nodeid());
1784 if(s->m_ctx)
1786 int l= strlen(s->m_ctx->m_tokenBuffer);
1787 p->l->m_output->println("parser_buffer_len: %u",l);
1788 p->l->m_output->println("parser_status: %d",s->m_ctx->m_status);
1791 if(s!=p->l)
1792 NdbMutex_Unlock(s->m_mutex);
1795 void
1796 MgmApiSession::getSession(Parser_t::Context &ctx,
1797 Properties const &args) {
1798 Uint64 id;
1799 struct get_session_param p;
1801 args.get("id", &id);
1803 p.l= this;
1804 p.id= id;
1805 p.found= false;
1807 m_output->println("get session reply");
1808 m_mgmsrv.get_socket_server()->foreachSession(get_session,(void*)&p);
1810 if(p.found==false)
1811 m_output->println("id: 0");
1813 m_output->println("");
1816 template class MutexVector<int>;
1817 template class Vector<ParserRow<MgmApiSession> const*>;