Browse Source

HDFS-11850. Ozone: Stack Overflow in XceiverClientManager because of race condition in accessing openClient. Contributed by Mukul Kumar Singh.

Chen Liang 8 years ago
parent
commit
b72ac9273e

+ 23 - 22
hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/scm/XceiverClientManager.java

@@ -105,28 +105,29 @@ public class XceiverClientManager {
     Preconditions.checkArgument(pipeline.getMachines() != null);
     Preconditions.checkArgument(!pipeline.getMachines().isEmpty());
     String containerName = pipeline.getContainerName();
-    XceiverClientWithAccessInfo info = openClient.getIfPresent(containerName);
-
-    if (info != null) {
-      // we do have this connection, add reference and return
-      info.incrementReference();
-      return info.getXceiverClient();
-    } else {
-      // connection not found, create new, add reference and return
-      final XceiverClientSpi xceiverClient = useRatis?
-          XceiverClientRatis.newXceiverClientRatis(pipeline, conf)
-          : new XceiverClient(pipeline, conf);
-      try {
-        xceiverClient.connect();
-      } catch (Exception e) {
-        throw new IOException("Exception connecting XceiverClient.", e);
-      }
-      info = new XceiverClientWithAccessInfo(xceiverClient);
-      info.incrementReference();
-      synchronized (openClient) {
+    synchronized(openClient) {
+      XceiverClientWithAccessInfo info =
+          openClient.getIfPresent(containerName);
+
+      if (info != null) {
+        // we do have this connection, add reference and return
+        info.incrementReference();
+        return info.getXceiverClient();
+      } else {
+        // connection not found, create new, add reference and return
+        final XceiverClientSpi xceiverClient = useRatis ?
+            XceiverClientRatis.newXceiverClientRatis(pipeline, conf)
+            : new XceiverClient(pipeline, conf);
+        try {
+          xceiverClient.connect();
+        } catch (Exception e) {
+          throw new IOException("Exception connecting XceiverClient.", e);
+        }
+        info = new XceiverClientWithAccessInfo(xceiverClient);
+        info.incrementReference();
         openClient.put(containerName, info);
+        return xceiverClient;
       }
-      return xceiverClient;
     }
   }
 
@@ -141,9 +142,9 @@ public class XceiverClientManager {
     XceiverClientWithAccessInfo info;
     synchronized (openClient) {
       info = openClient.getIfPresent(containerName);
+      Preconditions.checkNotNull(info);
+      info.decrementReference();
     }
-    Preconditions.checkNotNull(info);
-    info.decrementReference();
   }
 
   /**