From bcbc007ecdeda83ff9da5c35e79606bd42cc59c0 Mon Sep 17 00:00:00 2001 From: Christine Caulfield Date: Wed, 14 Jan 2009 09:27:40 +0000 Subject: [PATCH] add corosync_cfg_get_node_addrs() call. git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1726 fd59a12c-fef9-0310-b244-a6a79926bd2f --- include/corosync/cfg.h | 26 +++++++++++++ include/corosync/ipc_cfg.h | 18 ++++++++- lib/cfg.c | 76 ++++++++++++++++++++++++++++++++++++++ services/cfg.c | 44 ++++++++++++++++++++++ tools/corosync-cfgtool.c | 48 +++++++++++++++++++++++- 5 files changed, 208 insertions(+), 4 deletions(-) diff --git a/include/corosync/cfg.h b/include/corosync/cfg.h index 90a37b45..e8b56fdf 100644 --- a/include/corosync/cfg.h +++ b/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 diff --git a/include/corosync/ipc_cfg.h b/include/corosync/ipc_cfg.h index bacb2af0..09d4bccd 100644 --- a/include/corosync/ipc_cfg.h +++ b/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, diff --git a/lib/cfg.c b/lib/cfg.c index b3d84dc5..f962a74b 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #include #include +#include #include #include #include @@ -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; inum_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); +} diff --git a/services/cfg.c b/services/cfg.c index 1239d239..dc3c8ba0 100644 --- a/services/cfg.c +++ b/services/cfg.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -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; iaddrs[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); +} diff --git a/tools/corosync-cfgtool.c b/tools/corosync-cfgtool.c index 8f8ff71f..8b2bb9d8 100644 --- a/tools/corosync-cfgtool.c +++ b/tools/corosync-cfgtool.c @@ -47,6 +47,7 @@ #include #include +#include #include 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; iss_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;