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

This commit is contained in:
Chen Liang 2017-05-22 10:20:04 -07:00 committed by Owen O'Malley
parent ae5242accb
commit a0f51ee3d7

View File

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