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,7 +105,9 @@ 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
@ -113,7 +115,7 @@ public XceiverClientSpi acquireClient(Pipeline pipeline) throws IOException {
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 {
@ -123,12 +125,11 @@ public XceiverClientSpi acquireClient(Pipeline pipeline) throws IOException {
} }
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;
} }
} }
}
/** /**
* Releases an XceiverClient after use. * Releases an XceiverClient after use.
@ -141,10 +142,10 @@ public void releaseClient(XceiverClientSpi xceiverClient) {
XceiverClientWithAccessInfo info; XceiverClientWithAccessInfo info;
synchronized (openClient) { synchronized (openClient) {
info = openClient.getIfPresent(containerName); info = openClient.getIfPresent(containerName);
}
Preconditions.checkNotNull(info); Preconditions.checkNotNull(info);
info.decrementReference(); info.decrementReference();
} }
}
/** /**
* A helper class for caching and cleaning XceiverClient. Three parameters: * A helper class for caching and cleaning XceiverClient. Three parameters: