mirror of
https://github.com/samba-team/samba.git
synced 2025-03-08 04:58:40 +03:00
adda GETPUBLICIPS control to libctdb and use this in the test example
enhance the test example to show the new releaseip/takeip messages (This used to be ctdb commit 21cc57883e6c02b0e037211b26d1d866d5d7f03d)
This commit is contained in:
parent
0b5bd411ca
commit
22ea35f17d
@ -443,6 +443,43 @@ ctdb_getnodemap_send(struct ctdb_connection *ctdb,
|
||||
bool ctdb_getnodemap_recv(struct ctdb_connection *ctdb,
|
||||
struct ctdb_request *req, struct ctdb_node_map **nodemap);
|
||||
|
||||
/**
|
||||
* ctdb_getpublicips_send - read the public ip list 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()
|
||||
*
|
||||
* This control returns the list of public ips known to the local node.
|
||||
* Deamons only know about those ips that are listed in the local
|
||||
* public addresses file, which means the returned list of ips may
|
||||
* be only a subset of all ips across the entire cluster.
|
||||
*
|
||||
* 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_getpublicips_send(struct ctdb_connection *ctdb,
|
||||
uint32_t destnode,
|
||||
ctdb_callback_t callback,
|
||||
void *cbdata);
|
||||
/**
|
||||
* ctdb_getpublicips_recv - read the public ip list from a node
|
||||
* @ctdb: the ctdb_connection from ctdb_connect.
|
||||
* @req: the completed request.
|
||||
* @ips: a pointer to the returned public ip list
|
||||
*
|
||||
* This returns false if something went wrong.
|
||||
* If the command failed, it guarantees to set ips 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_publicips().
|
||||
*/
|
||||
bool ctdb_getpublicips_recv(struct ctdb_connection *ctdb,
|
||||
struct ctdb_request *req, struct ctdb_all_public_ips **ips);
|
||||
|
||||
/**
|
||||
* ctdb_getrecmaster_send - read the recovery master of a node
|
||||
* @ctdb: the ctdb_connection from ctdb_connect.
|
||||
@ -612,6 +649,37 @@ bool ctdb_getnodemap(struct ctdb_connection *ctdb,
|
||||
void ctdb_free_nodemap(struct ctdb_node_map *nodemap);
|
||||
|
||||
|
||||
/**
|
||||
* ctdb_getpublicips - read the public ip list from a node.
|
||||
* @ctdb: the ctdb_connection from ctdb_connect.
|
||||
* @destnode: the destination node (see below)
|
||||
* @ips: a pointer to the returned public ip list
|
||||
*
|
||||
* This control returns the list of public ips known to the local node.
|
||||
* Deamons only know about those ips that are listed in the local
|
||||
* public addresses file, which means the returned list of ips may
|
||||
* be only a subset of all ips across the entire cluster.
|
||||
*
|
||||
* There are several special values for destnode, detailed in
|
||||
* ctdb_protocol.h, particularly CTDB_CURRENT_NODE which means the
|
||||
* local ctdbd.
|
||||
*
|
||||
* This returns false if something went wrong.
|
||||
* If the command failed, it guarantees to set ips 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_publicips().
|
||||
*/
|
||||
bool ctdb_getpublicips(struct ctdb_connection *ctdb,
|
||||
uint32_t destnode, struct ctdb_all_public_ips **ips);
|
||||
|
||||
/*
|
||||
* This function is used to release/free the public ip structure returned
|
||||
* by ctdb_getpublicips() and ctdb_getpublicips_recv()
|
||||
*/
|
||||
void ctdb_free_publicips(struct ctdb_all_public_ips *ips);
|
||||
|
||||
|
||||
/* These ugly macro wrappers make the callbacks typesafe. */
|
||||
#include <ctdb_typesafe_cb.h>
|
||||
@ -669,4 +737,8 @@ void ctdb_free_nodemap(struct ctdb_node_map *nodemap);
|
||||
ctdb_getnodemap_send((ctdb), (destnode), \
|
||||
ctdb_sendcb((cb), (cbdata)), (cbdata))
|
||||
|
||||
#define ctdb_getpublicips_send(ctdb, destnode, cb, cbdata) \
|
||||
ctdb_getpublicips_send((ctdb), (destnode), \
|
||||
ctdb_sendcb((cb), (cbdata)), (cbdata))
|
||||
|
||||
#endif
|
||||
|
@ -991,10 +991,6 @@ struct ctdb_public_ipv4 {
|
||||
struct sockaddr_in sin;
|
||||
};
|
||||
|
||||
struct ctdb_public_ip {
|
||||
uint32_t pnn;
|
||||
ctdb_sock_addr addr;
|
||||
};
|
||||
int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
|
||||
uint32_t destnode, struct ctdb_public_ip *ip);
|
||||
int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
|
||||
@ -1005,10 +1001,6 @@ struct ctdb_all_public_ipsv4 {
|
||||
struct ctdb_public_ipv4 ips[1];
|
||||
};
|
||||
|
||||
struct ctdb_all_public_ips {
|
||||
uint32_t num;
|
||||
struct ctdb_public_ip ips[1];
|
||||
};
|
||||
int32_t ctdb_control_get_public_ipsv4(struct ctdb_context *ctdb, struct ctdb_req_control *c, TDB_DATA *outdata);
|
||||
int32_t ctdb_control_get_public_ips(struct ctdb_context *ctdb, struct ctdb_req_control *c, TDB_DATA *outdata);
|
||||
int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
|
||||
|
@ -155,6 +155,12 @@ struct ctdb_call_info {
|
||||
*/
|
||||
#define CTDB_SRVID_ISCSID_RANGE 0xFE02000000000000LL
|
||||
|
||||
/* A range of ports reserved for testing (top 32 bits)
|
||||
* All ports matching the 32 top bits are reserved for exclusive use by
|
||||
* test applications
|
||||
*/
|
||||
#define CTDB_SRVID_TEST_RANGE 0xFE03000000000000LL
|
||||
|
||||
/* used on the domain socket, send a pdu to the local daemon */
|
||||
#define CTDB_CURRENT_NODE 0xF0000001
|
||||
/* send a broadcast to all nodes in the cluster, active or not */
|
||||
@ -518,4 +524,14 @@ struct ctdb_node_map {
|
||||
#define NODE_FLAGS_INACTIVE (NODE_FLAGS_DELETED|NODE_FLAGS_DISCONNECTED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)
|
||||
|
||||
|
||||
struct ctdb_public_ip {
|
||||
uint32_t pnn;
|
||||
ctdb_sock_addr addr;
|
||||
};
|
||||
|
||||
struct ctdb_all_public_ips {
|
||||
uint32_t num;
|
||||
struct ctdb_public_ip ips[1];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -25,6 +25,7 @@
|
||||
#undef ctdb_getrecmaster_send
|
||||
#undef ctdb_getpnn_send
|
||||
#undef ctdb_getnodemap_send
|
||||
#undef ctdb_getpublicips_send
|
||||
|
||||
bool ctdb_getrecmaster_recv(struct ctdb_connection *ctdb,
|
||||
struct ctdb_request *req, uint32_t *recmaster)
|
||||
@ -124,3 +125,50 @@ void ctdb_free_nodemap(struct ctdb_node_map *nodemap)
|
||||
}
|
||||
free(nodemap);
|
||||
}
|
||||
|
||||
bool ctdb_getpublicips_recv(struct ctdb_connection *ctdb,
|
||||
struct ctdb_request *req,
|
||||
struct ctdb_all_public_ips **ips)
|
||||
{
|
||||
struct ctdb_reply_control *reply;
|
||||
|
||||
*ips = NULL;
|
||||
reply = unpack_reply_control(ctdb, req, CTDB_CONTROL_GET_PUBLIC_IPS);
|
||||
if (!reply) {
|
||||
return false;
|
||||
}
|
||||
if (reply->status == -1) {
|
||||
DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: status -1");
|
||||
return false;
|
||||
}
|
||||
if (reply->datalen == 0) {
|
||||
DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: returned data is 0 bytes");
|
||||
return false;
|
||||
}
|
||||
|
||||
*ips = malloc(reply->datalen);
|
||||
if (*ips == NULL) {
|
||||
DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: failed to malloc buffer");
|
||||
return false;
|
||||
}
|
||||
memcpy(*ips, reply->data, reply->datalen);
|
||||
|
||||
return true;
|
||||
}
|
||||
struct ctdb_request *ctdb_getpublicips_send(struct ctdb_connection *ctdb,
|
||||
uint32_t destnode,
|
||||
ctdb_callback_t callback,
|
||||
void *private_data)
|
||||
{
|
||||
return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_PUBLIC_IPS,
|
||||
destnode,
|
||||
NULL, 0, callback, private_data);
|
||||
}
|
||||
|
||||
void ctdb_free_publicips(struct ctdb_all_public_ips *ips)
|
||||
{
|
||||
if (ips == NULL) {
|
||||
return;
|
||||
}
|
||||
free(ips);
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ ctdb_set_message_handler_send(struct ctdb_connection *ctdb, uint64_t srvid,
|
||||
info->handler_data = handler_data;
|
||||
|
||||
DEBUG(ctdb, LOG_DEBUG,
|
||||
"ctdb_set_message_handler_send: sending request %u for id %llu",
|
||||
"ctdb_set_message_handler_send: sending request %u for id %llx",
|
||||
req->hdr.hdr->reqid, srvid);
|
||||
return req;
|
||||
}
|
||||
|
@ -138,6 +138,25 @@ bool ctdb_getnodemap(struct ctdb_connection *ctdb,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ctdb_getpublicips(struct ctdb_connection *ctdb,
|
||||
uint32_t destnode, struct ctdb_all_public_ips **ips)
|
||||
{
|
||||
struct ctdb_request *req;
|
||||
bool done = false;
|
||||
bool ret = false;
|
||||
|
||||
*ips = NULL;
|
||||
|
||||
req = synchronous(ctdb,
|
||||
ctdb_getpublicips_send(ctdb, destnode, set, &done),
|
||||
&done);
|
||||
if (req != NULL) {
|
||||
ret = ctdb_getpublicips_recv(ctdb, req, ips);
|
||||
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)
|
||||
{
|
||||
|
@ -41,25 +41,33 @@
|
||||
TDB_DATA key;
|
||||
|
||||
|
||||
char *ctdb_addr_to_str(ctdb_sock_addr *addr)
|
||||
{
|
||||
static char cip[128] = "";
|
||||
|
||||
switch (addr->sa.sa_family) {
|
||||
case AF_INET:
|
||||
inet_ntop(addr->ip.sin_family, &addr->ip.sin_addr, cip, sizeof(cip));
|
||||
break;
|
||||
case AF_INET6:
|
||||
inet_ntop(addr->ip6.sin6_family, &addr->ip6.sin6_addr, cip, sizeof(cip));
|
||||
break;
|
||||
default:
|
||||
printf("ERROR, unknown family %u\n", addr->sa.sa_family);
|
||||
}
|
||||
|
||||
return cip;
|
||||
}
|
||||
|
||||
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,
|
||||
ctdb_addr_to_str(&nodemap->nodes[i].addr),
|
||||
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 ":"",
|
||||
@ -71,7 +79,17 @@ void print_nodemap(struct ctdb_node_map *nodemap)
|
||||
|
||||
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);
|
||||
printf("Message received on port %llx : %s\n", srvid, data.dptr);
|
||||
}
|
||||
|
||||
void rip_h(struct ctdb_connection *ctdb, uint64_t srvid, TDB_DATA data, void *private_data)
|
||||
{
|
||||
printf("RELEASE IP message for %s\n", data.dptr);
|
||||
}
|
||||
|
||||
void tip_h(struct ctdb_connection *ctdb, uint64_t srvid, TDB_DATA data, void *private_data)
|
||||
{
|
||||
printf("TAKE IP message for %s\n", data.dptr);
|
||||
}
|
||||
|
||||
static void gnm_cb(struct ctdb_connection *ctdb,
|
||||
@ -91,6 +109,35 @@ static void gnm_cb(struct ctdb_connection *ctdb,
|
||||
ctdb_free_nodemap(nodemap);
|
||||
}
|
||||
|
||||
void print_ips(struct ctdb_all_public_ips *ips)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Num public ips:%d\n", ips->num);
|
||||
for (i=0; i<ips->num;i++) {
|
||||
printf("%s hosted on node %d\n",
|
||||
ctdb_addr_to_str(&ips->ips[i].addr),
|
||||
ips->ips[i].pnn);
|
||||
}
|
||||
}
|
||||
|
||||
static void ips_cb(struct ctdb_connection *ctdb,
|
||||
struct ctdb_request *req, void *private)
|
||||
{
|
||||
bool status;
|
||||
struct ctdb_all_public_ips *ips;
|
||||
|
||||
status = ctdb_getpublicips_recv(ctdb, req, &ips);
|
||||
ctdb_request_free(ctdb, req);
|
||||
if (!status) {
|
||||
printf("Error reading PUBLIC IPS\n");
|
||||
return;
|
||||
}
|
||||
printf("ASYNC response to getpublicips:\n");
|
||||
print_ips(ips);
|
||||
ctdb_free_publicips(ips);
|
||||
}
|
||||
|
||||
static void pnn_cb(struct ctdb_connection *ctdb,
|
||||
struct ctdb_request *req, void *private)
|
||||
{
|
||||
@ -186,6 +233,7 @@ int main(int argc, char *argv[])
|
||||
uint32_t recmaster;
|
||||
TDB_DATA msg;
|
||||
bool rrl_cb_called = false;
|
||||
uint64_t srvid;
|
||||
|
||||
ctdb_log_level = LOG_DEBUG;
|
||||
ctdb_connection = ctdb_connect("/tmp/ctdb.socket",
|
||||
@ -195,23 +243,43 @@ int main(int argc, char *argv[])
|
||||
|
||||
pfd.fd = ctdb_get_fd(ctdb_connection);
|
||||
|
||||
handle = ctdb_set_message_handler_send(ctdb_connection, 55,
|
||||
srvid = CTDB_SRVID_TEST_RANGE|55;
|
||||
handle = ctdb_set_message_handler_send(ctdb_connection, srvid,
|
||||
msg_h, NULL,
|
||||
message_handler_cb, NULL);
|
||||
message_handler_cb, &srvid);
|
||||
if (handle == NULL) {
|
||||
printf("Failed to register message port\n");
|
||||
exit(10);
|
||||
}
|
||||
|
||||
/* Hack for testing: this makes sure registration goes out. */
|
||||
/* Hack for testing: this makes sure registrations went out. */
|
||||
while (!registered) {
|
||||
ctdb_service(ctdb_connection, POLLIN|POLLOUT);
|
||||
}
|
||||
|
||||
handle = ctdb_set_message_handler_send(ctdb_connection,
|
||||
CTDB_SRVID_RELEASE_IP,
|
||||
rip_h, NULL,
|
||||
message_handler_cb, NULL);
|
||||
if (handle == NULL) {
|
||||
printf("Failed to register message port for RELEASE IP\n");
|
||||
exit(10);
|
||||
}
|
||||
|
||||
handle = ctdb_set_message_handler_send(ctdb_connection,
|
||||
CTDB_SRVID_TAKE_IP,
|
||||
tip_h, NULL,
|
||||
message_handler_cb, NULL);
|
||||
if (handle == NULL) {
|
||||
printf("Failed to register message port for TAKE IP\n");
|
||||
exit(10);
|
||||
}
|
||||
|
||||
msg.dptr="HelloWorld";
|
||||
msg.dsize = strlen(msg.dptr);
|
||||
|
||||
if (!ctdb_send_message(ctdb_connection, 0, 55, msg)) {
|
||||
srvid = CTDB_SRVID_TEST_RANGE|55;
|
||||
if (!ctdb_send_message(ctdb_connection, 0, srvid, msg)) {
|
||||
printf("Failed to send message. Aborting\n");
|
||||
exit(10);
|
||||
}
|
||||
@ -276,6 +344,16 @@ int main(int argc, char *argv[])
|
||||
exit(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the list of public ips from a node (async)
|
||||
*/
|
||||
handle = ctdb_getpublicips_send(ctdb_connection, CTDB_CURRENT_NODE,
|
||||
ips_cb, NULL);
|
||||
if (handle == NULL) {
|
||||
printf("Failed to send getpublicips control\n");
|
||||
exit(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the nodemap from a node (sync)
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user