summaryrefslogtreecommitdiff
path: root/ndb/src/mgmapi
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/src/mgmapi')
-rw-r--r--ndb/src/mgmapi/Makefile_old2
-rw-r--r--ndb/src/mgmapi/mgmapi.cpp148
-rw-r--r--ndb/src/mgmapi/mgmapi_configuration.cpp157
-rw-r--r--ndb/src/mgmapi/mgmapi_configuration.hpp32
-rw-r--r--ndb/src/mgmapi/test/keso.c14
5 files changed, 328 insertions, 25 deletions
diff --git a/ndb/src/mgmapi/Makefile_old b/ndb/src/mgmapi/Makefile_old
index 9e7ba4f5ac7..fa734f998e6 100644
--- a/ndb/src/mgmapi/Makefile_old
+++ b/ndb/src/mgmapi/Makefile_old
@@ -15,7 +15,7 @@ LIB_TARGET := MGM_API
LIB_TARGET_ARCHIVES := $(ARCHIVE_TARGET) general portlib
# Source files of non-templated classes (.C files)
-SOURCES = mgmapi.cpp
+SOURCES = mgmapi.cpp mgmapi_configuration.cpp
CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \
-I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon)
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index fcdfe943fb1..72ba282ad13 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -19,6 +19,7 @@
#include <NdbTCP.h>
#include "mgmapi.h"
#include "mgmapi_debug.h"
+#include "mgmapi_configuration.hpp"
#include <socket_io.h>
#include <NdbOut.hpp>
@@ -26,6 +27,7 @@
#include <Parser.hpp>
#include <OutputStream.hpp>
#include <InputStream.hpp>
+#include <Base64.hpp>
#define MGM_CMD(name, fun, desc) \
@@ -93,15 +95,20 @@ struct ndb_mgm_handle {
#endif
};
-#define SET_ERROR(h, e, s) \
- { \
- char tmp[NDB_MGM_MAX_ERR_DESC_SIZE]; \
- snprintf(tmp, NDB_MGM_MAX_ERR_DESC_SIZE, " (mgmapi.cpp:%d)", __LINE__); \
- strncpy(h->last_error_desc, s, NDB_MGM_MAX_ERR_DESC_SIZE); \
- strncat(h->last_error_desc, tmp, NDB_MGM_MAX_ERR_DESC_SIZE); \
- h->last_error = e; \
- h->last_error_line = __LINE__; \
- }
+#define SET_ERROR(h, e, s) setError(h, e, __LINE__, s)
+
+static
+void
+setError(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);
+ vsnprintf(h->last_error_desc, sizeof(h->last_error_desc), msg, ap);
+ va_end(ap);
+}
#define CHECK_HANDLE(handle, ret) \
if(handle == 0) { \
@@ -185,9 +192,12 @@ ndb_mgm_get_latest_error(const NdbMgmHandle h)
return h->last_error;
}
-/**
- * Get latest error line associated with a handle
- */
+extern "C"
+const char *
+ndb_mgm_get_latest_error_desc(const NdbMgmHandle h){
+ return h->last_error_desc;
+}
+
extern "C"
int
ndb_mgm_get_latest_error_line(const NdbMgmHandle h)
@@ -207,13 +217,6 @@ ndb_mgm_get_latest_error_msg(const NdbMgmHandle h)
return "Error"; // Unknown Error message
}
-extern "C"
-const char *
-ndb_mgm_get_latest_error_desc(const NdbMgmHandle h)
-{
- return h->last_error_desc;
-}
-
static
int
parse_connect_string(const char * connect_string,
@@ -372,7 +375,8 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv)
// Convert ip address presentation format to numeric format
const int res1 = Ndb_getInAddr(&servaddr.sin_addr, handle->hostname);
if (res1 != 0) {
- SET_ERROR(handle, NDB_MGM_ILLEGAL_IP_ADDRESS, "");
+ DEBUG("Ndb_getInAddr(...) == -1");
+ setError(handle, EINVAL, __LINE__, "Invalid hostname/address");
return -1;
}
@@ -380,7 +384,8 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv)
sizeof(servaddr));
if (res2 == -1) {
NDB_CLOSE_SOCKET(sockfd);
- SET_ERROR(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, "");
+ setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, "Unable to connect to %s",
+ mgmsrv);
return -1;
}
@@ -389,7 +394,7 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv)
return 0;
}
-
+
/**
* Disconnect from a mgm server
*/
@@ -514,6 +519,8 @@ status_ackumulate(struct ndb_mgm_node_state * state,
state->node_group = atoi(value);
} else if(strcmp("version", field) == 0){
state->version = atoi(value);
+ } else if(strcmp("connect_count", field) == 0){
+ state->connect_count = atoi(value);
} else {
ndbout_c("Unknown field: %s", field);
}
@@ -1422,10 +1429,103 @@ ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId,
return 0;
}
+extern "C"
+struct ndb_mgm_configuration *
+ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
+
+ CHECK_HANDLE(handle, 0);
+ CHECK_CONNECTED(handle, 0);
+
+ Properties args;
+ args.put("version", version);
+
+ const ParserRow<ParserDummy> reply[] = {
+ MGM_CMD("get config reply", NULL, ""),
+ MGM_ARG("result", String, Mandatory, "Error message"),
+ MGM_ARG("Content-Length", Int, Optional, "Content length in bytes"),
+ MGM_ARG("Content-Type", String, Optional, "Type (octet-stream)"),
+ MGM_ARG("Content-Transfer-Encoding", String, Optional, "Encoding(base64)"),
+ MGM_END()
+ };
+
+ const Properties *prop;
+ prop = ndb_mgm_call(handle, reply, "get config", &args);
+
+ if(prop == NULL) {
+ SET_ERROR(handle, EIO, "Unable to fetch config");
+ return 0;
+ }
+
+ do {
+ const char * buf;
+ if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
+ ndbout_c("ERROR Message: %s\n", buf);
+ break;
+ }
+
+ buf = "<Unspecified>";
+ if(!prop->get("Content-Type", &buf) ||
+ strcmp(buf, "ndbconfig/octet-stream") != 0){
+ ndbout_c("Unhandled response type: %s", buf);
+ break;
+ }
+
+ buf = "<Unspecified>";
+ if(!prop->get("Content-Transfer-Encoding", &buf)
+ || strcmp(buf, "base64") != 0){
+ ndbout_c("Unhandled encoding: %s", buf);
+ break;
+ }
+
+ buf = "<Content-Length Unspecified>";
+ Uint32 len = 0;
+ if(!prop->get("Content-Length", &len)){
+ ndbout_c("Invalid response: %s\n", buf);
+ break;
+ }
+
+ len += 1; // Trailing \n
+
+ char* buf64 = new char[len];
+ int read = 0;
+ size_t start = 0;
+ do {
+ if((read = read_socket(handle->socket, handle->read_timeout,
+ &buf64[start], len-start)) == -1){
+ delete[] buf64;
+ buf64 = 0;
+ break;
+ }
+ start += read;
+ } while(start < len);
+ if(buf64 == 0)
+ break;
+
+ UtilBuffer tmp;
+ const int res = base64_decode(buf64, len-1, tmp);
+ delete[] buf64;
+ if(res != 0){
+ ndbout_c("Failed to decode buffer");
+ break;
+ }
+
+ ConfigValuesFactory cvf;
+ const int res2 = cvf.unpack(tmp);
+ if(!res2){
+ ndbout_c("Failed to unpack buffer");
+ break;
+ }
+
+ return (ndb_mgm_configuration*)cvf.m_cfg;
+ } while(0);
+
+ delete prop;
+ return 0;
+}
+
/*****************************************************************************
* Global Replication
- *****************************************************************************/
-
+ ******************************************************************************/
extern "C"
int
ndb_mgm_rep_command(NdbMgmHandle handle, unsigned int request,
diff --git a/ndb/src/mgmapi/mgmapi_configuration.cpp b/ndb/src/mgmapi/mgmapi_configuration.cpp
new file mode 100644
index 00000000000..ae7fe2c294c
--- /dev/null
+++ b/ndb/src/mgmapi/mgmapi_configuration.cpp
@@ -0,0 +1,157 @@
+#include <mgmapi.h>
+#include "mgmapi_configuration.hpp"
+#include <new>
+
+ndb_mgm_configuration_iterator::ndb_mgm_configuration_iterator
+(const ndb_mgm_configuration & conf, unsigned type_of_section)
+ : m_config(conf.m_config)
+{
+ m_sectionNo = ~0;
+ m_typeOfSection = type_of_section;
+ first();
+}
+
+ndb_mgm_configuration_iterator::~ndb_mgm_configuration_iterator(){
+ reset();
+}
+
+void
+ndb_mgm_configuration_iterator::reset(){
+ if(m_sectionNo != (Uint32)~0){
+ m_config.closeSection();
+ }
+}
+
+
+int
+ndb_mgm_configuration_iterator::enter(){
+ bool ok = m_config.openSection(m_typeOfSection, m_sectionNo);
+ if(ok){
+ return 0;
+ }
+
+ reset();
+ m_sectionNo = ~0;
+ return -1;
+}
+
+int
+ndb_mgm_configuration_iterator::first(){
+ reset();
+ m_sectionNo = 0;
+ return enter();
+}
+
+int
+ndb_mgm_configuration_iterator::next(){
+ reset();
+ m_sectionNo++;
+ return enter();
+}
+
+int
+ndb_mgm_configuration_iterator::valid() const {
+ return m_sectionNo != (Uint32)~0;
+}
+
+int
+ndb_mgm_configuration_iterator::find(int param, unsigned search){
+ unsigned val = search + 1;
+
+ while(get(param, &val) == 0 && val != search){
+ if(next() != 0)
+ break;
+ }
+
+ if(val == search)
+ return 0;
+
+ return -1;
+}
+
+int
+ndb_mgm_configuration_iterator::get(int param, unsigned * value) const {
+ return m_config.get(param, value) != true;
+
+}
+
+int
+ndb_mgm_configuration_iterator::get(int param,
+ unsigned long long * value) const{
+ return m_config.get(param, value) != true;
+}
+
+int
+ndb_mgm_configuration_iterator::get(int param, const char ** value) const {
+ return m_config.get(param, value) != true;
+}
+
+/**
+ * Published C interface
+ */
+extern "C"
+ndb_mgm_configuration_iterator*
+ndb_mgm_create_configuration_iterator(ndb_mgm_configuration * conf,
+ unsigned type_of_section){
+ ndb_mgm_configuration_iterator* iter = (ndb_mgm_configuration_iterator*)
+ malloc(sizeof(ndb_mgm_configuration_iterator));
+ if(iter == 0)
+ return 0;
+
+ return new(iter) ndb_mgm_configuration_iterator(* conf, type_of_section);
+}
+
+
+extern "C"
+void ndb_mgm_destroy_iterator(ndb_mgm_configuration_iterator* iter){
+ if(iter != 0){
+ iter->~ndb_mgm_configuration_iterator();
+ free(iter);
+ }
+}
+
+extern "C"
+int
+ndb_mgm_first(ndb_mgm_configuration_iterator* iter){
+ return iter->first();
+}
+
+extern "C"
+int
+ndb_mgm_next(ndb_mgm_configuration_iterator* iter){
+ return iter->next();
+}
+
+extern "C"
+int
+ndb_mgm_valid(const ndb_mgm_configuration_iterator* iter){
+ return iter->valid();
+}
+
+extern "C"
+int
+ndb_mgm_get_int_parameter(const ndb_mgm_configuration_iterator* iter,
+ int param, unsigned * value){
+ return iter->get(param, value);
+}
+
+extern "C"
+int
+ndb_mgm_get_int64_parameter(const ndb_mgm_configuration_iterator* iter,
+ int param, unsigned long long * value){
+ return iter->get(param, value);
+}
+
+extern "C"
+int
+ndb_mgm_get_string_parameter(const ndb_mgm_configuration_iterator* iter,
+ int param, const char ** value){
+ return iter->get(param, value);
+}
+
+extern "C"
+int
+ndb_mgm_find(ndb_mgm_configuration_iterator* iter,
+ int param, unsigned search){
+ return iter->find(param, search);
+}
diff --git a/ndb/src/mgmapi/mgmapi_configuration.hpp b/ndb/src/mgmapi/mgmapi_configuration.hpp
new file mode 100644
index 00000000000..c7feffd3a4e
--- /dev/null
+++ b/ndb/src/mgmapi/mgmapi_configuration.hpp
@@ -0,0 +1,32 @@
+#ifndef MGMAPI_CONFIGURATION_HPP
+#define MGMAPI_CONFIGURATION_HPP
+
+#include <ConfigValues.hpp>
+
+struct ndb_mgm_configuration {
+ ConfigValues m_config;
+};
+
+struct ndb_mgm_configuration_iterator {
+ Uint32 m_sectionNo;
+ Uint32 m_typeOfSection;
+ ConfigValues::ConstIterator m_config;
+
+ ndb_mgm_configuration_iterator(const ndb_mgm_configuration &, unsigned type);
+ ~ndb_mgm_configuration_iterator();
+
+ int first();
+ int next();
+ int valid() const;
+ int find(int param, unsigned value);
+
+ int get(int param, unsigned * value) const ;
+ int get(int param, unsigned long long * value) const ;
+ int get(int param, const char ** value) const ;
+
+ //
+ void reset();
+ int enter();
+};
+
+#endif
diff --git a/ndb/src/mgmapi/test/keso.c b/ndb/src/mgmapi/test/keso.c
index d5086b20b6a..d2675b2ca8a 100644
--- a/ndb/src/mgmapi/test/keso.c
+++ b/ndb/src/mgmapi/test/keso.c
@@ -29,6 +29,7 @@ static int testConnect(NdbMgmHandle h, struct ndb_mgm_reply* reply);
static int testDisconnect(NdbMgmHandle h, struct ndb_mgm_reply* reply);
static int testStatus(NdbMgmHandle h, struct ndb_mgm_reply* reply);
+static int testGetConfig(NdbMgmHandle h, struct ndb_mgm_reply* reply);
#ifdef VM_TRACE
static int testLogSignals(NdbMgmHandle h, struct ndb_mgm_reply* reply);
static int testStartSignalLog(NdbMgmHandle h, struct ndb_mgm_reply* reply);
@@ -152,6 +153,19 @@ int testDisconnect(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
}
static
+int testGetConfig(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
+ int i = 0;
+ struct ndb_mgm_configuration * config = ndb_mgm_get_configuration(h, 0);
+ if (config != NULL) {
+ free(config);
+ } else {
+ ndbout_c("Unable to get config");
+ return -1;
+ }
+ return 0;
+}
+
+static
int testStatus(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
int i = 0;
struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h);