From: "Fabio M. Di Nitto" <fdini...@redhat.com>

Resolves: rhbz#786118

Signed-off-by: Fabio M. Di Nitto <fdini...@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

Reply via email to