Просмотр исходного кода

add corosync_cfg_get_node_addrs() call.


git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1726 fd59a12c-fef9-0310-b244-a6a79926bd2f
Christine Caulfield 17 лет назад
Родитель
Сommit
bcbc007ecd
5 измененных файлов с 208 добавлено и 4 удалено
  1. 26 0
      include/corosync/cfg.h
  2. 16 2
      include/corosync/ipc_cfg.h
  3. 76 0
      lib/cfg.c
  4. 44 0
      services/cfg.c
  5. 46 2
      tools/corosync-cfgtool.c

+ 26 - 0
include/corosync/cfg.h

@@ -124,6 +124,22 @@ typedef struct {
 		corosyncCfgShutdownCallback;
 } CorosyncCfgCallbacksT;
 
+/*
+ * A node address. This is a complete sockaddr_in[6]
+ * To explain:
+ *  If you cast cna_address to a 'struct sockaddr', the sa_family field
+ *  will be AF_INET or AF_INET6. Armed with that knowledge you can then
+ *  cast it to a sockaddr_in or sockaddr_in6 and pull out the address.
+ *  No other sockaddr fields are valid.
+ *  Also, you must ignore any part of the sockaddr beyond the length supplied
+ */
+typedef struct
+{
+	int  addressLength;
+	char address[sizeof(struct sockaddr_in6)];
+} CorosyncCfgNodeAddressT;
+
+
 /*
  * Interfaces
  */
@@ -212,6 +228,16 @@ cs_error_t
 corosync_cfg_state_track_stop (
         corosync_cfg_handle_t cfg_handle);
 
+
+cs_error_t
+corosync_cfg_get_node_addrs (
+	corosync_cfg_handle_t cfg_handle,
+	int nodeid,
+	int max_addrs,
+	int *num_addrs,
+	CorosyncCfgNodeAddressT *addrs);
+
+
 #ifdef __cplusplus
 }
 #endif

+ 16 - 2
include/corosync/ipc_cfg.h

