Browse Source

HADOOP-8954. stat executable not found on Windows. Contributed by Bikas Saha, and Ivan Mitic ported by Chris Narouth.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-trunk-win@1401528 13f79535-47bb-0310-9956-ffa450edef68
Suresh Srinivas 12 years ago
parent
commit
0695c4f644

+ 3 - 0
hadoop-common-project/hadoop-common/CHANGES.branch-trunk-win.txt

@@ -14,3 +14,6 @@ branch-trunk-win changes - unreleased
   branch-trunk-win to enable initial test pass. (Raja Aluri, Davio Lao, 
   branch-trunk-win to enable initial test pass. (Raja Aluri, Davio Lao, 
   Sumadhur Reddy Bolli, Ahmed El Baz, Kanna Karanam, Chuan Liu, 
   Sumadhur Reddy Bolli, Ahmed El Baz, Kanna Karanam, Chuan Liu, 
   Ivan Mitic, Chris Nauroth, and Bikas Saha via suresh)
   Ivan Mitic, Chris Nauroth, and Bikas Saha via suresh)
+
+  HADOOP-8954. "stat" executable not found on Windows. (Bikas Saha, Ivan Mitic
+  ported by Chris Narouth via suresh)

+ 13 - 25
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/HardLink.java

@@ -25,9 +25,11 @@ import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.InputStreamReader;
 import java.util.Arrays;
 import java.util.Arrays;
 
 
+import org.apache.hadoop.util.Shell;
+
 /**
 /**
  * Class for creating hardlinks.
  * Class for creating hardlinks.
- * Supports Unix/Linux, WinXP/2003/Vista via Cygwin, and Mac OS X.
+ * Supports Unix/Linux, Windows via winutils , and Mac OS X.
  * 
  * 
  * The HardLink class was formerly a static inner class of FSUtil,
  * The HardLink class was formerly a static inner class of FSUtil,
  * and the methods provided were blatantly non-thread-safe.
  * and the methods provided were blatantly non-thread-safe.
@@ -41,7 +43,7 @@ public class HardLink {
 
 
   public enum OSType {
   public enum OSType {
     OS_TYPE_UNIX,
     OS_TYPE_UNIX,
-    OS_TYPE_WINXP,
+    OS_TYPE_WIN,
     OS_TYPE_SOLARIS,
     OS_TYPE_SOLARIS,
     OS_TYPE_MAC
     OS_TYPE_MAC
   }
   }
@@ -55,7 +57,7 @@ public class HardLink {
   //methods without instantiating the HardLink object
   //methods without instantiating the HardLink object
   static { 
   static { 
     osType = getOSType();
     osType = getOSType();
-    if (osType == OSType.OS_TYPE_WINXP) {
+    if (osType == OSType.OS_TYPE_WIN) {
       // Windows
       // Windows
       getHardLinkCommand = new HardLinkCGWin();
       getHardLinkCommand = new HardLinkCGWin();
     } else {
     } else {
@@ -79,14 +81,8 @@ public class HardLink {
   
   
   static private OSType getOSType() {
   static private OSType getOSType() {
     String osName = System.getProperty("os.name");
     String osName = System.getProperty("os.name");
-    if (osName.contains("Windows") &&
-            (osName.contains("XP") 
-            || osName.contains("2003") 
-            || osName.contains("Vista")
-            || osName.contains("Windows_7")
-            || osName.contains("Windows 7") 
-            || osName.contains("Windows7"))) {
-      return OSType.OS_TYPE_WINXP;
+    if (Shell.WINDOWS) {
+      return OSType.OS_TYPE_WIN;
     }
     }
     else if (osName.contains("SunOS") 
     else if (osName.contains("SunOS") 
             || osName.contains("Solaris")) {
             || osName.contains("Solaris")) {
@@ -266,14 +262,16 @@ public class HardLink {
     //unit testing (sort of) on non-Win servers
     //unit testing (sort of) on non-Win servers
 
 
     static String[] hardLinkCommand = {
     static String[] hardLinkCommand = {
-                        "fsutil","hardlink","create", null, null};
+                        Shell.WINUTILS,"hardlink","create", null, null};
     static String[] hardLinkMultPrefix = {
     static String[] hardLinkMultPrefix = {
                         "cmd","/q","/c","for", "%f", "in", "("};
                         "cmd","/q","/c","for", "%f", "in", "("};
     static String   hardLinkMultDir = "\\%f";
     static String   hardLinkMultDir = "\\%f";
     static String[] hardLinkMultSuffix = {
     static String[] hardLinkMultSuffix = {
-                        ")", "do", "fsutil", "hardlink", "create", null, 
+                        ")", "do", Shell.WINUTILS, "hardlink", "create", null,
                         "%f", "1>NUL"};
                         "%f", "1>NUL"};
-    static String[] getLinkCountCommand = {"stat","-c%h", null};
+    static String[] getLinkCountCommand = {
+                        Shell.WINUTILS, "hardlink",
+                        "stat", null};
     //Windows guarantees only 8K - 1 bytes cmd length.
     //Windows guarantees only 8K - 1 bytes cmd length.
     //Subtract another 64b to allow for Java 'exec' overhead
     //Subtract another 64b to allow for Java 'exec' overhead
     static final int maxAllowedCmdArgLength = 8*1024 - 65;
     static final int maxAllowedCmdArgLength = 8*1024 - 65;
@@ -324,12 +322,6 @@ public class HardLink {
       String[] buf = new String[getLinkCountCommand.length];
       String[] buf = new String[getLinkCountCommand.length];
       System.arraycopy(getLinkCountCommand, 0, buf, 0, 
       System.arraycopy(getLinkCountCommand, 0, buf, 0, 
                        getLinkCountCommand.length);
                        getLinkCountCommand.length);
-      //The linkCount command is actually a Cygwin shell command,
-      //not a Windows shell command, so we should use "makeShellPath()"
-      //instead of "getCanonicalPath()".  However, that causes another
-      //shell exec to "cygpath.exe", and "stat.exe" actually can handle
-      //DOS-style paths (it just prints a couple hundred bytes of warning
-      //to stderr), so we use the more efficient "getCanonicalPath()".
       buf[getLinkCountCommand.length - 1] = file.getCanonicalPath();
       buf[getLinkCountCommand.length - 1] = file.getCanonicalPath();
       return buf;
       return buf;
     }
     }
@@ -350,7 +342,7 @@ public class HardLink {
       //add the fixed overhead of the hardLinkMult command 
       //add the fixed overhead of the hardLinkMult command 
       //(prefix, suffix, and Dir suffix)
       //(prefix, suffix, and Dir suffix)
       sum += ("cmd.exe /q /c for %f in ( ) do "
       sum += ("cmd.exe /q /c for %f in ( ) do "
-              + "fsutil hardlink create \\%f %f 1>NUL ").length();
+              + Shell.WINUTILS + " hardlink create \\%f %f 1>NUL ").length();
       return sum;
       return sum;
     }
     }
     
     
@@ -577,14 +569,10 @@ public class HardLink {
   /* Create an IOException for failing to get link count. */
   /* Create an IOException for failing to get link count. */
   private static IOException createIOException(File f, String message,
   private static IOException createIOException(File f, String message,
       String error, int exitvalue, Exception cause) {
       String error, int exitvalue, Exception cause) {
-    
-    final String winErrMsg = "; Windows errors in getLinkCount are often due "
-         + "to Cygwin misconfiguration";
 
 
     final String s = "Failed to get link count on file " + f
     final String s = "Failed to get link count on file " + f
         + ": message=" + message
         + ": message=" + message
         + "; error=" + error
         + "; error=" + error
-        + ((osType == OSType.OS_TYPE_WINXP) ? winErrMsg : "")
         + "; exit value=" + exitvalue;
         + "; exit value=" + exitvalue;
     return (cause == null) ? new IOException(s) : new IOException(s, cause);
     return (cause == null) ? new IOException(s) : new IOException(s, cause);
   }
   }

