Addendum patch for HDFS-9781. FsDatasetImpl#getBlockReports can occasionally throw NullPointerException. Contributed by Manoj Govindassamy.

This commit is contained in:
Xiao Chen 2016-09-09 10:52:05 -07:00
parent d4d076876a
commit a0b0383677

View File

@ -589,20 +589,21 @@ public void testRemoveVolumeBeingWritten() throws Exception {
// Will write and remove on dn0. // Will write and remove on dn0.
final ExtendedBlock eb = new ExtendedBlock(BLOCK_POOL_IDS[0], 0); final ExtendedBlock eb = new ExtendedBlock(BLOCK_POOL_IDS[0], 0);
final CountDownLatch startFinalizeLatch = new CountDownLatch(1); final CountDownLatch startFinalizeLatch = new CountDownLatch(1);
final CountDownLatch brReceivedLatch = new CountDownLatch(1); final CountDownLatch blockReportReceivedLatch = new CountDownLatch(1);
final CountDownLatch volRemovedLatch = new CountDownLatch(1); final CountDownLatch volRemoveStartedLatch = new CountDownLatch(1);
final CountDownLatch volRemoveCompletedLatch = new CountDownLatch(1);
class BlockReportThread extends Thread { class BlockReportThread extends Thread {
public void run() { public void run() {
// Lets wait for the volume remove process to start // Lets wait for the volume remove process to start
try { try {
volRemovedLatch.await(); volRemoveStartedLatch.await();
} catch (Exception e) { } catch (Exception e) {
LOG.info("Unexpected exception when waiting for vol removal:", e); LOG.info("Unexpected exception when waiting for vol removal:", e);
} }
LOG.info("Getting block report"); LOG.info("Getting block report");
dataset.getBlockReports(eb.getBlockPoolId()); dataset.getBlockReports(eb.getBlockPoolId());
LOG.info("Successfully received block report"); LOG.info("Successfully received block report");
brReceivedLatch.countDown(); blockReportReceivedLatch.countDown();
} }
} }
@ -623,7 +624,7 @@ public void run() {
} }
// Lets wait for the other thread finish getting block report // Lets wait for the other thread finish getting block report
brReceivedLatch.await(); blockReportReceivedLatch.await();
dataset.finalizeBlock(eb); dataset.finalizeBlock(eb);
LOG.info("FinalizeBlock finished"); LOG.info("FinalizeBlock finished");
@ -633,34 +634,58 @@ public void run() {
} }
} }
ResponderThread res = new ResponderThread(); class VolRemoveThread extends Thread {
res.start(); public void run() {
startFinalizeLatch.await(); try {
Set<File> volumesToRemove = new HashSet<>();
// Verify if block report can be received volumesToRemove.add(StorageLocation.parse(
// when volume is being removed dataset.getVolume(eb).getBasePath()).getFile());
final BlockReportThread brt = new BlockReportThread(); /**
brt.start(); * TODO: {@link FsDatasetImpl#removeVolumes(Set, boolean)} is throwing
* IllegalMonitorStateException when there is a parallel reader/writer
Set<File> volumesToRemove = new HashSet<>(); * to the volume. Remove below exception handling block after fixing
volumesToRemove.add( * HDFS-10830.
StorageLocation.parse(dataset.getVolume(eb).getBasePath()).getFile()); */
/** LOG.info("Removing volume " + volumesToRemove);
* TODO: {@link FsDatasetImpl#removeVolumes(Set, boolean)} is throwing dataset.removeVolumes(volumesToRemove, true);
* IllegalMonitorStateException when there is a parallel reader/writer volRemoveCompletedLatch.countDown();
* to the volume. Remove below try/catch block after fixing HDFS-10830. LOG.info("Removed volume " + volumesToRemove);
*/ } catch (Exception e) {
try { LOG.info("Unexpected issue while removing volume: ", e);
LOG.info("Removing volume " + volumesToRemove); volRemoveCompletedLatch.countDown();
dataset.removeVolumes(volumesToRemove, true); }
} catch (Exception e) { }
LOG.info("Unexpected issue while removing volume: ", e);
} finally {
volRemovedLatch.countDown();
} }
LOG.info("Volumes removed"); // Start the volume write operation
brReceivedLatch.await(); ResponderThread responderThread = new ResponderThread();
responderThread.start();
startFinalizeLatch.await();
// Start the block report get operation
final BlockReportThread blockReportThread = new BlockReportThread();
blockReportThread.start();
// Start the volume remove operation
VolRemoveThread volRemoveThread = new VolRemoveThread();
volRemoveThread.start();
// Let volume write and remove operation be
// blocked for few seconds
Thread.sleep(2000);
// Signal block report receiver and volume writer
// thread to complete their operations so that vol
// remove can proceed
volRemoveStartedLatch.countDown();
// Verify if block report can be received
// when volume is in use and also being removed
blockReportReceivedLatch.await();
// Verify if volume can be removed safely when there
// are read/write operation in-progress
volRemoveCompletedLatch.await();
} }
/** /**