mgmapi.cpp
来自「MySQL源码文件5.X系列, 可自已编译到服务器」· C++ 代码 · 共 2,561 行 · 第 1/5 页
CPP
2,561 行
/* 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; version 2 of the License. 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 <ndb_global.h>#include <my_sys.h>#include <LocalConfig.hpp>#include <NdbAutoPtr.hpp>#include <NdbSleep.h>#include <NdbTCP.h>#include <mgmapi.h>#include <mgmapi_internal.h>#include <mgmapi_debug.h>#include "mgmapi_configuration.hpp"#include <socket_io.h>#include <version.h>#include <NdbOut.hpp>#include <SocketServer.hpp>#include <SocketClient.hpp>#include <Parser.hpp>#include <OutputStream.hpp>#include <InputStream.hpp>#include <base64.h>#define MGM_CMD(name, fun, desc) \ { name, \ 0, \ ParserRow<ParserDummy>::Cmd, \ ParserRow<ParserDummy>::String, \ ParserRow<ParserDummy>::Optional, \ ParserRow<ParserDummy>::IgnoreMinMax, \ 0, 0, \ fun, \ desc, 0 }#define MGM_ARG(name, type, opt, desc) \ { name, \ 0, \ ParserRow<ParserDummy>::Arg, \ ParserRow<ParserDummy>::type, \ ParserRow<ParserDummy>::opt, \ ParserRow<ParserDummy>::IgnoreMinMax, \ 0, 0, \ 0, \ desc, 0 }#define MGM_END() \ { 0, \ 0, \ ParserRow<ParserDummy>::Arg, \ ParserRow<ParserDummy>::Int, \ ParserRow<ParserDummy>::Optional, \ ParserRow<ParserDummy>::IgnoreMinMax, \ 0, 0, \ 0, \ 0, 0 }class ParserDummy : private SocketServer::Session {public: ParserDummy(NDB_SOCKET_TYPE sock);};ParserDummy::ParserDummy(NDB_SOCKET_TYPE sock) : SocketServer::Session(sock) {}typedef Parser<ParserDummy> Parser_t;#define NDB_MGM_MAX_ERR_DESC_SIZE 256struct ndb_mgm_handle { int cfg_i; int connected; int last_error; int last_error_line; char last_error_desc[NDB_MGM_MAX_ERR_DESC_SIZE]; int read_timeout; int write_timeout; unsigned int connect_timeout; NDB_SOCKET_TYPE socket; LocalConfig cfg;#ifdef MGMAPI_LOG FILE* logfile;#endif FILE *errstream; char *m_name; int mgmd_version_major; int mgmd_version_minor; int mgmd_version_build; char * m_bindaddress;};#define SET_ERROR(h, e, s) setError(h, e, __LINE__, s)staticvoidsetError(NdbMgmHandle h, int error, int error_line, const char * msg, ...){ h->last_error = error; \ h->last_error_line = error_line; va_list ap; va_start(ap, msg); BaseString::vsnprintf(h->last_error_desc, sizeof(h->last_error_desc), msg, ap); va_end(ap);}#define CHECK_HANDLE(handle, ret) \ if(handle == 0) { \ SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_HANDLE, ""); \ return ret; \ } #define CHECK_CONNECTED(handle, ret) \ if (handle->connected != 1) { \ SET_ERROR(handle, NDB_MGM_SERVER_NOT_CONNECTED , ""); \ return ret; \ }#define CHECK_REPLY(reply, ret) \ if(reply == NULL) { \ SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \ return ret; \ }/***************************************************************************** * Handles *****************************************************************************/extern "C"NdbMgmHandlendb_mgm_create_handle(){ DBUG_ENTER("ndb_mgm_create_handle"); NdbMgmHandle h = (NdbMgmHandle)my_malloc(sizeof(ndb_mgm_handle),MYF(MY_WME)); h->connected = 0; h->last_error = 0; h->last_error_line = 0; h->socket = NDB_INVALID_SOCKET; h->read_timeout = 50000; h->write_timeout = 100; h->connect_timeout = 0; h->cfg_i = -1; h->errstream = stdout; h->m_name = 0; h->m_bindaddress = 0; strncpy(h->last_error_desc, "No error", NDB_MGM_MAX_ERR_DESC_SIZE); new (&(h->cfg)) LocalConfig; h->cfg.init(0, 0);#ifdef MGMAPI_LOG h->logfile = 0;#endif h->mgmd_version_major= -1; h->mgmd_version_minor= -1; h->mgmd_version_build= -1; DBUG_PRINT("info", ("handle: 0x%lx", (long)h)); DBUG_RETURN(h);}extern "C"voidndb_mgm_set_name(NdbMgmHandle handle, const char *name){ my_free(handle->m_name, MYF(MY_ALLOW_ZERO_PTR)); handle->m_name= my_strdup(name, MYF(MY_WME));}extern "C"intndb_mgm_set_connectstring(NdbMgmHandle handle, const char * mgmsrv){ DBUG_ENTER("ndb_mgm_set_connectstring"); DBUG_PRINT("info", ("handle: 0x%lx", (long)handle)); handle->cfg.~LocalConfig(); new (&(handle->cfg)) LocalConfig; if (!handle->cfg.init(mgmsrv, 0) || handle->cfg.ids.size() == 0) { handle->cfg.~LocalConfig(); new (&(handle->cfg)) LocalConfig; handle->cfg.init(0, 0); /* reset the LocalConfig */ SET_ERROR(handle, NDB_MGM_ILLEGAL_CONNECT_STRING, ""); DBUG_RETURN(-1); } handle->cfg_i= -1; DBUG_RETURN(0);}extern "C"intndb_mgm_set_bindaddress(NdbMgmHandle handle, const char * arg){ DBUG_ENTER("ndb_mgm_set_bindaddress"); if (handle->m_bindaddress) free(handle->m_bindaddress); if (arg) handle->m_bindaddress = strdup(arg); else handle->m_bindaddress = 0; DBUG_RETURN(0);}/** * Destroy a handle */extern "C"voidndb_mgm_destroy_handle(NdbMgmHandle * handle){ DBUG_ENTER("ndb_mgm_destroy_handle"); if(!handle) DBUG_VOID_RETURN; DBUG_PRINT("info", ("handle: 0x%lx", (long)(* handle))); /** * important! only disconnect if connected * other code relies on this */ if((* handle)->connected){ ndb_mgm_disconnect(* handle); }#ifdef MGMAPI_LOG if ((* handle)->logfile != 0){ fclose((* handle)->logfile); (* handle)->logfile = 0; }#endif (*handle)->cfg.~LocalConfig(); my_free((*handle)->m_name, MYF(MY_ALLOW_ZERO_PTR)); if ((*handle)->m_bindaddress) free((*handle)->m_bindaddress); my_free((char*)* handle,MYF(MY_ALLOW_ZERO_PTR)); * handle = 0; DBUG_VOID_RETURN;}extern "C" voidndb_mgm_set_error_stream(NdbMgmHandle handle, FILE * file){ handle->errstream = file;}/***************************************************************************** * Error handling *****************************************************************************//** * Get latest error associated with a handle */extern "C"intndb_mgm_get_latest_error(const NdbMgmHandle h){ return h->last_error;}extern "C"const char *ndb_mgm_get_latest_error_desc(const NdbMgmHandle h){ return h->last_error_desc;}extern "C"intndb_mgm_get_latest_error_line(const NdbMgmHandle h){ return h->last_error_line;}extern "C"const char *ndb_mgm_get_latest_error_msg(const NdbMgmHandle h){ for (int i=0; i<ndb_mgm_noOfErrorMsgs; i++) { if (ndb_mgm_error_msgs[i].code == h->last_error) return ndb_mgm_error_msgs[i].msg; } return "Error"; // Unknown Error message}/* * Call an operation, and return the reply */static const Properties *ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply, const char *cmd, const Properties *cmd_args) { DBUG_ENTER("ndb_mgm_call"); DBUG_PRINT("enter",("handle->socket: %d, cmd: %s", handle->socket, cmd)); SocketOutputStream out(handle->socket); SocketInputStream in(handle->socket, handle->read_timeout); out.println(cmd);#ifdef MGMAPI_LOG /** * Print command to log file */ FileOutputStream f(handle->logfile); f.println("OUT: %s", cmd);#endif if(cmd_args != NULL) { Properties::Iterator iter(cmd_args); const char *name; while((name = iter.next()) != NULL) { PropertiesType t; Uint32 val_i; Uint64 val_64; BaseString val_s; cmd_args->getTypeOf(name, &t); switch(t) { case PropertiesType_Uint32: cmd_args->get(name, &val_i); out.println("%s: %d", name, val_i); break; case PropertiesType_Uint64: cmd_args->get(name, &val_64); out.println("%s: %Ld", name, val_64); break; case PropertiesType_char: cmd_args->get(name, val_s); out.println("%s: %s", name, val_s.c_str()); break; case PropertiesType_Properties: DBUG_PRINT("info",("Ignoring PropertiesType_Properties.")); /* Ignore */ break; default: DBUG_PRINT("info",("Ignoring PropertiesType: %d.",t)); } }#ifdef MGMAPI_LOG /** * Print arguments to log file */ cmd_args->print(handle->logfile, "OUT: ");#endif } out.println(""); Parser_t::Context ctx; ParserDummy session(handle->socket); Parser_t parser(command_reply, in, true, true, true); const Properties* p = parser.parse(ctx, session); if (p == NULL){ if(!ndb_mgm_is_connected(handle)) { DBUG_RETURN(NULL); } else { if(ctx.m_status==Parser_t::Eof || ctx.m_status==Parser_t::NoLine) { ndb_mgm_disconnect(handle); DBUG_RETURN(NULL); } /** * Print some info about why the parser returns NULL */ fprintf(handle->errstream, "Error in mgm protocol parser. cmd: >%s< status: %d curr: %s\n", cmd, (Uint32)ctx.m_status, (ctx.m_currentToken)?ctx.m_currentToken:"NULL"); DBUG_PRINT("info",("ctx.status: %d, ctx.m_currentToken: %s", ctx.m_status, ctx.m_currentToken)); } }#ifdef MGMAPI_LOG else { /** * Print reply to log file */ p->print(handle->logfile, "IN: "); }#endif DBUG_RETURN(p);}/** * Returns true if connected */extern "C"int ndb_mgm_is_connected(NdbMgmHandle handle){ if(!handle) return 0; if(handle->connected) { if(Ndb_check_socket_hup(handle->socket)) { handle->connected= 0; NDB_CLOSE_SOCKET(handle->socket); } } return handle->connected;}extern "C"int ndb_mgm_set_connect_timeout(NdbMgmHandle handle, unsigned int seconds){ if(!handle) return -1; handle->connect_timeout= seconds; return 0;}/** * Connect to a management server */extern "C"intndb_mgm_connect(NdbMgmHandle handle, int no_retries, int retry_delay_in_seconds, int verbose){ SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_connect"); CHECK_HANDLE(handle, -1); DBUG_ENTER("ndb_mgm_connect");#ifdef MGMAPI_LOG /** * Open the log file */ char logname[64]; BaseString::snprintf(logname, 64, "mgmapi.log"); handle->logfile = fopen(logname, "w");#endif char buf[1024]; /** * Do connect */ LocalConfig &cfg= handle->cfg; NDB_SOCKET_TYPE sockfd= NDB_INVALID_SOCKET; Uint32 i; int binderror = 0; SocketClient s(0, 0); s.set_connect_timeout(handle->connect_timeout); if (!s.init()) { fprintf(handle->errstream, "Unable to create socket, " "while trying to connect with connect string: %s\n", cfg.makeConnectString(buf,sizeof(buf))); setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, "Unable to create socket, " "while trying to connect with connect string: %s\n", cfg.makeConnectString(buf,sizeof(buf))); DBUG_RETURN(-1); } if (handle->m_bindaddress) { BaseString::snprintf(buf, sizeof(buf), handle->m_bindaddress); unsigned short portno = 0; char * port = strchr(buf, ':'); if (port != 0) { portno = atoi(port+1); * port = 0; } int err; if ((err = s.bind(buf, portno)) != 0) { fprintf(handle->errstream, "Unable to bind local address %s errno: %d, " "while trying to connect with connect string: %s\n", handle->m_bindaddress, err, cfg.makeConnectString(buf,sizeof(buf))); setError(handle, NDB_MGM_BIND_ADDRESS, __LINE__, "Unable to bind local address %s errno: %d, " "while trying to connect with connect string: %s\n", handle->m_bindaddress, err, cfg.makeConnectString(buf,sizeof(buf))); DBUG_RETURN(-1); } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?