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
1 changed files with 56 additions and 31 deletions

View File

@ -589,20 +589,21 @@ public class TestFsDatasetImpl {
// 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 class TestFsDatasetImpl {
} }
// 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 class TestFsDatasetImpl {
} }
} }
ResponderThread res = new ResponderThread(); class VolRemoveThread extends Thread {
res.start(); public void run() {
startFinalizeLatch.await(); try {
// Verify if block report can be received
// when volume is being removed
final BlockReportThread brt = new BlockReportThread();
brt.start();
Set<File> volumesToRemove = new HashSet<>(); Set<File> volumesToRemove = new HashSet<>();
volumesToRemove.add( volumesToRemove.add(StorageLocation.parse(
StorageLocation.parse(dataset.getVolume(eb).getBasePath()).getFile()); dataset.getVolume(eb).getBasePath()).getFile());
/** /**
* TODO: {@link FsDatasetImpl#removeVolumes(Set, boolean)} is throwing * TODO: {@link FsDatasetImpl#removeVolumes(Set, boolean)} is throwing
* IllegalMonitorStateException when there is a parallel reader/writer * IllegalMonitorStateException when there is a parallel reader/writer
* to the volume. Remove below try/catch block after fixing HDFS-10830. * to the volume. Remove below exception handling block after fixing
* HDFS-10830.
*/ */
try {
LOG.info("Removing volume " + volumesToRemove); LOG.info("Removing volume " + volumesToRemove);
dataset.removeVolumes(volumesToRemove, true); dataset.removeVolumes(volumesToRemove, true);
volRemoveCompletedLatch.countDown();
LOG.info("Removed volume " + volumesToRemove);
} catch (Exception e) { } catch (Exception e) {
LOG.info("Unexpected issue while removing volume: ", e); LOG.info("Unexpected issue while removing volume: ", e);
} finally { volRemoveCompletedLatch.countDown();
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();
} }
/** /**