[Cluster-devel] [PATCH] cman-preconfig: allow host aliases as valid cluster nodenames

Fabio M. Di Nitto fdinitto at redhat.com
Wed Jun 27 09:48:18 UTC 2012


From: "Fabio M. Di Nitto" <fdinitto at redhat.com>

Resolves: rhbz#786118

Signed-off-by: Fabio M. Di Nitto <fdinitto at redhat.com>
---
 cman/daemon/cman-preconfig.c |   91 +++++++++++++++++++++++++++++++++++-------
 1 files changed, 76 insertions(+), 15 deletions(-)

diff --git a/cman/daemon/cman-preconfig.c b/cman/daemon/cman-preconfig.c
index d88ff3d..68fec22 100644
--- a/cman/daemon/cman-preconfig.c
+++ b/cman/daemon/cman-preconfig.c
@@ -451,7 +451,7 @@ static int verify_nodename(struct objdb_iface_ver0 *objdb, char *node)
 	struct sockaddr *sa;
 	hdb_handle_t nodes_handle;
 	hdb_handle_t find_handle = 0;
-	int error;
+	int found = 0;
 
 	/* nodename is either from commandline or from uname */
 	if (nodelist_byname(objdb, cluster_parent_handle, node))
@@ -497,12 +497,11 @@ static int verify_nodename(struct objdb_iface_ver0 *objdb, char *node)
 	}
 	objdb->object_find_destroy(find_handle);
 
-
-	/* The cluster.conf names may not be related to uname at all,
-	   they may match a hostname on some network interface.
-	   NOTE: This is IPv4 only */
-	error = getifaddrs(&ifa_list);
-	if (error)
+	/*
+	 * The cluster.conf names may not be related to uname at all,
+	 * they may match a hostname on some network interface.
+	 */
+	if (getifaddrs(&ifa_list))
 		return -1;
 
 	for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
@@ -521,12 +520,13 @@ static int verify_nodename(struct objdb_iface_ver0 *objdb, char *node)
 		if (sa->sa_family == AF_INET6)
 			salen = sizeof(struct sockaddr_in6);
 
-		error = getnameinfo(sa, salen, nodename2,
-				    sizeof(nodename2), NULL, 0, 0);
-		if (!error) {
+		if (getnameinfo(sa, salen,
+				nodename2, sizeof(nodename2), 
+				NULL, 0, 0) == 0) {
 
 			if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
 				strncpy(node, nodename2, sizeof(nodename) - 1);
+				found = 1;
 				goto out;
 			}
 
@@ -537,27 +537,88 @@ static int verify_nodename(struct objdb_iface_ver0 *objdb, char *node)
 
 				if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
 					strncpy(node, nodename2, sizeof(nodename) - 1);
+					found = 1;
 					goto out;
 				}
 			}
 		}
 
 		/* See if it's the IP address that's in cluster.conf */
-		error = getnameinfo(sa, sizeof(*sa), nodename2,
-				    sizeof(nodename2), NULL, 0, NI_NUMERICHOST);
-		if (error)
+		if (getnameinfo(sa, sizeof(*sa),
+				nodename2, sizeof(nodename2), 
+				NULL, 0, NI_NUMERICHOST))
 			continue;
 
 		if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
 			strncpy(node, nodename2, sizeof(nodename) - 1);
+			found = 1;
 			goto out;
 		}
 	}
 
-	error = -1;
  out:
+	if (found) {
+		freeifaddrs(ifa_list);
+		return 0;
+	}
+
+	/*
+	 * This section covers the usecase where the nodename specified in cluster.conf
+	 * is an alias specified in /etc/hosts. For example:
+	 * <ipaddr> hostname alias1 alias2
+	 * and <clusternode name="alias2">
+	 * the above calls use uname and getnameinfo does not return aliases.
+	 * here we take the name specified in cluster.conf, resolve it to an address
+	 * and then compare against all known local ip addresses.
+	 * if we have a match, we found our nodename. In theory this chunk of code
+	 * could replace all the checks above, but let's avoid any possible regressions
+	 * and use it as last.
+	 */
+
+	nodes_handle = nodeslist_init(objdb, cluster_parent_handle, &find_handle);
+	while (nodes_handle) {
+		char *dbnodename = NULL;
+		struct addrinfo hints;
+		struct addrinfo *result = NULL, *rp = NULL;
+
+		if (objdb_get_string(objdb, nodes_handle, "name", &dbnodename)) {
+			goto next;
+		}
+
+		memset(&hints, 0, sizeof(struct addrinfo));
+		hints.ai_family = AF_UNSPEC;
+		hints.ai_socktype = SOCK_DGRAM;
+		hints.ai_flags = 0;
+		hints.ai_protocol = IPPROTO_UDP;
+
+		if (getaddrinfo(dbnodename, NULL, &hints, &result))
+			goto next;
+
+		for (rp = result; rp != NULL; rp = rp->ai_next) {
+			for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
+				if (ipaddr_equal((struct sockaddr_storage *)rp->ai_addr,
+						 (struct sockaddr_storage *)ifa->ifa_addr)) {
+					freeaddrinfo(result);
+					strncpy(node, dbnodename, sizeof(nodename) - 1);
+					found = 1;
+					goto out2;
+				}
+			}
+		}
+
+		freeaddrinfo(result);
+ next:
+		nodes_handle = nodeslist_next(objdb, find_handle);
+	}
+ out2:
+	objdb->object_find_destroy(find_handle);
 	freeifaddrs(ifa_list);
-	return error;
+
+	if (found) {
+		return 0;
+	}
+
+	return -1;
 }
 
 /* Get any environment variable overrides */
-- 
1.7.7.6




More information about the Cluster-devel mailing list