+ 2 - 16
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestHardLink.java

@@ -54,17 +54,6 @@ import static org.apache.hadoop.fs.HardLink.*;
  * NOTICE: This test class only tests the functionality of the OS
  * NOTICE: This test class only tests the functionality of the OS
  * upon which the test is run! (although you're pretty safe with the
  * upon which the test is run! (although you're pretty safe with the
  * unix-like OS's, unless a typo sneaks in.)
  * unix-like OS's, unless a typo sneaks in.)
- * 
- * Notes about Windows testing:  
- * (a) In order to create hardlinks, the process must be run with 
- * administrative privs, in both the account AND the invocation.
- * For instance, to run within Eclipse, the Eclipse application must be 
- * launched by right-clicking on it, and selecting "Run as Administrator" 
- * (and that option will only be available if the current user id does 
- * in fact have admin privs).
- * (b) The getLinkCount() test case will fail for Windows, unless Cygwin
- * is set up properly.  In particular, ${cygwin}/bin must be in
- * the PATH environment variable, so the cygwin utilities can be found.
  */
  */
 public class TestHardLink {
 public class TestHardLink {
   
   
@@ -221,9 +210,6 @@ public class TestHardLink {
    * Sanity check the simplest case of HardLink.getLinkCount()
    * Sanity check the simplest case of HardLink.getLinkCount()
    * to make sure we get back "1" for ordinary single-linked files.
    * to make sure we get back "1" for ordinary single-linked files.
    * Tests with multiply-linked files are in later test cases.
    * Tests with multiply-linked files are in later test cases.
-   * 
-   * If this fails on Windows but passes on Unix, the most likely cause is 
-   * incorrect configuration of the Cygwin installation; see above.
    */
    */
   @Test
   @Test
   public void testGetLinkCount() throws IOException {
   public void testGetLinkCount() throws IOException {
@@ -404,7 +390,7 @@ public class TestHardLink {
     assertEquals(5, win.hardLinkCommand.length); 
     assertEquals(5, win.hardLinkCommand.length); 
     assertEquals(7, win.hardLinkMultPrefix.length);
     assertEquals(7, win.hardLinkMultPrefix.length);
     assertEquals(8, win.hardLinkMultSuffix.length);
     assertEquals(8, win.hardLinkMultSuffix.length);
-    assertEquals(3, win.getLinkCountCommand.length);
+    assertEquals(4, win.getLinkCountCommand.length);
 
 
     assertTrue(win.hardLinkMultPrefix[4].equals("%f"));
     assertTrue(win.hardLinkMultPrefix[4].equals("%f"));
     //make sure "%f" was not munged
     //make sure "%f" was not munged
@@ -415,7 +401,7 @@ public class TestHardLink {
     assertTrue(win.hardLinkMultSuffix[7].equals("1>NUL"));
     assertTrue(win.hardLinkMultSuffix[7].equals("1>NUL"));
     //make sure "1>NUL" was not munged
     //make sure "1>NUL" was not munged
     assertEquals(5, ("1>NUL").length()); 
     assertEquals(5, ("1>NUL").length()); 
-    assertTrue(win.getLinkCountCommand[1].equals("-c%h"));
+    assertTrue(win.getLinkCountCommand[1].equals("hardlink"));
     //make sure "-c%h" was not munged
     //make sure "-c%h" was not munged
     assertEquals(4, ("-c%h").length()); 
     assertEquals(4, ("-c%h").length()); 
   }
   }