mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
Merge joreland@bk-internal.mysql.com:/home/bk/mysql-5.0-ndb
into mysql.com:/home/jonas/src/mysql-5.0-ndb
This commit is contained in:
commit
7e04795f33
5 changed files with 65 additions and 451 deletions
|
@ -1,4 +1,4 @@
|
|||
SUBDIRS = common mgmapi ndbapi . kernel mgmsrv mgmclient cw
|
||||
SUBDIRS = common mgmapi ndbapi . kernel mgmclient mgmsrv cw
|
||||
|
||||
include $(top_srcdir)/ndb/config/common.mk.am
|
||||
|
||||
|
|
|
@ -1,345 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "CommandInterpreter.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "MgmtSrvr.hpp"
|
||||
#include "MgmtErrorReporter.hpp"
|
||||
#include <NdbOut.hpp>
|
||||
#include "convertStrToInt.hpp"
|
||||
#include <EventLogger.hpp>
|
||||
#include <signaldata/SetLogLevelOrd.hpp>
|
||||
#include "ConfigInfo.hpp"
|
||||
|
||||
#include <version.h>
|
||||
#include <m_string.h>
|
||||
|
||||
//******************************************************************************
|
||||
//******************************************************************************
|
||||
CommandInterpreter::CommandInterpreter(MgmtSrvr& mgmtSrvr) :
|
||||
_mgmtSrvr(mgmtSrvr) {
|
||||
}
|
||||
|
||||
|
||||
bool emptyString(const char* s) {
|
||||
if (s == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < strlen(s); ++i) {
|
||||
if (! isspace(s[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class AutoPtr {
|
||||
public:
|
||||
AutoPtr(void * ptr) : m_ptr(ptr) {}
|
||||
~AutoPtr() { free(m_ptr);}
|
||||
private:
|
||||
void * m_ptr;
|
||||
};
|
||||
|
||||
const char *CommandInterpreter::get_error_text(int err_no)
|
||||
{
|
||||
return _mgmtSrvr.getErrorText(err_no, m_err_str, sizeof(m_err_str));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//*****************************************************************************
|
||||
int CommandInterpreter::readAndExecute() {
|
||||
|
||||
char* _line = readline_gets();
|
||||
char * line;
|
||||
if(_line == NULL) {
|
||||
ndbout << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
line = strdup(_line);
|
||||
|
||||
AutoPtr ptr(line);
|
||||
|
||||
if (emptyString(line)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < strlen(line); ++i) {
|
||||
line[i] = toupper(line[i]);
|
||||
}
|
||||
|
||||
// if there is anything in the line proceed
|
||||
char* firstToken = strtok(line, " ");
|
||||
char* allAfterFirstToken = strtok(NULL, "\0");
|
||||
|
||||
if (strcmp(firstToken, "ALL") == 0) {
|
||||
analyseAfterFirstToken(-1, allAfterFirstToken);
|
||||
}
|
||||
else if(strcmp(firstToken, "QUIT") == 0 ||
|
||||
strcmp(firstToken, "EXIT") == 0 ||
|
||||
strcmp(firstToken, "BYE") == 0){
|
||||
return false;
|
||||
} else {
|
||||
// First token should be a digit, process ID
|
||||
|
||||
int processId;
|
||||
if (! convert(firstToken, processId)) {
|
||||
ndbout << "Invalid command: " << _line << "." << endl;
|
||||
return true;
|
||||
}
|
||||
if (processId < 0) {
|
||||
ndbout << "Invalid process ID: " << firstToken << "." << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
analyseAfterFirstToken(processId, allAfterFirstToken);
|
||||
|
||||
} // else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static const CommandInterpreter::CommandFunctionPair commands[] = {
|
||||
{ "TRACE", &CommandInterpreter::executeTrace }
|
||||
,{ "LOGIN", &CommandInterpreter::executeLogIn }
|
||||
,{ "LOGOUT", &CommandInterpreter::executeLogOut }
|
||||
,{ "LOGOFF", &CommandInterpreter::executeLogOff }
|
||||
};
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//*****************************************************************************
|
||||
void
|
||||
CommandInterpreter::analyseAfterFirstToken(int processId,
|
||||
char* allAfterFirstToken) {
|
||||
|
||||
if (emptyString(allAfterFirstToken)) {
|
||||
if (processId == -1) {
|
||||
ndbout << "Expected a command after ALL." << endl;
|
||||
}
|
||||
else {
|
||||
ndbout << "Expected a command after process ID." << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
char* secondToken = strtok(allAfterFirstToken, " ");
|
||||
char* allAfterSecondToken = strtok(NULL, "\0");
|
||||
|
||||
const int tmpSize = sizeof(commands)/sizeof(CommandFunctionPair);
|
||||
ExecuteFunction fun = 0;
|
||||
const char * command = 0;
|
||||
for(int i = 0; i<tmpSize; i++){
|
||||
if(strcmp(secondToken, commands[i].command) == 0){
|
||||
fun = commands[i].executeFunction;
|
||||
command = commands[i].command;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(fun == 0){
|
||||
ndbout << "Invalid command: " << secondToken << "." << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(processId == -1){
|
||||
executeForAll(command, fun, allAfterSecondToken);
|
||||
} else {
|
||||
ndbout << "Executing " << command << " on node: "
|
||||
<< processId << endl << endl;
|
||||
(this->*fun)(processId, allAfterSecondToken, false);
|
||||
ndbout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
|
||||
const char * allAfterSecondToken){
|
||||
|
||||
NodeId nodeId = 0;
|
||||
while(_mgmtSrvr.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
|
||||
ndbout << "Executing " << cmd << " on node: "
|
||||
<< nodeId << endl << endl;
|
||||
(this->*fun)(nodeId, allAfterSecondToken, true);
|
||||
ndbout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//*****************************************************************************
|
||||
bool CommandInterpreter::parseBlockSpecification(const char* allAfterLog,
|
||||
Vector<BaseString>& blocks) {
|
||||
|
||||
// Parse: [BLOCK = {ALL|<blockName>+}]
|
||||
|
||||
if (emptyString(allAfterLog)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copy allAfterLog since strtok will modify it
|
||||
char* newAllAfterLog = strdup(allAfterLog);
|
||||
char* firstTokenAfterLog = strtok(newAllAfterLog, " ");
|
||||
for (unsigned int i = 0; i < strlen(firstTokenAfterLog); ++i) {
|
||||
firstTokenAfterLog[i] = toupper(firstTokenAfterLog[i]);
|
||||
}
|
||||
|
||||
if (strcmp(firstTokenAfterLog, "BLOCK") != 0) {
|
||||
ndbout << "Unexpected value: " << firstTokenAfterLog
|
||||
<< ". Expected BLOCK." << endl;
|
||||
free(newAllAfterLog);
|
||||
return false;
|
||||
}
|
||||
|
||||
char* allAfterFirstToken = strtok(NULL, "\0");
|
||||
if (emptyString(allAfterFirstToken)) {
|
||||
ndbout << "Expected =." << endl;
|
||||
free(newAllAfterLog);
|
||||
return false;
|
||||
}
|
||||
|
||||
char* secondTokenAfterLog = strtok(allAfterFirstToken, " ");
|
||||
if (strcmp(secondTokenAfterLog, "=") != 0) {
|
||||
ndbout << "Unexpected value: " << secondTokenAfterLog
|
||||
<< ". Expected =." << endl;
|
||||
free(newAllAfterLog);
|
||||
return false;
|
||||
}
|
||||
|
||||
char* blockName = strtok(NULL, " ");
|
||||
bool all = false;
|
||||
if (blockName != NULL && (strcmp(blockName, "ALL") == 0)) {
|
||||
all = true;
|
||||
}
|
||||
while (blockName != NULL) {
|
||||
blocks.push_back(BaseString(blockName));
|
||||
blockName = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
if (blocks.size() == 0) {
|
||||
ndbout << "No block specified." << endl;
|
||||
free(newAllAfterLog);
|
||||
return false;
|
||||
}
|
||||
if (blocks.size() > 1 && all) {
|
||||
// More than "ALL" specified
|
||||
ndbout << "Nothing expected after ALL." << endl;
|
||||
free(newAllAfterLog);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(newAllAfterLog);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommandInterpreter::executeLogIn(int processId,
|
||||
const char* parameters, bool all) {
|
||||
|
||||
(void)all; // Don't want compiler warning
|
||||
|
||||
Vector<BaseString> blocks;
|
||||
if (! parseBlockSpecification(parameters, blocks)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::In, blocks);
|
||||
if (result != 0) {
|
||||
ndbout << get_error_text(result) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
//******************************************************************************
|
||||
void CommandInterpreter::executeLogOut(int processId,
|
||||
const char* parameters, bool all) {
|
||||
|
||||
(void)all; // Don't want compiler warning
|
||||
|
||||
Vector<BaseString> blocks;
|
||||
if (! parseBlockSpecification(parameters, blocks)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Out, blocks);
|
||||
if (result != 0) {
|
||||
ndbout << get_error_text(result) << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
//******************************************************************************
|
||||
void CommandInterpreter::executeLogOff(int processId,
|
||||
const char* parameters, bool all) {
|
||||
|
||||
(void)all; // Don't want compiler warning
|
||||
|
||||
Vector<BaseString> blocks;
|
||||
if (! parseBlockSpecification(parameters, blocks)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Off, blocks);
|
||||
if (result != 0) {
|
||||
ndbout << get_error_text(result) << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CommandInterpreter::executeTrace(int processId,
|
||||
const char* parameters, bool all) {
|
||||
|
||||
(void)all; // Don't want compiler warning
|
||||
|
||||
if (emptyString(parameters)) {
|
||||
ndbout << "Missing trace number." << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
char* newpar = strdup(parameters);
|
||||
char* firstParameter = strtok(newpar, " ");
|
||||
|
||||
|
||||
int traceNo;
|
||||
if (! convert(firstParameter, traceNo)) {
|
||||
ndbout << "Expected an integer." << endl;
|
||||
free(newpar);
|
||||
return;
|
||||
}
|
||||
|
||||
char* allAfterFirstParameter = strtok(NULL, "\0");
|
||||
|
||||
if (! emptyString(allAfterFirstParameter)) {
|
||||
ndbout << "Nothing expected after trace number." << endl;
|
||||
free(newpar);
|
||||
return;
|
||||
}
|
||||
|
||||
int result = _mgmtSrvr.setTraceNo(processId, traceNo);
|
||||
if (result != 0) {
|
||||
ndbout << get_error_text(result) << endl;
|
||||
}
|
||||
free(newpar);
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef CommandInterpreter_H
|
||||
#define CommandInterpreter_H
|
||||
|
||||
#include <ndb_global.h>
|
||||
#include <Vector.hpp>
|
||||
#include <BaseString.hpp>
|
||||
|
||||
class MgmtSrvr;
|
||||
|
||||
class CommandInterpreter {
|
||||
public:
|
||||
CommandInterpreter(MgmtSrvr& mgmtSrvr);
|
||||
int readAndExecute();
|
||||
|
||||
private:
|
||||
char m_err_str[1024];
|
||||
const char *get_error_text(int err_no);
|
||||
|
||||
char *readline_gets ()
|
||||
{
|
||||
static char linebuffer[254];
|
||||
static char *line_read = (char *)NULL;
|
||||
|
||||
/* If the buffer has already been allocated, return the memory
|
||||
to the free pool. */
|
||||
if (line_read)
|
||||
{
|
||||
free (line_read);
|
||||
line_read = (char *)NULL;
|
||||
}
|
||||
|
||||
/* Get a line from the user. */
|
||||
fputs("ndb_mgmd> ", stdout);
|
||||
linebuffer[sizeof(linebuffer)-1]=0;
|
||||
line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin);
|
||||
if (line_read == linebuffer) {
|
||||
char *q=linebuffer;
|
||||
while (*q > 31) q++;
|
||||
*q=0;
|
||||
line_read= strdup(linebuffer);
|
||||
}
|
||||
return (line_read);
|
||||
}
|
||||
|
||||
void analyseAfterFirstToken(int processId, char* allAfterFirstTokenCstr);
|
||||
bool parseBlockSpecification(const char* allAfterLog,
|
||||
Vector<BaseString>& blocks);
|
||||
|
||||
public:
|
||||
void executeTrace(int processId, const char* parameters, bool all);
|
||||
void executeLogIn(int processId, const char* parameters, bool all);
|
||||
void executeLogOut(int processId, const char* parameters, bool all);
|
||||
void executeLogOff(int processId, const char* parameters, bool all);
|
||||
|
||||
public:
|
||||
typedef void (CommandInterpreter::* ExecuteFunction)(int processId,
|
||||
const char * param,
|
||||
bool all);
|
||||
|
||||
struct CommandFunctionPair {
|
||||
const char * command;
|
||||
ExecuteFunction executeFunction;
|
||||
};
|
||||
private:
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void executeForAll(const char * cmd, ExecuteFunction fun, const char * param);
|
||||
|
||||
/**
|
||||
* Management server to use when executing commands
|
||||
*/
|
||||
MgmtSrvr& _mgmtSrvr;
|
||||
};
|
||||
|
||||
#endif // CommandInterpreter_H
|
|
@ -16,17 +16,20 @@ ndb_mgmd_SOURCES = \
|
|||
MgmtSrvrConfig.cpp \
|
||||
ConfigInfo.cpp \
|
||||
InitConfigFileParser.cpp \
|
||||
Config.cpp \
|
||||
CommandInterpreter.cpp
|
||||
Config.cpp
|
||||
|
||||
INCLUDES_LOC = -I$(top_srcdir)/ndb/src/ndbapi \
|
||||
-I$(top_srcdir)/ndb/src/mgmapi \
|
||||
-I$(top_srcdir)/ndb/src/common/mgmcommon
|
||||
-I$(top_srcdir)/ndb/src/common/mgmcommon \
|
||||
-I$(top_srcdir)/ndb/src/mgmclient
|
||||
|
||||
LDADD_LOC = $(top_builddir)/ndb/src/libndbclient.la \
|
||||
LDADD_LOC = $(top_srcdir)/ndb/src/mgmclient/CommandInterpreter.o \
|
||||
$(top_builddir)/ndb/src/libndbclient.la \
|
||||
$(top_builddir)/dbug/libdbug.a \
|
||||
$(top_builddir)/mysys/libmysys.a \
|
||||
$(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
|
||||
$(top_builddir)/strings/libmystrings.a \
|
||||
@readline_link@ \
|
||||
@NDB_SCI_LIBS@ \
|
||||
@TERMCAP_LIB@
|
||||
|
||||
DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#if defined NDB_OSE || defined NDB_SOFTOSE
|
||||
#include <efs.h>
|
||||
#else
|
||||
#include "CommandInterpreter.hpp"
|
||||
#include <ndb_mgmclient.hpp>
|
||||
#endif
|
||||
|
||||
#undef DEBUG
|
||||
|
@ -48,11 +48,54 @@
|
|||
|
||||
const char progname[] = "mgmtsrvr";
|
||||
|
||||
// copied from mysql.cc to get readline
|
||||
extern "C" {
|
||||
#if defined( __WIN__) || defined(OS2)
|
||||
#include <conio.h>
|
||||
#elif !defined(__NETWARE__)
|
||||
#include <readline/readline.h>
|
||||
extern "C" int add_history(const char *command); /* From readline directory */
|
||||
#define HAVE_READLINE
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
read_and_execute(Ndb_mgmclient* com, const char * prompt, int _try_reconnect)
|
||||
{
|
||||
static char *line_read = (char *)NULL;
|
||||
|
||||
/* If the buffer has already been allocated, return the memory
|
||||
to the free pool. */
|
||||
if (line_read)
|
||||
{
|
||||
free (line_read);
|
||||
line_read = (char *)NULL;
|
||||
}
|
||||
#ifdef HAVE_READLINE
|
||||
/* Get a line from the user. */
|
||||
line_read = readline (prompt);
|
||||
/* If the line has any text in it, save it on the history. */
|
||||
if (line_read && *line_read)
|
||||
add_history (line_read);
|
||||
#else
|
||||
static char linebuffer[254];
|
||||
fputs(prompt, stdout);
|
||||
linebuffer[sizeof(linebuffer)-1]=0;
|
||||
line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin);
|
||||
if (line_read == linebuffer) {
|
||||
char *q=linebuffer;
|
||||
while (*q > 31) q++;
|
||||
*q=0;
|
||||
line_read= strdup(linebuffer);
|
||||
}
|
||||
#endif
|
||||
return com->execute(line_read,_try_reconnect);
|
||||
}
|
||||
|
||||
/**
|
||||
* @struct MgmGlobals
|
||||
* @brief Global Variables used in the management server
|
||||
******************************************************************************/
|
||||
*****************************************************************************/
|
||||
struct MgmGlobals {
|
||||
MgmGlobals();
|
||||
~MgmGlobals();
|
||||
|
@ -297,14 +340,19 @@ int main(int argc, char** argv)
|
|||
|
||||
#if ! defined NDB_OSE && ! defined NDB_SOFTOSE
|
||||
if(glob.interactive) {
|
||||
CommandInterpreter com(* glob.mgmObject);
|
||||
while(com.readAndExecute());
|
||||
BaseString con_str;
|
||||
if(glob.interface_name)
|
||||
con_str.appfmt("host=%s:%d", glob.interface_name, glob.port);
|
||||
else
|
||||
con_str.appfmt("localhost:%d", glob.port);
|
||||
Ndb_mgmclient com(con_str.c_str(), 1);
|
||||
while(g_StopServer != true && read_and_execute(&com, "ndb_mgm> ", 1));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
while(g_StopServer != true)
|
||||
NdbSleep_MilliSleep(500);
|
||||
}
|
||||
{
|
||||
while(g_StopServer != true)
|
||||
NdbSleep_MilliSleep(500);
|
||||
}
|
||||
|
||||
g_eventLogger.info("Shutting down server...");
|
||||
glob.socketServer->stopServer();
|
||||
|
|
Loading…
Add table
Reference in a new issue