From 54b88943ff6092e9895bb1afcb08e33f42c126cd Mon Sep 17 00:00:00 2001 From: Colin Patrick Mccabe Date: Fri, 3 Apr 2015 16:34:23 -0700 Subject: [PATCH] HDFS-8051. FsVolumeList#addVolume should release volume reference if not put it into BlockScanner. (Lei (Eddy) Xu via Colin P. McCabe) (cherry picked from commit ef591b1d6a08f08358b19763a874de6010227307) (cherry picked from commit b26ba22a9023ac2ae058abf509db67aa8ef64b41) --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 +++ .../datanode/fsdataset/impl/FsVolumeList.java | 5 +++++ .../fsdataset/impl/TestFsVolumeList.java | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 9481261b99e..9955c71cea6 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -962,6 +962,9 @@ Release 2.7.0 - UNRELEASED HDFS-7996. After swapping a volume, BlockReceiver reports ReplicaNotFoundException (Lei (Eddy) Xu via Colin P. McCabe) + HDFS-8051. FsVolumeList#addVolume should release volume reference if not + put it into BlockScanner. (Lei (Eddy) Xu via Colin P. McCabe) + BREAKDOWN OF HDFS-7584 SUBTASKS AND RELATED JIRAS HDFS-7720. Quota by Storage Type API, tools and ClientNameNode diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsVolumeList.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsVolumeList.java index a5611c5b191..dda3d93aabd 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsVolumeList.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsVolumeList.java @@ -39,6 +39,7 @@ import org.apache.hadoop.hdfs.server.datanode.fsdataset.FsVolumeReference; import org.apache.hadoop.hdfs.server.datanode.fsdataset.FsVolumeSpi; import org.apache.hadoop.hdfs.server.datanode.fsdataset.VolumeChoosingPolicy; import org.apache.hadoop.hdfs.server.datanode.BlockScanner; +import org.apache.hadoop.hdfs.server.protocol.DatanodeStorage; import org.apache.hadoop.util.DiskChecker.DiskErrorException; import org.apache.hadoop.util.Time; @@ -290,6 +291,10 @@ class FsVolumeList { } if (blockScanner != null) { blockScanner.addVolumeScanner(ref); + } else { + // If the volume is not put into a volume scanner, it does not need to + // hold the reference. + IOUtils.cleanup(FsDatasetImpl.LOG, ref); } // If the volume is used to replace a failed volume, it needs to reset the // volume failure info for this volume. diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/TestFsVolumeList.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/TestFsVolumeList.java index 46189ba6dfc..eccff896bfc 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/TestFsVolumeList.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/TestFsVolumeList.java @@ -35,6 +35,7 @@ import java.util.Collections; import java.util.List; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; public class TestFsVolumeList { @@ -101,4 +102,22 @@ public class TestFsVolumeList { // checkDirs() should ignore the 2nd volume since it is closed. volumeList.checkDirs(); } + + @Test + public void testReleaseVolumeRefIfNoBlockScanner() throws IOException { + FsVolumeList volumeList = new FsVolumeList( + Collections.emptyList(), null, blockChooser); + File volDir = new File(baseDir, "volume-0"); + volDir.mkdirs(); + FsVolumeImpl volume = new FsVolumeImpl(dataset, "storage-id", volDir, + conf, StorageType.DEFAULT); + FsVolumeReference ref = volume.obtainReference(); + volumeList.addVolume(ref); + try { + ref.close(); + fail("Should throw exception because the reference is closed in " + + "VolumeList#addVolume()."); + } catch (IllegalStateException e) { + } + } }