[Cluster-devel] cluster/ccs/lib ccs.h libccs.c

rmccabe at sourceware.org rmccabe at sourceware.org
Mon Oct 8 16:43:21 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	rmccabe at sourceware.org	2007-10-08 16:43:21

Modified files:
	ccs/lib        : ccs.h libccs.c 

Log message:
	add new function to libccs:
	* 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.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/ccs/lib/ccs.h.diff?cvsroot=cluster&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/ccs/lib/libccs.c.diff?cvsroot=cluster&r1=1.10&r2=1.11

--- cluster/ccs/lib/ccs.h	2005/01/13 16:19:08	1.4
+++ cluster/ccs/lib/ccs.h	2007/10/08 16:43:21	1.5
@@ -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 16:43:21	1.11
@@ -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 <sys/un.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <netdb.h>
+#include <ctype.h>
 #include <errno.h>
 
 #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);
+}




More information about the Cluster-devel mailing list