@@ -50,7 +50,8 @@ enum req_lib_cfg_types {
         MESSAGE_REQ_CFG_SERVICEUNLOAD = 7,
 	MESSAGE_REQ_CFG_KILLNODE = 8,
 	MESSAGE_REQ_CFG_TRYSHUTDOWN = 9,
-	MESSAGE_REQ_CFG_REPLYTOSHUTDOWN = 10
+	MESSAGE_REQ_CFG_REPLYTOSHUTDOWN = 10,
+	MESSAGE_REQ_CFG_GET_NODE_ADDRS = 11
 };
 
 enum res_lib_cfg_types {
@@ -64,7 +65,8 @@ enum res_lib_cfg_types {
         MESSAGE_RES_CFG_SERVICEUNLOAD = 7,
 	MESSAGE_RES_CFG_KILLNODE = 8,
 	MESSAGE_RES_CFG_TRYSHUTDOWN = 9,
-	MESSAGE_RES_CFG_TESTSHUTDOWN = 10
+	MESSAGE_RES_CFG_TESTSHUTDOWN = 10,
+	MESSAGE_RES_CFG_GET_NODE_ADDRS = 11
 };
 
 struct req_lib_cfg_statetrack {
@@ -175,6 +177,18 @@ struct res_lib_cfg_testshutdown {
 	unsigned int flags;
 };
 
+struct req_lib_cfg_get_node_addrs {
+        mar_req_header_t header __attribute__((aligned(8)));
+	unsigned int nodeid;
+};
+
+struct res_lib_cfg_get_node_addrs {
+        mar_res_header_t header __attribute__((aligned(8)));
+	unsigned int family;
+	unsigned int num_addrs;
+	char addrs[TOTEMIP_ADDRLEN][0];
+};
+
 typedef enum {
 	AIS_AMF_ADMINISTRATIVETARGET_SERVICEUNIT = 0,
 	AIS_AMF_ADMINISTRATIVETARGET_SERVICEGROUP = 1,

+ 76 - 0
lib/cfg.c

@@ -40,6 +40,7 @@
 #include <errno.h>
 #include <signal.h>
 #include <pthread.h>
+#include <limits.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/select.h>
@@ -47,6 +48,7 @@
 
 #include <corosync/corotypes.h>
 #include <corosync/cfg.h>
+#include <corosync/totem/totemip.h>
 #include <corosync/mar_gen.h>
 #include <corosync/ipc_gen.h>
 #include <corosync/ipc_cfg.h>
@@ -794,3 +796,77 @@ corosync_cfg_replyto_shutdown (
 
 	return (error);
 }
+
+cs_error_t corosync_cfg_get_node_addrs (
+	corosync_cfg_handle_t cfg_handle,
+	int nodeid,
+	int max_addrs,
+	int *num_addrs,
+	CorosyncCfgNodeAddressT *addrs)
+{
+	cs_error_t error;
+	char buf[PIPE_BUF];
+	struct req_lib_cfg_get_node_addrs req_lib_cfg_get_node_addrs;
+	struct res_lib_cfg_get_node_addrs * res_lib_cfg_get_node_addrs = (struct res_lib_cfg_get_node_addrs *)buf;
+	struct cfg_instance *cfg_instance;
+	int addrlen;
+	int i;
+	struct iovec iov[2];
+
+	error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
+		(void *)&cfg_instance);
+	if (error != CS_OK) {
+		return (error);
+	}
+
+	pthread_mutex_lock (&cfg_instance->response_mutex);
+
+	req_lib_cfg_get_node_addrs.header.size = sizeof (req_lib_cfg_get_node_addrs);
+	req_lib_cfg_get_node_addrs.header.id = MESSAGE_REQ_CFG_GET_NODE_ADDRS;
+	req_lib_cfg_get_node_addrs.nodeid = nodeid;
+
+	iov[0].iov_base = (char *)&req_lib_cfg_get_node_addrs;
+	iov[0].iov_len = sizeof (req_lib_cfg_get_node_addrs);
+
+	error = saSendMsgReceiveReply (cfg_instance->response_fd, iov, 1,
+				       res_lib_cfg_get_node_addrs, sizeof (mar_res_header_t));
+
+	if (error == CS_OK && res_lib_cfg_get_node_addrs->header.size > sizeof(mar_res_header_t)) {
+		error = saRecvRetry (cfg_instance->response_fd, (char *)res_lib_cfg_get_node_addrs + sizeof (mar_res_header_t),
+				     res_lib_cfg_get_node_addrs->header.size - sizeof (mar_res_header_t));
+	}
+	pthread_mutex_unlock (&cfg_instance->response_mutex);
+
+	if (error != CS_OK) {
+		goto error_exit;
+	}
+
+	if (res_lib_cfg_get_node_addrs->family == AF_INET)
+		addrlen = sizeof(struct sockaddr_in);
+	if (res_lib_cfg_get_node_addrs->family == AF_INET6)
+		addrlen = sizeof(struct sockaddr_in6);
+
+	for (i=0; i<max_addrs && i<res_lib_cfg_get_node_addrs->num_addrs; i++) {
+		addrs[i].addressLength = addrlen;
+		struct sockaddr_in *in;
+		struct sockaddr_in6 *in6;
+
+		if (res_lib_cfg_get_node_addrs->family == AF_INET) {
+			in = (struct sockaddr_in *)addrs[i].address;
+			in->sin_family = AF_INET;
+			memcpy(&in->sin_addr, &res_lib_cfg_get_node_addrs->addrs[i][0], sizeof(struct in_addr));
+		}
+		if (res_lib_cfg_get_node_addrs->family == AF_INET6) {
+			in6 = (struct sockaddr_in6 *)addrs[i].address;
+			in6->sin6_family = AF_INET6;
+			memcpy(&in6->sin6_addr, &res_lib_cfg_get_node_addrs->addrs[i][0], sizeof(struct in6_addr));
+		}
+	}
+	*num_addrs = res_lib_cfg_get_node_addrs->num_addrs;
+	errno = error = res_lib_cfg_get_node_addrs->header.error;
+
+error_exit:
+
+	pthread_mutex_unlock (&cfg_instance->response_mutex);
+	return (error);
+}

+ 44 - 0
services/cfg.c

@@ -42,6 +42,7 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <limits.h>
 #include <errno.h>
 #include <signal.h>
 #include <string.h>
@@ -52,6 +53,7 @@
 #include <corosync/queue.h>
 #include <corosync/mar_gen.h>
 #include <corosync/ipc_gen.h>
+#include <corosync/totem/totemip.h>
 #include <corosync/ipc_cfg.h>
 #include <corosync/lcr/lcr_comp.h>
 #include <corosync/engine/logsys.h>
@@ -160,6 +162,10 @@ static void message_handler_req_lib_cfg_replytoshutdown (
 	void *conn,
 	void *msg);
 
+static void message_handler_req_lib_cfg_get_node_addrs (
+	void *conn,
+	void *msg);
+
 /*
  * Service Handler Definition
  */
@@ -230,6 +236,12 @@ static struct corosync_lib_handler cfg_lib_engine[] =
 		.response_size		= 0,
 		.response_id		= 0,
 		.flow_control		= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+	},
+	{ /* 11 */
+		.lib_handler_fn		= message_handler_req_lib_cfg_get_node_addrs,
+		.response_size		= sizeof (struct res_lib_cfg_get_node_addrs),
+		.response_id		= MESSAGE_RES_CFG_GET_NODE_ADDRS,
+		.flow_control		= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
 	}
 };
 
@@ -957,3 +969,35 @@ static void message_handler_req_lib_cfg_replytoshutdown (
 	check_shutdown_status();
 	LEAVE();
 }
