This function returns a pointer to a nodemap structure.
The returned structure must later be freed by calling ctdb_free_nodemap().
Move the definition of ctdb_sock_addr from ctdb_client.h to ctdb_protocol.h
Move the definition of the node flags, ctdb_node_and_flags and ctdb_node_map from ctdb_private.h to ctdb_protocol.h
Add both sync and async example for ctdb_getnodemap to the test application libctdb/tst.c
#include <stdarg.h>
#include <stdio.h>
#include <tdb.h>
+#include <netinet/in.h>
#include <ctdb_protocol.h>
/**
struct ctdb_request *req, uint32_t *pnn);
+/**
+ * ctdb_getnodemap_send - read the nodemap number from a node.
+ * @ctdb: the ctdb_connection from ctdb_connect.
+ * @destnode: the destination node (see below)
+ * @callback: the callback when ctdb replies to our message (typesafe)
+ * @cbdata: the argument to callback()
+ *
+ * There are several special values for destnode, detailed in
+ * ctdb_protocol.h, particularly CTDB_CURRENT_NODE which means the
+ * local ctdbd.
+ */
+struct ctdb_request *
+ctdb_getnodemap_send(struct ctdb_connection *ctdb,
+ uint32_t destnode,
+ ctdb_callback_t callback,
+ void *cbdata);
+/**
+ * ctdb_getnodemap_recv - read an ctdb_getnodemap reply from ctdbd
+ * @ctdb: the ctdb_connection from ctdb_connect.
+ * @req: the completed request.
+ * @nodemap: a pointer to the returned nodemap structure
+ *
+ * This returns false if something went wrong.
+ * If the command failed, it guarantees to set nodemap to NULL.
+ * A non-NULL value for nodemap means the command was successful.
+ *
+ * A non-NULL value of the nodemap must be release released/freed
+ * by ctdb_free_nodemap().
+ */
+bool ctdb_getnodemap_recv(struct ctdb_connection *ctdb,
+ struct ctdb_request *req, struct ctdb_node_map **nodemap);
+
/**
* ctdb_getrecmaster_send - read the recovery master of a node
* @ctdb: the ctdb_connection from ctdb_connect.
struct ctdb_request *
ctdb_getrecmaster_send(struct ctdb_connection *ctdb,
uint32_t destnode,
- ctdb_callback_t callback, void *cbdata);
+ ctdb_callback_t callback, void *cbdata);
/**
* ctdb_getrecmaster_recv - read an ctdb_getrecmaster reply from ctdbd
uint32_t destnode,
uint32_t *recmaster);
+
+/**
+ * ctdb_getnodemap - read the nodemap from a node (synchronous)
+ * @ctdb: the ctdb_connection from ctdb_connect.
+ * @destnode: the destination node (see below)
+ * @nodemap: a pointer to the nodemap to fill in
+ *
+ * There are several special values for destnode, detailed in
+ * ctdb_protocol.h, particularly CTDB_CURRENT_NODE which means the
+ * local ctdbd.
+ *
+ * Returns true and fills in *nodemap on success.
+ * A non-NULL nodemap must be freed by calling ctdb_free_nodemap.
+ */
+bool ctdb_getnodemap(struct ctdb_connection *ctdb,
+ uint32_t destnode, struct ctdb_node_map **nodemap);
+
+/*
+ * This function is used to release/free the nodemap structure returned
+ * by ctdb_getnodemap() and ctdb_getnodemap_recv()
+ */
+void ctdb_free_nodemap(struct ctdb_node_map *nodemap);
+
+
+
/* These ugly macro wrappers make the callbacks typesafe. */
#include <ctdb_typesafe_cb.h>
#define ctdb_sendcb(cb, cbdata) \
#define ctdb_getrecmaster_send(ctdb, destnode, cb, cbdata) \
ctdb_getrecmaster_send((ctdb), (destnode), \
ctdb_sendcb((cb), (cbdata)), (cbdata))
+
+#define ctdb_getnodemap_send(ctdb, destnode, cb, cbdata) \
+ ctdb_getnodemap_send((ctdb), (destnode), \
+ ctdb_sendcb((cb), (cbdata)), (cbdata))
+
#endif
struct timeval last_recovery_finished;
};
-/*
- definitions for different socket structures
- */
-typedef struct sockaddr_in ctdb_addr_in;
-typedef struct sockaddr_in6 ctdb_addr_in6;
-typedef union {
- struct sockaddr sa;
- ctdb_addr_in ip;
- ctdb_addr_in6 ip6;
-} ctdb_sock_addr;
-
/*
struct for tcp_client control
this is an ipv4 only version of this structure used by samba
const char *name; /* for debug messages */
void *private_data; /* private to transport */
uint32_t pnn;
-#define NODE_FLAGS_DISCONNECTED 0x00000001 /* node isn't connected */
-#define NODE_FLAGS_UNHEALTHY 0x00000002 /* monitoring says node is unhealthy */
-#define NODE_FLAGS_PERMANENTLY_DISABLED 0x00000004 /* administrator has disabled node */
-#define NODE_FLAGS_BANNED 0x00000008 /* recovery daemon has banned the node */
-#define NODE_FLAGS_DELETED 0x00000010 /* this node has been deleted */
-#define NODE_FLAGS_STOPPED 0x00000020 /* this node has been stopped */
-#define NODE_FLAGS_DISABLED (NODE_FLAGS_UNHEALTHY|NODE_FLAGS_PERMANENTLY_DISABLED)
-#define NODE_FLAGS_INACTIVE (NODE_FLAGS_DELETED|NODE_FLAGS_DISCONNECTED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)
uint32_t flags;
/* used by the dead node monitoring */
};
-/* table that contains a list of all nodes a ctdb knows about and their
- status
- */
-struct ctdb_node_and_flags {
- uint32_t pnn;
- uint32_t flags;
- ctdb_sock_addr addr;
-};
-
-struct ctdb_node_map {
- uint32_t num;
- struct ctdb_node_and_flags nodes[1];
-};
-
struct ctdb_node_and_flagsv4 {
uint32_t pnn;
uint32_t flags;
uint32_t laccessor;
uint32_t lacount;
};
+
+
+/*
+ definitions for different socket structures
+ */
+typedef struct sockaddr_in ctdb_addr_in;
+typedef struct sockaddr_in6 ctdb_addr_in6;
+typedef union {
+ struct sockaddr sa;
+ ctdb_addr_in ip;
+ ctdb_addr_in6 ip6;
+} ctdb_sock_addr;
+
+/*
+ A structure describing a single node, its flags and its address
+*/
+struct ctdb_node_and_flags {
+ uint32_t pnn;
+ uint32_t flags;
+ ctdb_sock_addr addr;
+};
+
+
+/*
+ Structure used for a nodemap.
+ The nodemap is the structure containing a list of all nodes
+ known to the cluster and their associated flags.
+*/
+struct ctdb_node_map {
+ uint32_t num;
+ struct ctdb_node_and_flags nodes[1];
+};
+
+/*
+ * Node flags
+ */
+#define NODE_FLAGS_DISCONNECTED 0x00000001 /* node isn't connected */
+#define NODE_FLAGS_UNHEALTHY 0x00000002 /* monitoring says node is unhealthy */
+#define NODE_FLAGS_PERMANENTLY_DISABLED 0x00000004 /* administrator has disabled node */
+#define NODE_FLAGS_BANNED 0x00000008 /* recovery daemon has banned the node */
+#define NODE_FLAGS_DELETED 0x00000010 /* this node has been deleted */
+#define NODE_FLAGS_STOPPED 0x00000020 /* this node has been stopped */
+#define NODE_FLAGS_DISABLED (NODE_FLAGS_UNHEALTHY|NODE_FLAGS_PERMANENTLY_DISABLED)
+#define NODE_FLAGS_INACTIVE (NODE_FLAGS_DELETED|NODE_FLAGS_DISCONNECTED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)
+
+
#endif
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include <string.h>
#include <ctdb.h>
#include <ctdb_protocol.h>
#include "libctdb_private.h"
/* Remove type-safety macros. */
#undef ctdb_getrecmaster_send
#undef ctdb_getpnn_send
+#undef ctdb_getnodemap_send
bool ctdb_getrecmaster_recv(struct ctdb_connection *ctdb,
struct ctdb_request *req, uint32_t *recmaster)
return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_PNN, destnode,
NULL, 0, callback, private_data);
}
+
+bool ctdb_getnodemap_recv(struct ctdb_connection *ctdb,
+ struct ctdb_request *req, struct ctdb_node_map **nodemap)
+{
+ struct ctdb_reply_control *reply;
+
+ *nodemap = NULL;
+ reply = unpack_reply_control(ctdb, req, CTDB_CONTROL_GET_NODEMAP);
+ if (!reply) {
+ return false;
+ }
+ if (reply->status == -1) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: status -1");
+ return false;
+ }
+ if (reply->datalen == 0) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: returned data is 0 bytes");
+ return false;
+ }
+
+ *nodemap = malloc(reply->datalen);
+ if (*nodemap == NULL) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: failed to malloc buffer");
+ return false;
+ }
+ memcpy(*nodemap, reply->data, reply->datalen);
+
+ return true;
+}
+struct ctdb_request *ctdb_getnodemap_send(struct ctdb_connection *ctdb,
+ uint32_t destnode,
+ ctdb_callback_t callback,
+ void *private_data)
+{
+ return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_NODEMAP,
+ destnode,
+ NULL, 0, callback, private_data);
+}
+
+void ctdb_free_nodemap(struct ctdb_node_map *nodemap)
+{
+ if (nodemap == NULL) {
+ return;
+ }
+ free(nodemap);
+}
#include <stdlib.h>
#include "io_elem.h"
#include <tdb.h>
+#include <netinet/in.h>
#include <ctdb_protocol.h> // For CTDB_DS_ALIGNMENT and ctdb_req_header
struct io_elem {
return ret;
}
+bool ctdb_getnodemap(struct ctdb_connection *ctdb,
+ uint32_t destnode, struct ctdb_node_map **nodemap)
+{
+ struct ctdb_request *req;
+ bool done = false;
+ bool ret = false;
+
+ *nodemap = NULL;
+
+ req = synchronous(ctdb,
+ ctdb_getnodemap_send(ctdb, destnode, set, &done),
+ &done);
+ if (req != NULL) {
+ ret = ctdb_getnodemap_recv(ctdb, req, nodemap);
+ ctdb_request_free(ctdb, req);
+ }
+ return ret;
+}
+
bool ctdb_set_message_handler(struct ctdb_connection *ctdb, uint64_t srvid,
ctdb_message_fn_t handler, void *cbdata)
{
#include <syslog.h>
#include <tdb.h>
#include <ctdb.h>
+#include <ctdb_protocol.h>
TDB_DATA key;
+
+void print_nodemap(struct ctdb_node_map *nodemap)
+{
+ int i;
+ char cip[128];
+
+ printf("number of nodes:%d\n", nodemap->num);
+ for (i=0;i<nodemap->num;i++) {
+ switch(nodemap->nodes[i].addr.sa.sa_family) {
+ case AF_INET:
+ inet_ntop(nodemap->nodes[i].addr.ip.sin_family, &nodemap->nodes[i].addr.ip.sin_addr, cip, sizeof(cip));
+ break;
+ case AF_INET6:
+ inet_ntop(nodemap->nodes[i].addr.ip6.sin6_family, &nodemap->nodes[i].addr.ip6.sin6_addr, cip, sizeof(cip));
+ break;
+ }
+
+ printf("Node:%d Address:%s Flags:%s%s%s%s%s%s\n",
+ nodemap->nodes[i].pnn,
+ cip,
+ nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED?"DISCONNECTED ":"",
+ nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY?"UNHEALTHY ":"",
+ nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED?"ADMIN DISABLED ":"",
+ nodemap->nodes[i].flags&NODE_FLAGS_BANNED?"BANNED ":"",
+ nodemap->nodes[i].flags&NODE_FLAGS_DELETED?"DELETED ":"",
+ nodemap->nodes[i].flags&NODE_FLAGS_STOPPED?"STOPPED ":"");
+ }
+}
+
void msg_h(struct ctdb_connection *ctdb, uint64_t srvid, TDB_DATA data, void *private_data)
{
printf("Message received on port %d : %s\n", (int)srvid, data.dptr);
}
+static void gnm_cb(struct ctdb_connection *ctdb,
+ struct ctdb_request *req, void *private)
+{
+ bool status;
+ struct ctdb_node_map *nodemap;
+
+ status = ctdb_getnodemap_recv(ctdb, req, &nodemap);
+ ctdb_request_free(ctdb, req);
+ if (!status) {
+ printf("Error reading NODEMAP\n");
+ return;
+ }
+ printf("ASYNC response to getnodemap:\n");
+ print_nodemap(nodemap);
+ ctdb_free_nodemap(nodemap);
+}
+
static void pnn_cb(struct ctdb_connection *ctdb,
struct ctdb_request *req, void *private)
{
printf("Error reading PNN\n");
return;
}
- printf("pnn:%d\n", pnn);
+ printf("ASYNC RESPONSE TO GETPNN: pnn:%d\n", pnn);
}
static void rm_cb(struct ctdb_connection *ctdb,
struct ctdb_connection *ctdb_connection;
struct ctdb_request *handle;
struct ctdb_db *ctdb_db_context;
+ struct ctdb_node_map *nodemap;
struct pollfd pfd;
uint32_t recmaster;
TDB_DATA msg;
if (!rrl_cb_called) {
printf("READRECORDLOCK is async\n");
}
+
+ /*
+ * Read the nodemap from a node (async)
+ */
+ handle = ctdb_getnodemap_send(ctdb_connection, CTDB_CURRENT_NODE,
+ gnm_cb, NULL);
+ if (handle == NULL) {
+ printf("Failed to send get_nodemap control\n");
+ exit(10);
+ }
+
+ /*
+ * Read the nodemap from a node (sync)
+ */
+ if (!ctdb_getnodemap(ctdb_connection, CTDB_CURRENT_NODE,
+ &nodemap)) {
+ printf("Failed to receive response to getrecmaster\n");
+ exit(10);
+ }
+ printf("SYNC response to getnodemap:\n");
+ print_nodemap(nodemap);
+ ctdb_free_nodemap(nodemap);
+
for (;;) {
pfd.events = ctdb_which_events(ctdb_connection);