From 9c9b3f09ed65520acb6352f018fd739266a0eb29 Mon Sep 17 00:00:00 2001 From: Harsh J Date: Sun, 23 Sep 2012 10:50:44 +0000 Subject: [PATCH] HADOOP-8158. Interrupting hadoop fs -put from the command line causes a LeaseExpiredException. Contributed by Daryn Sharp. (harsh) git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1389010 13f79535-47bb-0310-9956-ffa450edef68 --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 ++ .../org/apache/hadoop/hdfs/DFSClient.java | 12 ++++++++ .../hadoop/hdfs/DistributedFileSystem.java | 6 ++-- .../hdfs/TestDistributedFileSystem.java | 29 ++++++++++++++++++- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 9831e9302b..52c4c0e60b 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -219,6 +219,9 @@ Trunk (Unreleased) HDFS-3678. Edit log files are never being purged from 2NN. (atm) + HADOOP-8158. Interrupting hadoop fs -put from the command line + causes a LeaseExpiredException. (daryn via harsh) + Release 2.0.3-alpha - Unreleased INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java index 53b6466202..92179fe99d 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java @@ -77,6 +77,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.BlockLocation; import org.apache.hadoop.fs.BlockStorageLocation; @@ -695,6 +696,17 @@ public synchronized void close() throws IOException { } } + /** + * Close all open streams, abandoning all of the leases and files being + * created. + * @param abort whether streams should be gracefully closed + */ + public void closeOutputStreams(boolean abort) { + if (clientRunning) { + closeAllFilesBeingWritten(abort); + } + } + /** * Get the default block size for this cluster * @return the default block size in bytes diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java index 3222ef2491..0e30245ce5 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java @@ -535,10 +535,10 @@ protected boolean primitiveMkdir(Path f, FsPermission absolutePermission) @Override public void close() throws IOException { try { - super.processDeleteOnExit(); - dfs.close(); - } finally { + dfs.closeOutputStreams(false); super.close(); + } finally { + dfs.close(); } } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java index 4815b61fee..b668779234 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java @@ -22,7 +22,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; - +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; @@ -54,6 +56,7 @@ import org.apache.hadoop.util.Time; import org.apache.log4j.Level; import org.junit.Test; +import org.mockito.InOrder; public class TestDistributedFileSystem { private static final Random RAN = new Random(); @@ -127,7 +130,31 @@ public void testDFSClose() throws Exception { if (cluster != null) {cluster.shutdown();} } } + + @Test + public void testDFSCloseOrdering() throws Exception { + DistributedFileSystem fs = new MyDistributedFileSystem(); + Path path = new Path("/a"); + fs.deleteOnExit(path); + fs.close(); + + InOrder inOrder = inOrder(fs.dfs); + inOrder.verify(fs.dfs).closeOutputStreams(eq(false)); + inOrder.verify(fs.dfs).delete(eq(path.toString()), eq(true)); + inOrder.verify(fs.dfs).close(); + } + private static class MyDistributedFileSystem extends DistributedFileSystem { + MyDistributedFileSystem() { + statistics = new FileSystem.Statistics("myhdfs"); // can't mock finals + dfs = mock(DFSClient.class); + } + @Override + public boolean exists(Path p) { + return true; // trick out deleteOnExit + } + } + @Test public void testDFSSeekExceptions() throws IOException { Configuration conf = getTestConfiguration();