Browse Source

HDFS-5944. LeaseManager:findLeaseWithPrefixPath can't handle path like /a/b/ and cause SecondaryNameNode failed do checkpoint. Contributed by Yonjiong Zhao

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-1@1570382 13f79535-47bb-0310-9956-ffa450edef68
Brandon Li 11 years ago
parent
commit
a2de02ab8c

+ 3 - 0
CHANGES.txt

@@ -196,6 +196,9 @@ Release 1.3.0 - unreleased
     HDFS-2264. NamenodeProtocol has the wrong value for clientPrincipal in 
     KerberosInfo annotation. (Aaron T. Myers, backported by jing9)
 
+    HDFS-5944. LeaseManager:findLeaseWithPrefixPath can't handle path like /a/b/
+    and cause SecondaryNameNode failed do checkpoint (Yunjiong Zhao via brandonli)
+
 Release 1.2.2 - unreleased
 
   INCOMPATIBLE CHANGES

+ 6 - 1
src/hdfs/org/apache/hadoop/hdfs/server/namenode/LeaseManager.java

@@ -331,7 +331,12 @@ public class LeaseManager {
     }
 
     List<Map.Entry<String, Lease>> entries = new ArrayList<Map.Entry<String, Lease>>();
-    final int srclen = prefix.length();
+    int srclen = prefix.length();
+
+    // prefix may ended with '/'
+    if (prefix.charAt(srclen -1) == Path.SEPARATOR_CHAR) {
+      srclen -= 1;
+    }
 
     for(Map.Entry<String, Lease> entry : path2lease.tailMap(prefix).entrySet()) {
       final String p = entry.getKey();

+ 32 - 0
src/test/org/apache/hadoop/hdfs/server/namenode/TestLeaseManager.java

@@ -46,6 +46,7 @@ public class TestLeaseManager extends TestCase {
     throws IOException, InterruptedException {
     Configuration conf = new Configuration();
     MiniDFSCluster cluster = new MiniDFSCluster(conf, 3, true, null);
+    cluster.waitActive();
     NameNode namenode = cluster.getNameNode();
     FSNamesystem spyNamesystem = spy(namenode.getNamesystem());
     LeaseManager leaseManager = new LeaseManager(spyNamesystem);
@@ -77,6 +78,37 @@ public class TestLeaseManager extends TestCase {
     
     assertTrue("internalReleaseOne not called", internalReleaseOneCalled.isCalled());
     assertFalse("internalRelease called", internalReleaseCalled.isCalled());
+    cluster.shutdown();
+  }
+
+  public void testRemoveLeaseWithPrefixPath() throws IOException {
+    Configuration conf = new Configuration();
+    MiniDFSCluster cluster = new MiniDFSCluster(conf, 3, true, null);
+    cluster.waitActive();
+    
+    NameNode namenode = cluster.getNameNode();
+    FSNamesystem spyNamesystem = spy(namenode.getNamesystem());
+    LeaseManager leaseManager = new LeaseManager(spyNamesystem);
+
+    leaseManager.addLease("holder1", "/a/b");
+    leaseManager.addLease("holder1", "/a/c");
+    assertNotNull(leaseManager.getLeaseByPath("/a/b"));
+    assertNotNull(leaseManager.getLeaseByPath("/a/c"));
+
+    leaseManager.removeLeaseWithPrefixPath("/a");
+
+    assertNull(leaseManager.getLeaseByPath("/a/b"));
+    assertNull(leaseManager.getLeaseByPath("/a/c"));
+
+    leaseManager.addLease("holder1", "/a/b");
+    leaseManager.addLease("holder1", "/a/c");
+
+    leaseManager.removeLeaseWithPrefixPath("/a/");
+
+    assertNull(leaseManager.getLeaseByPath("/a/b"));
+    assertNull(leaseManager.getLeaseByPath("/a/c"));
+    
+    cluster.shutdown();
   }
   
   private static class CalledAnswer<T> implements Answer<T>{