HADOOP-6017. Lease Manager in NameNode does not handle certain characters
in filenames. This results in fatal errors in Secondary NameNode and while
restrating NameNode. (Tsz Wo (Nicholas), SZE via rangadi)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/core/branches/branch-0.18@785057 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CHANGES.txt b/CHANGES.txt
index 25a962e..2f12c12 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -25,6 +25,10 @@
 
     HADOOP-5644. Namnode is stuck in safe mode. (Suresh Srinivas via hairong)
 
+    HADOOP-6017. Lease Manager in NameNode does not handle certain characters
+    in filenames. This results in fatal errors in Secondary NameNode and while
+    restrating NameNode. (Tsz Wo (Nicholas), SZE via rangadi)
+
 Release 0.18.3 - 2009-01-27
 
   IMPROVEMENTS
diff --git a/src/hdfs/org/apache/hadoop/dfs/LeaseManager.java b/src/hdfs/org/apache/hadoop/dfs/LeaseManager.java
index a13aac6..6ab45b0 100644
--- a/src/hdfs/org/apache/hadoop/dfs/LeaseManager.java
+++ b/src/hdfs/org/apache/hadoop/dfs/LeaseManager.java
@@ -282,11 +282,12 @@
                ", replaceBy=" + replaceBy);
     }
 
+    final int len = overwrite.length();
     for(Map.Entry<String, Lease> entry : findLeaseWithPrefixPath(src, sortedLeasesByPath)) {
       final String oldpath = entry.getKey();
       final Lease lease = entry.getValue();
-      final String newpath = oldpath.replaceFirst(
-          java.util.regex.Pattern.quote(overwrite), replaceBy);
+      //overwrite must be a prefix of oldpath
+      final String newpath = replaceBy + oldpath.substring(len);
       if (LOG.isDebugEnabled()) {
         LOG.debug("changeLease: replacing " + oldpath + " with " + newpath);
       }
diff --git a/src/test/org/apache/hadoop/dfs/TestRenameWhileOpen.java b/src/test/org/apache/hadoop/dfs/TestRenameWhileOpen.java
index 692e4e4..af7e664 100644
--- a/src/test/org/apache/hadoop/dfs/TestRenameWhileOpen.java
+++ b/src/test/org/apache/hadoop/dfs/TestRenameWhileOpen.java
@@ -92,9 +92,8 @@
    * move /user/dir1 /user/dir3
    */
   public void testWhileOpenRenameParent() throws IOException {
-    /* XXX This test is temporarily disabled since sync() is not supported in
-     * 0.18.3. This is a 0.18.3 only change. */
-    if (true) return;
+    /* XXX parts of This test are temporarily disabled since sync() is not
+     * supported in 0.18.3. This is a 0.18.3 only change. */
     Configuration conf = new Configuration();
     final int MAX_IDLE_TIME = 2000; // 2s
     conf.setInt("ipc.client.connection.maxidletime", MAX_IDLE_TIME);
@@ -111,6 +110,8 @@
       fs = cluster.getFileSystem();
       final int nnport = cluster.getNameNodePort();
 
+      Path dir3 = new Path("/user/dir3");
+      if (false) {// Removed in 0.18
       // create file1.
       Path dir1 = new Path("/user/a+b/dir1");
       Path file1 = new Path(dir1, "file1");
@@ -130,10 +131,24 @@
       stm2.sync();
 
       // move dir1 while file1 is open
-      Path dir3 = new Path("/user/dir3");
       fs.mkdirs(dir3);
       fs.rename(dir1, dir3);
-
+      }
+      
+      // create file3
+      Path file3 = new Path(dir3, "file3");
+      FSDataOutputStream stm3 = TestFileCreation.createFile(fs, file3, 1);
+      writeFile(stm3);
+      // rename file3 to some bad name
+      try {
+        fs.rename(file3, new Path(dir3, "$ "));
+      } catch(Exception e) {
+        e.printStackTrace();
+      }
+      try { // ignore the io excpeiton while closing.
+        stm3.close();
+      } catch (IOException ignored) {}
+      
       // restart cluster with the same namenode port as before.
       // This ensures that leases are persisted in fsimage.
       cluster.shutdown();
@@ -151,11 +166,13 @@
       cluster.waitActive();
       fs = cluster.getFileSystem();
 
+      /* XXX Removed in 0.18
       Path newfile = new Path("/user/dir3/dir1", "file1");
       assertTrue(!fs.exists(file1));
       assertTrue(fs.exists(file2));
       assertTrue(fs.exists(newfile));
       checkFullFile(fs, newfile);
+      */
     } finally {
       fs.close();
       cluster.shutdown();