[SCM] CTDB repository - branch 1.2 updated - ctdb-1.0.114-331-gc8a985d

Ronnie Sahlberg sahlberg at samba.org
Tue Sep 14 22:56:37 MDT 2010


The branch, 1.2 has been updated
       via  c8a985d4a01aa146f25472d7d2937d73cafcfb0b (commit)
      from  478e3d29f2682f7f3ac684eaaa4aafd61da1358b (commit)

http://gitweb.samba.org/?p=sahlberg/ctdb.git;a=shortlog;h=1.2


- Log -----------------------------------------------------------------
commit c8a985d4a01aa146f25472d7d2937d73cafcfb0b
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Wed Sep 15 14:56:57 2010 +1000

    adda GETPUBLICIPS control to libctdb and use this in the test example
    
    enhance the test example to show the new releaseip/takeip messages

-----------------------------------------------------------------------

Summary of changes:
 include/ctdb.h          |   72 ++++++++++++++++++++++++++++++
 include/ctdb_private.h  |    8 ---
 include/ctdb_protocol.h |   16 +++++++
 libctdb/control.c       |   48 ++++++++++++++++++++
 libctdb/messages.c      |    2 +-
 libctdb/sync.c          |   19 ++++++++
 libctdb/tst.c           |  110 ++++++++++++++++++++++++++++++++++++++++-------
 7 files changed, 250 insertions(+), 25 deletions(-)


Changeset truncated at 500 lines:

diff --git a/include/ctdb.h b/include/ctdb.h
index 92f4626..1c6cf35 100644
--- a/include/ctdb.h
+++ b/include/ctdb.h
@@ -444,6 +444,43 @@ 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.
  * @destnode: the destination node (see below)
@@ -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
diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index b707afd..acf5a5e 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -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, 
diff --git a/include/ctdb_protocol.h b/include/ctdb_protocol.h
index a9f6249..f04b3f3 100644
--- a/include/ctdb_protocol.h
+++ b/include/ctdb_protocol.h
@@ -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
diff --git a/libctdb/control.c b/libctdb/control.c
index d193400..07185db 100644
--- a/libctdb/control.c
+++ b/libctdb/control.c
@@ -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);
+}
diff --git a/libctdb/messages.c b/libctdb/messages.c
index b79857c..d61d29e 100644
--- a/libctdb/messages.c
+++ b/libctdb/messages.c
@@ -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;
 }
diff --git a/libctdb/sync.c b/libctdb/sync.c
index d0aa86a..a1be3be 100644
--- a/libctdb/sync.c
+++ b/libctdb/sync.c
@@ -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)
 {
diff --git a/libctdb/tst.c b/libctdb/tst.c
index b423a48..e61561f 100644
--- a/libctdb/tst.c
+++ b/libctdb/tst.c
@@ -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);
 	}
@@ -277,6 +345,16 @@ int main(int argc, char *argv[])
 	}
 
 	/*
+	 * 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)
 	 */
 	if (!ctdb_getnodemap(ctdb_connection, CTDB_CURRENT_NODE,


-- 
CTDB repository


More information about the samba-cvs mailing list