From ff8b7bc253be4d595272bc28a153de4e12282579 Mon Sep 17 00:00:00 2001 From: Tsz-wo Sze Date: Thu, 29 Jul 2010 17:58:55 +0000 Subject: [PATCH] HADOOP-6888. Add a new FileSystem API closeAllForUGI(..) for closing all file systems associated with a particular UGI. Contributed by Kan Zhang git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@980523 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 3 ++ src/java/org/apache/hadoop/fs/FileSystem.java | 37 +++++++++++++++++++ .../hadoop/fs/TestFileSystemCaching.java | 29 +++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index cd265868dc3..dcc452a0e1e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -26,6 +26,9 @@ Trunk (unreleased changes) input path if recursive is true. Block locations are returned together with each file's status. (hairong) + HADOOP-6888. Add a new FileSystem API closeAllForUGI(..) for closing all + file systems associated with a particular UGI. (Kan Zhang via szetszwo) + IMPROVEMENTS HADOOP-6644. util.Shell getGROUPS_FOR_USER_COMMAND method name diff --git a/src/java/org/apache/hadoop/fs/FileSystem.java b/src/java/org/apache/hadoop/fs/FileSystem.java index 534b334052e..9a994e35563 100644 --- a/src/java/org/apache/hadoop/fs/FileSystem.java +++ b/src/java/org/apache/hadoop/fs/FileSystem.java @@ -311,6 +311,17 @@ public abstract class FileSystem extends Configured implements Closeable { CACHE.closeAll(); } + /** + * Close all cached filesystems for a given UGI. Be sure those filesystems + * are not used anymore. + * @param ugi + * @throws IOException + */ + public static void closeAllForUGI(UserGroupInformation ugi) + throws IOException { + CACHE.closeAll(ugi); + } + /** Make sure that a path specifies a FileSystem. */ public Path makeQualified(Path path) { checkPath(path); @@ -1816,6 +1827,32 @@ public abstract class FileSystem extends Configured implements Closeable { } } + synchronized void closeAll(UserGroupInformation ugi) throws IOException { + List targetFSList = new ArrayList(); + //Make a pass over the list and collect the filesystems to close + //we cannot close inline since close() removes the entry from the Map + for (Map.Entry entry : map.entrySet()) { + final Key key = entry.getKey(); + final FileSystem fs = entry.getValue(); + if (ugi.equals(key.ugi) && fs != null) { + targetFSList.add(fs); + } + } + List exceptions = new ArrayList(); + //now make a pass over the target list and close each + for (FileSystem fs : targetFSList) { + try { + fs.close(); + } + catch(IOException ioe) { + exceptions.add(ioe); + } + } + if (!exceptions.isEmpty()) { + throw MultipleIOException.createIOException(exceptions); + } + } + /** FileSystem.Cache.Key */ static class Key { final String scheme; diff --git a/src/test/core/org/apache/hadoop/fs/TestFileSystemCaching.java b/src/test/core/org/apache/hadoop/fs/TestFileSystemCaching.java index b545e2eeeaa..0ec8305a5e4 100644 --- a/src/test/core/org/apache/hadoop/fs/TestFileSystemCaching.java +++ b/src/test/core/org/apache/hadoop/fs/TestFileSystemCaching.java @@ -179,4 +179,33 @@ public class TestFileSystemCaching { fs1.close(); fs2.close(); } + + @Test + public void testCloseAllForUGI() throws Exception { + final Configuration conf = new Configuration(); + conf.set("fs.cachedfile.impl", conf.get("fs.file.impl")); + UserGroupInformation ugiA = UserGroupInformation.createRemoteUser("foo"); + FileSystem fsA = ugiA.doAs(new PrivilegedExceptionAction() { + public FileSystem run() throws Exception { + return FileSystem.get(new URI("cachedfile://a"), conf); + } + }); + //Now we should get the cached filesystem + FileSystem fsA1 = ugiA.doAs(new PrivilegedExceptionAction() { + public FileSystem run() throws Exception { + return FileSystem.get(new URI("cachedfile://a"), conf); + } + }); + assertSame(fsA, fsA1); + + FileSystem.closeAllForUGI(ugiA); + + //Now we should get a different (newly created) filesystem + fsA1 = ugiA.doAs(new PrivilegedExceptionAction() { + public FileSystem run() throws Exception { + return FileSystem.get(new URI("cachedfile://a"), conf); + } + }); + assertNotSame(fsA, fsA1); + } }