diff options
-rw-r--r-- | ctdb/include/ctdb.h | 65 | ||||
-rw-r--r-- | ctdb/include/ctdb_client.h | 11 | ||||
-rw-r--r-- | ctdb/include/ctdb_private.h | 22 | ||||
-rw-r--r-- | ctdb/include/ctdb_protocol.h | 46 | ||||
-rw-r--r-- | ctdb/libctdb/control.c | 48 | ||||
-rw-r--r-- | ctdb/libctdb/io_elem.c | 1 | ||||
-rw-r--r-- | ctdb/libctdb/sync.c | 19 | ||||
-rw-r--r-- | ctdb/libctdb/tst.c | 73 |
8 files changed, 250 insertions, 35 deletions
diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h index 95376ce772..92f4626868 100644 --- a/ctdb/include/ctdb.h +++ b/ctdb/include/ctdb.h @@ -26,6 +26,7 @@ #include <stdarg.h> #include <stdio.h> #include <tdb.h> +#include <netinet/in.h> #include <ctdb_protocol.h> /** @@ -411,6 +412,38 @@ bool ctdb_getpnn_recv(struct ctdb_connection *ctdb, /** + * 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. * @destnode: the destination node (see below) @@ -424,7 +457,7 @@ bool ctdb_getpnn_recv(struct ctdb_connection *ctdb, 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 @@ -555,6 +588,31 @@ bool ctdb_getrecmaster(struct ctdb_connection *ctdb, 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) \ @@ -606,4 +664,9 @@ bool ctdb_getrecmaster(struct ctdb_connection *ctdb, #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 diff --git a/ctdb/include/ctdb_client.h b/ctdb/include/ctdb_client.h index 8fedfde831..16ed9c05f7 100644 --- a/ctdb/include/ctdb_client.h +++ b/ctdb/include/ctdb_client.h @@ -451,17 +451,6 @@ struct ctdb_uptime { }; /* - 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 samba will later be migrated over to use the diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 66558d471c..b707afda7b 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -205,14 +205,6 @@ struct ctdb_node { 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 */ @@ -879,20 +871,6 @@ struct ctdb_control_list_tunable { }; -/* 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; diff --git a/ctdb/include/ctdb_protocol.h b/ctdb/include/ctdb_protocol.h index df6e90c292..8c90675ede 100644 --- a/ctdb/include/ctdb_protocol.h +++ b/ctdb/include/ctdb_protocol.h @@ -452,4 +452,50 @@ struct ctdb_ltdb_header { 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 diff --git a/ctdb/libctdb/control.c b/ctdb/libctdb/control.c index d5f23f0fcd..d1934008d2 100644 --- a/ctdb/libctdb/control.c +++ b/ctdb/libctdb/control.c @@ -16,6 +16,7 @@ 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" @@ -23,6 +24,7 @@ /* 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) @@ -76,3 +78,49 @@ struct ctdb_request *ctdb_getpnn_send(struct ctdb_connection *ctdb, 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); +} diff --git a/ctdb/libctdb/io_elem.c b/ctdb/libctdb/io_elem.c index e00ddda056..bff21cb313 100644 --- a/ctdb/libctdb/io_elem.c +++ b/ctdb/libctdb/io_elem.c @@ -25,6 +25,7 @@ #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 { diff --git a/ctdb/libctdb/sync.c b/ctdb/libctdb/sync.c index 2ec96d8737..d0aa86ac18 100644 --- a/ctdb/libctdb/sync.c +++ b/ctdb/libctdb/sync.c @@ -119,6 +119,25 @@ bool ctdb_getpnn(struct ctdb_connection *ctdb, 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) { diff --git a/ctdb/libctdb/tst.c b/ctdb/libctdb/tst.c index 8bf5e63fae..b423a48ccf 100644 --- a/ctdb/libctdb/tst.c +++ b/ctdb/libctdb/tst.c @@ -36,14 +36,61 @@ #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) { @@ -56,7 +103,7 @@ static void pnn_cb(struct ctdb_connection *ctdb, 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, @@ -134,6 +181,7 @@ int main(int argc, char *argv[]) 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; @@ -217,6 +265,29 @@ int main(int argc, char *argv[]) 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); |