浏览代码

HADOOP-6545. Changes the Key for the FileSystem cache to be UGI. Contributed by Devaraj Das.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@912207 13f79535-47bb-0310-9956-ffa450edef68
Devaraj Das 15 年之前
父节点
当前提交
115ef5b8c7

+ 2 - 0
CHANGES.txt

@@ -224,6 +224,8 @@ Trunk (unreleased changes)
     HADOOP-6572. Makes sure that SASL encryption and push to responder
     HADOOP-6572. Makes sure that SASL encryption and push to responder
     queue for the RPC response happens atomically. (Kan Zhang via ddas)
     queue for the RPC response happens atomically. (Kan Zhang via ddas)
 
 
+    HADOOP-6545. Changes the Key for the FileSystem cache to be UGI (ddas)
+
 Release 0.21.0 - Unreleased
 Release 0.21.0 - Unreleased
 
 
   INCOMPATIBLE CHANGES
   INCOMPATIBLE CHANGES

+ 5 - 6
src/java/org/apache/hadoop/fs/FileSystem.java

@@ -1854,7 +1854,7 @@ public abstract class FileSystem extends Configured implements Closeable {
     static class Key {
     static class Key {
       final String scheme;
       final String scheme;
       final String authority;
       final String authority;
-      final String username;
+      final UserGroupInformation ugi;
       final long unique;   // an artificial way to make a key unique
       final long unique;   // an artificial way to make a key unique
 
 
       Key(URI uri, Configuration conf) throws IOException {
       Key(URI uri, Configuration conf) throws IOException {
@@ -1866,13 +1866,12 @@ public abstract class FileSystem extends Configured implements Closeable {
         authority = uri.getAuthority()==null?"":uri.getAuthority().toLowerCase();
         authority = uri.getAuthority()==null?"":uri.getAuthority().toLowerCase();
         this.unique = unique;
         this.unique = unique;
         
         
-        UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
-        username = ugi.getUserName();
+        this.ugi = UserGroupInformation.getCurrentUser();
       }
       }
 
 
       /** {@inheritDoc} */
       /** {@inheritDoc} */
       public int hashCode() {
       public int hashCode() {
-        return (scheme + authority + username).hashCode() + (int)unique;
+        return (scheme + authority).hashCode() + ugi.hashCode() + (int)unique;
       }
       }
 
 
       static boolean isEqual(Object a, Object b) {
       static boolean isEqual(Object a, Object b) {
@@ -1888,7 +1887,7 @@ public abstract class FileSystem extends Configured implements Closeable {
           Key that = (Key)obj;
           Key that = (Key)obj;
           return isEqual(this.scheme, that.scheme)
           return isEqual(this.scheme, that.scheme)
                  && isEqual(this.authority, that.authority)
                  && isEqual(this.authority, that.authority)
-                 && isEqual(this.username, that.username)
+                 && isEqual(this.ugi, that.ugi)
                  && (this.unique == that.unique);
                  && (this.unique == that.unique);
         }
         }
         return false;        
         return false;        
@@ -1896,7 +1895,7 @@ public abstract class FileSystem extends Configured implements Closeable {
 
 
       /** {@inheritDoc} */
       /** {@inheritDoc} */
       public String toString() {
       public String toString() {
-        return username + "@" + scheme + "://" + authority;        
+        return "("+ugi.toString() + ")@" + scheme + "://" + authority;        
       }
       }
     }
     }
   }
   }

+ 64 - 0
src/test/core/org/apache/hadoop/fs/TestFileSystemCaching.java

@@ -24,7 +24,16 @@ import static junit.framework.Assert.assertNotSame;
 import java.net.URI;
 import java.net.URI;
 
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.token.Token;
+import org.apache.hadoop.security.token.TokenIdentifier;
 import org.junit.Test;
 import org.junit.Test;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import static org.mockito.Mockito.mock;
+
+
 
 
 public class TestFileSystemCaching {
 public class TestFileSystemCaching {
 
 
@@ -46,5 +55,60 @@ public class TestFileSystemCaching {
     FileSystem fs2 = FileSystem.get(new URI("uncachedfile://a"), conf);
     FileSystem fs2 = FileSystem.get(new URI("uncachedfile://a"), conf);
     assertNotSame(fs1, fs2);
     assertNotSame(fs1, fs2);
   }
   }
+  
+  @SuppressWarnings("unchecked")
+  @Test
+  public <T extends TokenIdentifier> void testCacheForUgi() throws Exception {
+    final Configuration conf = new Configuration();
+    conf.set("fs.cachedfile.impl", conf.get("fs.file.impl"));
+    UserGroupInformation ugiA = UserGroupInformation.createRemoteUser("foo");
+    UserGroupInformation ugiB = UserGroupInformation.createRemoteUser("bar");
+    FileSystem fsA = ugiA.doAs(new PrivilegedExceptionAction<FileSystem>() {
+      public FileSystem run() throws Exception {
+        return FileSystem.get(new URI("cachedfile://a"), conf);
+      }
+    });
+    FileSystem fsA1 = ugiA.doAs(new PrivilegedExceptionAction<FileSystem>() {
+      public FileSystem run() throws Exception {
+        return FileSystem.get(new URI("cachedfile://a"), conf);
+      }
+    });
+    //Since the UGIs are the same, we should have the same filesystem for both
+    assertSame(fsA, fsA1);
+    
+    FileSystem fsB = ugiB.doAs(new PrivilegedExceptionAction<FileSystem>() {
+      public FileSystem run() throws Exception {
+        return FileSystem.get(new URI("cachedfile://a"), conf);
+      }
+    });
+    //Since the UGIs are different, we should end up with different filesystems
+    //corresponding to the two UGIs
+    assertNotSame(fsA, fsB);
+    
+    Token<T> t1 = mock(Token.class);
+    ugiA = UserGroupInformation.createRemoteUser("foo");
+    ugiA.addToken(t1);
+    
+    fsA = ugiA.doAs(new PrivilegedExceptionAction<FileSystem>() {
+      public FileSystem run() throws Exception {
+        return FileSystem.get(new URI("cachedfile://a"), conf);
+      }
+    });
+    //Although the users in the UGI are same, ugiA has tokens in it, and
+    //we should end up with different filesystems corresponding to the two UGIs
+    assertNotSame(fsA, fsA1);
+    
+    ugiA = UserGroupInformation.createRemoteUser("foo");
+    ugiA.addToken(t1);
+    
+    fsA1 = ugiA.doAs(new PrivilegedExceptionAction<FileSystem>() {
+      public FileSystem run() throws Exception {
+        return FileSystem.get(new URI("cachedfile://a"), conf);
+      }
+    });
+    //Now the users in the UGI are the same, and they also have the same token.
+    //We should have the same filesystem for both
+    assertSame(fsA, fsA1);
+  }
 
 
 }
 }