+
+static void message_handler_req_lib_cfg_get_node_addrs (void *conn, void *msg)
+{
+	struct totem_ip_address node_ifs[INTERFACE_MAX];
+	char buf[PIPE_BUF];
+	char **status;
+	unsigned int num_interfaces = 0;
+	int ret = 0;
+	int i;
+	struct req_lib_cfg_get_node_addrs *req_lib_cfg_get_node_addrs = (struct req_lib_cfg_get_node_addrs *)msg;
+	struct res_lib_cfg_get_node_addrs *res_lib_cfg_get_node_addrs = (struct res_lib_cfg_get_node_addrs *)buf;
+
+	if (req_lib_cfg_get_node_addrs->nodeid == 0)
+		req_lib_cfg_get_node_addrs->nodeid = api->totem_nodeid_get();
+
+	api->totem_ifaces_get(req_lib_cfg_get_node_addrs->nodeid, node_ifs, &status, &num_interfaces);
+
+	res_lib_cfg_get_node_addrs->header.size = sizeof(struct res_lib_cfg_get_node_addrs) + (num_interfaces * TOTEMIP_ADDRLEN);
+	res_lib_cfg_get_node_addrs->header.id = MESSAGE_RES_CFG_GET_NODE_ADDRS;
+	res_lib_cfg_get_node_addrs->header.error = ret;
+	res_lib_cfg_get_node_addrs->num_addrs = num_interfaces;
+	if (num_interfaces) {
+		res_lib_cfg_get_node_addrs->family = node_ifs[0].family;
+		for (i = 0; i<num_interfaces; i++) {
+			memcpy(&res_lib_cfg_get_node_addrs->addrs[i][0], node_ifs[i].addr, TOTEMIP_ADDRLEN);
+		}
+	}
+	else {
+		res_lib_cfg_get_node_addrs->header.error = CS_ERR_NOT_EXIST;
+	}
+	api->ipc_conn_send_response(conn, res_lib_cfg_get_node_addrs, res_lib_cfg_get_node_addrs->header.size);
+}

+ 46 - 2
tools/corosync-cfgtool.c

@@ -47,6 +47,7 @@
 #include <arpa/inet.h>
 
 #include <corosync/corotypes.h>
+#include <corosync/totem/totem.h>
 #include <corosync/cfg.h>
 
 static void ringstatusget_do (void)
@@ -192,6 +193,45 @@ void shutdown_do()
 	(void)corosync_cfg_finalize (handle);
 }
 
+void showaddrs_do(int nodeid)
+{
+	cs_error_t result;
+	corosync_cfg_handle_t handle;
+	CorosyncCfgCallbacksT callbacks;
+	int numaddrs;
+	int i;
+	CorosyncCfgNodeAddressT addrs[INTERFACE_MAX];
+
+
+	result = corosync_cfg_initialize (&handle, &callbacks);
+	if (result != CS_OK) {
+		printf ("Could not initialize corosync configuration API error %d\n", result);
+		exit (1);
+	}
+
+	if (!corosync_cfg_get_node_addrs(handle, nodeid, INTERFACE_MAX, &numaddrs, addrs) == CS_OK) {
+		for (i=0; i<numaddrs; i++) {
+			char buf[INET6_ADDRSTRLEN];
+			struct sockaddr_storage *ss = (struct sockaddr_storage *)addrs[i].address;
+			struct sockaddr_in *sin = (struct sockaddr_in *)addrs[i].address;
+			struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addrs[i].address;
+			void *saddr;
+
+			if (ss->ss_family == AF_INET6)
+				saddr = &sin6->sin6_addr;
+			else
+				saddr = &sin->sin_addr;
+
+			inet_ntop(ss->ss_family, saddr, buf, sizeof(buf));
+			printf("%s", buf);
+		}
+		printf("\n");
+	}
+
+
+	(void)corosync_cfg_finalize (handle);
+}
+
 void killnode_do(unsigned int nodeid)
 {
 	cs_error_t result;
@@ -213,7 +253,7 @@ void killnode_do(unsigned int nodeid)
 
 void usage_do (void)
 {
-	printf ("corosync-cfgtool [-s] [-r] [-l] [-u] [service_name] [-v] [version] [-k] [nodeid]\n\n");
+	printf ("corosync-cfgtool [-s] [-r] [-l] [-u] [service_name] [-v] [version] [-k] [nodeid] [-a] [nodeid]\n\n");
 	printf ("A tool for displaying and configuring active parameters within corosync.\n");
 	printf ("options:\n");
 	printf ("\t-s\tDisplays the status of the current rings on this node.\n");
@@ -221,12 +261,13 @@ void usage_do (void)
 	printf ("\t\tre-enable redundant ring operation.\n");
 	printf ("\t-l\tLoad a service identified by name.\n");
 	printf ("\t-u\tUnload a service identified by name.\n");
+	printf ("\t-a\tDisplay the IP address(es) of a node\n");
 	printf ("\t-k\tKill a node identified by node id.\n");
 	printf ("\t-h\tShutdown corosync cleanly on this node.\n");
 }
 
 int main (int argc, char *argv[]) {
-	const char *options = "srl:u:v:k:h";
+	const char *options = "srl:u:v:k:a:h";
 	int opt;
 	int service_load = 0;
 	unsigned int nodeid;
@@ -260,6 +301,9 @@ int main (int argc, char *argv[]) {
 		case 'h':
 			shutdown_do();
 			break;
+		case 'a':
+			showaddrs_do( atoi(optarg) );
+			break;
 		case 'v':
 			version = atoi (optarg);
 			break;