Преглед на файлове

HADOOP-10866. RawLocalFileSystem fails to read symlink targets via the stat command when the format of the stat command uses non-curly quotes (yzhang via cmccabe)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1612428 13f79535-47bb-0310-9956-ffa450edef68
Colin McCabe преди 10 години
родител
ревизия
761d44f900

+ 4 - 0
hadoop-common-project/hadoop-common/CHANGES.txt

@@ -468,6 +468,10 @@ Release 2.6.0 - UNRELEASED
     HADOOP-10857.  Native Libraries Guide doen't mention a dependency on
     HADOOP-10857.  Native Libraries Guide doen't mention a dependency on
     openssl-development package (ozawa via cmccabe)
     openssl-development package (ozawa via cmccabe)
 
 
+    HADOOP-10866. RawLocalFileSystem fails to read symlink targets via the stat
+    command when the format of the stat command uses non-curly quotes (yzhang
+    via cmccabe)
+
 Release 2.5.0 - UNRELEASED
 Release 2.5.0 - UNRELEASED
 
 
   INCOMPATIBLE CHANGES
   INCOMPATIBLE CHANGES

+ 7 - 6
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/Stat.java

@@ -128,6 +128,8 @@ public class Stat extends Shell {
           " link " + original);
           " link " + original);
     }
     }
     // 6,symbolic link,6,1373584236,1373584236,lrwxrwxrwx,andrew,andrew,`link' -> `target'
     // 6,symbolic link,6,1373584236,1373584236,lrwxrwxrwx,andrew,andrew,`link' -> `target'
+    // OR
+    // 6,symbolic link,6,1373584236,1373584236,lrwxrwxrwx,andrew,andrew,'link' -> 'target'
     StringTokenizer tokens = new StringTokenizer(line, ",");
     StringTokenizer tokens = new StringTokenizer(line, ",");
     try {
     try {
       long length = Long.parseLong(tokens.nextToken());
       long length = Long.parseLong(tokens.nextToken());
@@ -147,18 +149,17 @@ public class Stat extends Shell {
       String group = tokens.nextToken();
       String group = tokens.nextToken();
       String symStr = tokens.nextToken();
       String symStr = tokens.nextToken();
       // 'notalink'
       // 'notalink'
-      // 'link' -> `target'
+      // `link' -> `target' OR 'link' -> 'target'
       // '' -> ''
       // '' -> ''
       Path symlink = null;
       Path symlink = null;
-      StringTokenizer symTokens = new StringTokenizer(symStr, "`");
-      symTokens.nextToken();
+      String parts[] = symStr.split(" -> ");      
       try {
       try {
-        String target = symTokens.nextToken();
-        target = target.substring(0, target.length()-1);
+        String target = parts[1];
+        target = target.substring(1, target.length()-1);
         if (!target.isEmpty()) {
         if (!target.isEmpty()) {
           symlink = new Path(target);
           symlink = new Path(target);
         }
         }
-      } catch (NoSuchElementException e) {
+      } catch (ArrayIndexOutOfBoundsException e) {
         // null if not a symlink
         // null if not a symlink
       }
       }
       // Set stat
       // Set stat

+ 19 - 9
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestStat.java

@@ -45,15 +45,15 @@ public class TestStat extends FileSystemTestHelper {
     final String doesNotExist;
     final String doesNotExist;
     final String directory;
     final String directory;
     final String file;
     final String file;
-    final String symlink;
+    final String[] symlinks;
     final String stickydir;
     final String stickydir;
 
 
     StatOutput(String doesNotExist, String directory, String file,
     StatOutput(String doesNotExist, String directory, String file,
-        String symlink, String stickydir) {
+        String[] symlinks, String stickydir) {
       this.doesNotExist = doesNotExist;
       this.doesNotExist = doesNotExist;
       this.directory = directory;
       this.directory = directory;
       this.file = file;
       this.file = file;
-      this.symlink = symlink;
+      this.symlinks = symlinks;
       this.stickydir = stickydir;
       this.stickydir = stickydir;
     }
     }
 
 
@@ -78,10 +78,12 @@ public class TestStat extends FileSystemTestHelper {
       status = stat.getFileStatusForTesting();
       status = stat.getFileStatusForTesting();
       assertTrue(status.isFile());
       assertTrue(status.isFile());
 
 
-      br = new BufferedReader(new StringReader(symlink));
-      stat.parseExecResult(br);
-      status = stat.getFileStatusForTesting();
-      assertTrue(status.isSymlink());
+      for (String symlink : symlinks) {
+        br = new BufferedReader(new StringReader(symlink));
+        stat.parseExecResult(br);
+        status = stat.getFileStatusForTesting();
+        assertTrue(status.isSymlink());
+      }
 
 
       br = new BufferedReader(new StringReader(stickydir));
       br = new BufferedReader(new StringReader(stickydir));
       stat.parseExecResult(br);
       stat.parseExecResult(br);
@@ -93,22 +95,30 @@ public class TestStat extends FileSystemTestHelper {
 
 
   @Test(timeout=10000)
   @Test(timeout=10000)
   public void testStatLinux() throws Exception {
   public void testStatLinux() throws Exception {
+    String[] symlinks = new String[] {
+        "6,symbolic link,1373584236,1373584236,777,andrew,andrew,`link' -> `target'",
+        "6,symbolic link,1373584236,1373584236,777,andrew,andrew,'link' -> 'target'"
+    };
     StatOutput linux = new StatOutput(
     StatOutput linux = new StatOutput(
         "stat: cannot stat `watermelon': No such file or directory",
         "stat: cannot stat `watermelon': No such file or directory",
         "4096,directory,1373584236,1373586485,755,andrew,root,`.'",
         "4096,directory,1373584236,1373586485,755,andrew,root,`.'",
         "0,regular empty file,1373584228,1373584228,644,andrew,andrew,`target'",
         "0,regular empty file,1373584228,1373584228,644,andrew,andrew,`target'",
-        "6,symbolic link,1373584236,1373584236,777,andrew,andrew,`link' -> `target'",
+        symlinks,
         "4096,directory,1374622334,1375124212,1755,andrew,andrew,`stickydir'");
         "4096,directory,1374622334,1375124212,1755,andrew,andrew,`stickydir'");
     linux.test();
     linux.test();
   }
   }
 
 
   @Test(timeout=10000)
   @Test(timeout=10000)
   public void testStatFreeBSD() throws Exception {
   public void testStatFreeBSD() throws Exception {
+    String[] symlinks = new String[] {
+        "6,Symbolic Link,1373508941,1373508941,120755,awang,awang,`link' -> `target'"
+    };
+    
     StatOutput freebsd = new StatOutput(
     StatOutput freebsd = new StatOutput(
         "stat: symtest/link: stat: No such file or directory",
         "stat: symtest/link: stat: No such file or directory",
         "512,Directory,1373583695,1373583669,40755,awang,awang,`link' -> `'",
         "512,Directory,1373583695,1373583669,40755,awang,awang,`link' -> `'",
         "0,Regular File,1373508937,1373508937,100644,awang,awang,`link' -> `'",
         "0,Regular File,1373508937,1373508937,100644,awang,awang,`link' -> `'",
-        "6,Symbolic Link,1373508941,1373508941,120755,awang,awang,`link' -> `target'",
+        symlinks,
         "512,Directory,1375139537,1375139537,41755,awang,awang,`link' -> `'");
         "512,Directory,1375139537,1375139537,41755,awang,awang,`link' -> `'");
     freebsd.test();
     freebsd.test();
   }
   }