From mboxrd@z Thu Jan 1 00:00:00 1970 From: rmccabe@sourceware.org Date: 8 Oct 2007 20:29:01 -0000 Subject: [Cluster-devel] cluster/ccs/lib ccs.h libccs.c Message-ID: <20071008202901.30228.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Branch: RHEL5 Changes by: rmccabe at sourceware.org 2007-10-08 20:29:01 Modified files: ccs/lib : ccs.h libccs.c Log message: fix 323711 Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/ccs/lib/ccs.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.4&r2=1.4.2.1 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/ccs/lib/libccs.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.10&r2=1.10.2.1 --- cluster/ccs/lib/ccs.h 2005/01/13 16:19:08 1.4 +++ cluster/ccs/lib/ccs.h 2007/10/08 20:29:00 1.4.2.1 @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -20,5 +20,6 @@ int ccs_set(int desc, const char *path, char *val); int ccs_get_state(int desc, char **cw_path, char **prev_query); int ccs_set_state(int desc, const char *cw_path, int reset_query); +int ccs_lookup_nodename(int desc, const char *nodename, char **rtn); #endif /* __CCS_DOT_H__ */ --- cluster/ccs/lib/libccs.c 2006/01/11 16:00:55 1.10 +++ cluster/ccs/lib/libccs.c 2007/10/08 20:29:00 1.10.2.1 @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include "log.h" /* Libraries should not print - so only use log_dbg */ @@ -623,3 +625,175 @@ EXIT("ccs_set_state"); return error; } + +/** + * ccs_lookup_nodename + * @cd: ccs descriptor + * @nodename: node name string + * @retval: pointer to location to assign the result, if found + * + * This function takes any valid representation (FQDN, non-qualified + * hostname, IP address, IPv6 address) of a node's name and finds its + * canonical name (per cluster.conf). This function will find the primary + * node name if passed a node's "altname" or any valid representation + * of it. + * + * Returns: 0 on success, < 0 on failure + */ +int ccs_lookup_nodename(int cd, const char *nodename, char **retval) { + char path[256]; + char host_only[128]; + char *str; + char *p; + int error; + int ret; + unsigned int i; + size_t nodename_len; + struct addrinfo hints; + + if (nodename == NULL) + return (-1); + + nodename_len = strlen(nodename); + ret = snprintf(path, sizeof(path), + "/cluster/clusternodes/clusternode[@name=\"%s\"]/@name", nodename); + if (ret < 0 || (size_t) ret >= sizeof(path)) + return (-ENOSPC); + + str = NULL; + error = ccs_get(cd, path, &str); + if (!error) { + *retval = str; + return (0); + } + + if (nodename_len >= sizeof(host_only)) + return (-ENOSPC); + + /* Try just the hostname */ + strcpy(host_only, nodename); + p = strchr(host_only, '.'); + if (p != NULL) { + *p = '\0'; + + ret = snprintf(path, sizeof(path), + "/cluster/clusternodes/clusternode[@name=\"%s\"]/@name", + host_only); + if (ret < 0 || (size_t) ret >= sizeof(path)) + return (-ENOSPC); + + str = NULL; + error = ccs_get(cd, path, &str); + if (!error) { + *retval = str; + return (0); + } + } + + memset(&hints, 0, sizeof(hints)); + if (strchr(nodename, ':') != NULL) + hints.ai_family = AF_INET6; + else if (isdigit(nodename[nodename_len - 1])) + hints.ai_family = AF_INET; + else + hints.ai_family = AF_UNSPEC; + + /* + ** Try to match against each clusternode in cluster.conf. + */ + for (i = 1 ; ; i++) { + const char *pathstr = NULL; + char canonical_name[128]; + unsigned int altcnt; + + ret = snprintf(path, sizeof(path), + "/cluster/clusternodes/clusternode[%u]/@name", i); + if (ret < 0 || (size_t) ret >= sizeof(path)) + continue; + + for (altcnt = 0 ; ; altcnt++) { + size_t len; + struct addrinfo *ai = NULL; + char cur_node[128]; + + if (altcnt != 0) { + ret = snprintf(path, sizeof(path), pathstr, i, altcnt); + if (ret < 0 || (size_t) ret >= sizeof(path)) + continue; + } + + str = NULL; + error = ccs_get(cd, path, &str); + if (error || !str) { + if (altcnt == 0) + goto out_fail; + break; + } + + if (altcnt == 0) { + if (strlen(str) >= sizeof(canonical_name)) { + free(str); + return (-ENOSPC); + } + strcpy(canonical_name, str); + } + + if (strlen(str) >= sizeof(cur_node)) { + free(str); + return (-ENOSPC); + } + + strcpy(cur_node, str); + + p = strchr(cur_node, '.'); + if (p != NULL) + len = p - cur_node; + else + len = strlen(cur_node); + + if (strlen(host_only) == len && + !strncasecmp(host_only, cur_node, len)) + { + free(str); + *retval = strdup(canonical_name); + if (*retval == NULL) + return (-ENOMEM); + return (0); + } + + if (getaddrinfo(str, NULL, &hints, &ai) == 0) { + struct addrinfo *cur; + + for (cur = ai ; cur != NULL ; cur = cur->ai_next) { + char hostbuf[512]; + if (getnameinfo(cur->ai_addr, cur->ai_addrlen, + hostbuf, sizeof(hostbuf), + NULL, 0, + hints.ai_family != AF_UNSPEC ? NI_NUMERICHOST : 0)) + { + continue; + } + + if (!strcasecmp(hostbuf, nodename)) { + freeaddrinfo(ai); + free(str); + *retval = strdup(canonical_name); + if (*retval == NULL) + return (-ENOMEM); + return (0); + } + } + freeaddrinfo(ai); + } + + free(str); + + /* Try any altnames */ + pathstr = "/cluster/clusternodes/clusternode[%u]/altname[%u]/@name"; + } + } + +out_fail: + *retval = NULL; + return (-1); +}