Index: conf/hadoop-default.xml =================================================================== --- conf/hadoop-default.xml (revision 439206) +++ conf/hadoop-default.xml (working copy) @@ -38,6 +38,40 @@ creations/deletions), or "all". + + + + mapred.tasktracker.dns.interface + default + The name of the Network Interface from which a task tracker should + report its IP address. + + + + + mapred.tasktracker.dns.nameserver + default + The host name or IP address of the name server (DNS) which a TaskTracker should + use to determine the host name used by the JobTracker for communication and display purposes. + + + + + dfs.datanode.dns.interface + default + The name of the Network Interface from which a data node should + report its IP address. + + + + + dfs.datanode.dns.nameserver + default + The host name or IP address of the name server (DNS) which a DataNode should + use to determine the host name used by the NameNode for communication and display purposes. + + + Index: src/java/org/apache/hadoop/net/DNS.java =================================================================== --- src/java/org/apache/hadoop/net/DNS.java (revision 0) +++ src/java/org/apache/hadoop/net/DNS.java (revision 0) @@ -0,0 +1,187 @@ +package org.apache.hadoop.net; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.Enumeration; +import java.util.Vector; + +import javax.naming.NamingException; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; + +/** + * + * A class that provides direct and reverse lookup functionalities, allowing the + * querying of specific network interfaces or nameservers. + * + * @author Lorenzo Thione + * + */ +public class DNS { + + /** + * Returns the hostname associated with the specified IP address by the + * provided nameserver. + * + * @param hostIp + * The address to reverse lookup + * @param ns + * The host name of a reachable DNS server + * @return The host name associated with the provided IP + * @throws NamingException + * If a NamingException is encountered + */ + public static String reverseDns(InetAddress hostIp, String ns) + throws NamingException { + // + // Builds the reverse IP lookup form + // This is formed by reversing the IP numbers and appending in-addr.arpa + // + String[] parts = hostIp.getHostAddress().split("\\."); + String reverseIP = parts[3] + "." + parts[2] + "." + parts[1] + "." + + parts[0] + ".in-addr.arpa"; + + DirContext ictx = new InitialDirContext(); + Attributes attribute = ictx.getAttributes("dns://" + + ((ns == null) ? "" : ns) + // Use "dns:///" if the default + // nameserver is to be used + "/" + reverseIP, new String[] { "PTR" }); + ictx.close(); + + return attribute.get("PTR").get().toString(); + } + + /** + * Returns all the IPs associated with the provided interface, if any, in + * textual form. + * + * @param strInterface + * The name of the network interface to query (e.g. eth0) + * @return A string vector of all the IPs associated with the provided + * interface + * @throws UnknownHostException + * If an UnknownHostException is encountered in querying the + * default interface + * + */ + public static String[] getIPs(String strInterface) + throws UnknownHostException { + try { + NetworkInterface netIF = NetworkInterface.getByName(strInterface); + if (netIF == null) + return new String[] { InetAddress.getLocalHost() + .getHostAddress() }; + else { + Vector ips = new Vector(); + Enumeration e = netIF.getInetAddresses(); + while (e.hasMoreElements()) + ips.add(((InetAddress) e.nextElement()).getHostAddress()); + return (String[]) ips.toArray(new String[] {}); + } + } catch (SocketException e) { + return new String[] { InetAddress.getLocalHost().getHostAddress() }; + } + } + + /** + * Returns the first available IP address associated with the provided + * network interface + * + * @param strInterface + * The name of the network interface to query (e.g. eth0) + * @return The IP address in text form + * @throws UnknownHostException + * If one is encountered in querying the default interface + */ + public static String getDefaultIP(String strInterface) + throws UnknownHostException { + String[] ips = getIPs(strInterface); + return ips[0]; + } + + /** + * Returns all the host names associated by the provided nameserver with the + * address bound to the specified network interface + * + * @param strInterface + * The name of the network interface to query (e.g. eth0) + * @param nameserver + * The DNS host name + * @return A string vector of all host names associated with the IPs tied to + * the specified interface + * @throws UnknownHostException + */ + public static String[] getHosts(String strInterface, String nameserver) + throws UnknownHostException { + String[] ips = getIPs(strInterface); + Vector hosts = new Vector(); + for (int ctr = 0; ctr < ips.length; ctr++) + try { + hosts.add(reverseDns(InetAddress.getByName(ips[ctr]), + nameserver)); + } catch (Exception e) { + } + + if (hosts.size() == 0) + return new String[] { InetAddress.getLocalHost().getHostName() }; + else + return (String[]) hosts.toArray(new String[] {}); + } + + /** + * Returns all the host names associated by the default nameserver with the + * address bound to the specified network interface + * + * @param strInterface + * The name of the network interface to query (e.g. eth0) + * @return The list of host names associated with IPs bound to the network + * interface + * @throws UnknownHostException + * If one is encountered while querying the deault interface + * + */ + public static String[] getHosts(String strInterface) + throws UnknownHostException { + return getHosts(strInterface, null); + } + + /** + * Returns the default (first) host name associated by the provided + * nameserver with the address bound to the specified network interface + * + * @param strInterface + * The name of the network interface to query (e.g. eth0) + * @param nameserver + * The DNS host name + * @return The default host names associated with IPs bound to the network + * interface + * @throws UnknownHostException + * If one is encountered while querying the deault interface + */ + public static String getDefaultHost(String strInterface, String nameserver) + throws UnknownHostException { + String[] hosts = getHosts(strInterface, nameserver); + return hosts[0]; + } + + /** + * Returns the default (first) host name associated by the default + * nameserver with the address bound to the specified network interface + * + * @param strInterface + * The name of the network interface to query (e.g. eth0) + * @return The default host name associated with IPs bound to the network + * interface + * @throws UnknownHostException + * If one is encountered while querying the deault interface + */ + public static String getDefaultHost(String strInterface) + throws UnknownHostException { + return getDefaultHost(strInterface, null); + } + +} Index: src/java/org/apache/hadoop/net/package.html =================================================================== --- src/java/org/apache/hadoop/net/package.html (revision 0) +++ src/java/org/apache/hadoop/net/package.html (revision 0) @@ -0,0 +1,5 @@ + + +Network-related classes. + + Index: src/java/org/apache/hadoop/mapred/TaskTracker.java =================================================================== --- src/java/org/apache/hadoop/mapred/TaskTracker.java (revision 439206) +++ src/java/org/apache/hadoop/mapred/TaskTracker.java (working copy) @@ -31,6 +31,7 @@ import org.apache.hadoop.metrics.ContextFactory; import org.apache.hadoop.metrics.MetricsContext; import org.apache.hadoop.metrics.MetricsRecord; +import org.apache.hadoop.net.DNS; /******************************************************* * TaskTracker is a process that starts and tracks MR Tasks @@ -154,8 +155,19 @@ * close(). */ synchronized void initialize() throws IOException { - this.localHostname = InetAddress.getLocalHost().getHostName(); + // Gets the network interface and nameserver from the cluster configuration parameters + String nif = this.fConf.get("mapred.tasktracker.dns.interface", "default"); + String ns = this.fConf.get("mapred.tasktracker.dns.nameserver", "default"); + //If default, report localHost() name, otherwise user reverse lookup from DNS and nif + if (nif.equals("default")) + this.localHostname = InetAddress.getLocalHost().getHostName(); + else + this.localHostname = ns.equals("default") ? + DNS.getDefaultHost(nif) : + DNS.getDefaultHost(nif, ns); + + //check local disk checkLocalDirs(this.fConf.getLocalDirs()); fConf.deleteLocalFiles(SUBDIR); Index: src/java/org/apache/hadoop/dfs/DataNode.java =================================================================== --- src/java/org/apache/hadoop/dfs/DataNode.java (revision 439206) +++ src/java/org/apache/hadoop/dfs/DataNode.java (working copy) @@ -15,21 +15,21 @@ */ package org.apache.hadoop.dfs; +import java.io.*; +import java.net.*; +import java.util.*; + import org.apache.commons.logging.*; - import org.apache.hadoop.ipc.*; -import org.apache.hadoop.conf.*; +import org.apache.hadoop.util.*; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.mapred.StatusHttpServer; import org.apache.hadoop.metrics.Metrics; -import org.apache.hadoop.util.*; +import org.apache.hadoop.metrics.MetricsRecord; +import org.apache.hadoop.net.DNS; import org.apache.hadoop.util.DiskChecker.DiskErrorException; import org.apache.hadoop.util.DiskChecker.DiskOutOfSpaceException; -import org.apache.hadoop.mapred.StatusHttpServer; -import java.io.*; -import java.net.*; -import java.util.*; -import org.apache.hadoop.metrics.MetricsRecord; - /********************************************************** * DataNode is a class (and program) that stores a set of * blocks for a DFS deployment. A single deployment can @@ -179,6 +179,21 @@ File datadir, InetSocketAddress nameNodeAddr, Configuration conf ) throws IOException { + + // Machine name is set to getlocalHost().getHostName(), so leave it unchanged unless + // the conf files contain network cluster parameters for this + + // Gets the network interface and nameserver from the cluster configuration parameters + String nif = conf.get("dfs.datanode.dns.interface", "default"); + String ns = conf.get("dfs.datanode.dns.nameserver", "default"); + + + //If default, report localHost() name, otherwise user reverse lookup from DNS and nif + if (!nif.equals("default")) + machineName = ns.equals("default") ? + DNS.getDefaultHost(nif) : + DNS.getDefaultHost(nif, ns); + // get storage info and lock the data dir storage = new DataStorage( datadir ); // connect to name node