commit 65b1fe60c04164d0c7c3ec9a846b401ab4e140d1 Author: Eric Yang Date: Fri Jul 27 20:31:54 2018 -0400 BUG-104171. Change DNS record lookup to a thread to prevent deadlock. diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/LookupTask.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/LookupTask.java new file mode 100644 index 0000000..ee13f1b --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/LookupTask.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.registry.server.dns; + +import org.xbill.DNS.Lookup; +import org.xbill.DNS.Name; +import org.xbill.DNS.Record; + +public class LookupTask implements Runnable{ + + private Name name; + private int type; + private Record[] records; + + public LookupTask(Name name, int type) { + this.name = name; + this.type = type; + } + + @Override + public void run() { + records = new Lookup(name, type).run(); + } + + public Record[] getResults() { + return records; + } +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java index 0022843..45ccdcb 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java @@ -88,6 +88,7 @@ import java.security.spec.RSAPrivateKeySpec; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Date; @@ -100,6 +101,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -941,7 +943,7 @@ public Boolean call() throws Exception { * @param port local port. * @throws IOException if the UDP processing fails. */ - private void serveNIOUDP(DatagramChannel channel, + private synchronized void serveNIOUDP(DatagramChannel channel, InetAddress addr, int port) throws Exception { SocketAddress remoteAddress = null; try { @@ -1132,7 +1134,7 @@ private byte remoteLookup(Message response, Name name, int type, } // Always add any CNAMEs to the response first - if (type != Type.CNAME) { + if (type != Type.CNAME && type != Type.PTR) { Record[] cnameAnswers = getRecords(name, Type.CNAME); if (cnameAnswers != null) { for (Record cnameR : cnameAnswers) { @@ -1178,7 +1180,16 @@ private byte remoteLookup(Message response, Name name, int type, */ protected Record[] getRecords(Name name, int type) { try { - return new Lookup(name, type).run(); + ExecutorService executor = Executors.newSingleThreadExecutor(); + LookupTask lookup = new LookupTask(name, type); + executor.submit(lookup); + try { + executor.awaitTermination(2, TimeUnit.SECONDS); + } catch (InterruptedException e) { + return null; + } + executor.shutdown(); + return lookup.getResults(); } catch (NullPointerException | ExceptionInInitializerError e) { LOG.error("Fail to lookup: " + name, e);