⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgmapi.cpp

📁 mysql-5.0.22.tar.gz源码包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* 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 <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 <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;  NDB_SOCKET_TYPE socket;  LocalConfig cfg;#ifdef MGMAPI_LOG  FILE* logfile;#endif  FILE *errstream;  char *m_name;};#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->cfg_i           = -1;  h->errstream       = stdout;  h->m_name          = 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  DBUG_PRINT("info", ("handle=0x%x", (UintPtr)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%x", (UintPtr)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);}/** * 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%x", (UintPtr)(* 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));  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: %d\n",	      cmd, (Uint32)ctx.m_status, ctx.m_currentToken);      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;}/** * 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  /**   * Do connect   */  LocalConfig &cfg= handle->cfg;  NDB_SOCKET_TYPE sockfd= NDB_INVALID_SOCKET;  Uint32 i;  while (sockfd == NDB_INVALID_SOCKET)  {    // do all the mgmt servers    for (i = 0; i < cfg.ids.size(); i++)    {      if (cfg.ids[i].type != MgmId_TCP)	continue;      SocketClient s(cfg.ids[i].name.c_str(), cfg.ids[i].port);      sockfd = s.connect();      if (sockfd != NDB_INVALID_SOCKET)	break;    }    if (sockfd != NDB_INVALID_SOCKET)      break;#ifndef DBUG_OFF    {      char buf[1024];      DBUG_PRINT("info",("Unable to connect with connect string: %s",			 cfg.makeConnectString(buf,sizeof(buf))));    }#endif    if (verbose > 0) {      char buf[1024];      fprintf(handle->errstream, "Unable to connect with connect string: %s\n",	      cfg.makeConnectString(buf,sizeof(buf)));      verbose= -1;    }    if (no_retries == 0) {      char buf[1024];      setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,	       "Unable to connect with connect string: %s",	       cfg.makeConnectString(buf,sizeof(buf)));      if (verbose == -2)	fprintf(handle->errstream, ", failed.\n");      DBUG_RETURN(-1);    }    if (verbose == -1) {      fprintf(handle->errstream, "Retrying every %d seconds", 	      retry_delay_in_seconds);      if (no_retries > 0)	fprintf(handle->errstream, ". Attempts left:");      else	fprintf(handle->errstream, ", until connected.");      fflush(handle->errstream);      verbose= -2;    }    if (no_retries > 0) {      if (verbose == -2) {	fprintf(handle->errstream, " %d", no_retries);	fflush(handle->errstream);      }      no_retries--;    }    NdbSleep_SecSleep(retry_delay_in_seconds);  }  if (verbose == -2)  {    fprintf(handle->errstream, "\n");    fflush(handle->errstream);  }  handle->cfg_i = i;    handle->socket    = sockfd;  handle->connected = 1;  DBUG_RETURN(0);}/** * Disconnect from a mgm server */extern "C"intndb_mgm_disconnect(NdbMgmHandle handle){  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_disconnect");  CHECK_HANDLE(handle, -1);  CHECK_CONNECTED(handle, -1);  NDB_CLOSE_SOCKET(handle->socket);  handle->socket = NDB_INVALID_SOCKET;  handle->connected = 0;  return 0;}struct ndb_mgm_type_atoi {  const char * str;  const char * alias;  enum ndb_mgm_node_type value;};static struct ndb_mgm_type_atoi type_values[] = {  { "NDB", "ndbd", NDB_MGM_NODE_TYPE_NDB},  { "API", "mysqld", NDB_MGM_NODE_TYPE_API },  { "MGM", "ndb_mgmd", NDB_MGM_NODE_TYPE_MGM }};const int no_of_type_values = (sizeof(type_values) / 			       sizeof(ndb_mgm_type_atoi));extern "C"ndb_mgm_node_typendb_mgm_match_node_type(const char * type){  if(type == 0)    return NDB_MGM_NODE_TYPE_UNKNOWN;    for(int i = 0; i<no_of_type_values; i++)    if(strcmp(type, type_values[i].str) == 0)      return type_values[i].value;    else if(strcmp(type, type_values[i].alias) == 0)      return type_values[i].value;    return NDB_MGM_NODE_TYPE_UNKNOWN;}extern "C"const char * ndb_mgm_get_node_type_string(enum ndb_mgm_node_type type){  for(int i = 0; i<no_of_type_values; i++)    if(type_values[i].value == type)      return type_values[i].str;  return 0;}extern "C"const char * ndb_mgm_get_node_type_alias_string(enum ndb_mgm_node_type type, const char** str){  for(int i = 0; i<no_of_type_values; i++)    if(type_values[i].value == type)      {	if (str)	  *str= type_values[i].str;	return type_values[i].alias;      }  return 0;}struct ndb_mgm_status_atoi {  const char * str;  enum ndb_mgm_node_status value;};static struct ndb_mgm_status_atoi status_values[] = {  { "UNKNOWN", NDB_MGM_NODE_STATUS_UNKNOWN },  { "NO_CONTACT", NDB_MGM_NODE_STATUS_NO_CONTACT },  { "NOT_STARTED", NDB_MGM_NODE_STATUS_NOT_STARTED },  { "STARTING", NDB_MGM_NODE_STATUS_STARTING },  { "STARTED", NDB_MGM_NODE_STATUS_STARTED },  { "SHUTTING_DOWN", NDB_MGM_NODE_STATUS_SHUTTING_DOWN },  { "RESTARTING", NDB_MGM_NODE_STATUS_RESTARTING },  { "SINGLE USER MODE", NDB_MGM_NODE_STATUS_SINGLEUSER }};const int no_of_status_values = (sizeof(status_values) / 				 sizeof(ndb_mgm_status_atoi));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -