Author: sradia
Date: Fri Jun 1 01:34:35 2012
New Revision: 1344963
URL: http://svn.apache.org/viewvc?rev=1344963&view=rev
Log:
HADOOP-8374 Improve support for hard link manipulation on Windows (Bikas Saha
via Sanjay)
Modified:
hadoop/common/branches/branch-1-win/CHANGES.txt
hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/fs/HardLink.java
hadoop/common/branches/branch-1-win/src/test/org/apache/hadoop/fs/TestHardLink.java
Modified: hadoop/common/branches/branch-1-win/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-1-win/CHANGES.txt?rev=1344963&r1=1344962&r2=1344963&view=diff
==============================================================================
--- hadoop/common/branches/branch-1-win/CHANGES.txt (original)
+++ hadoop/common/branches/branch-1-win/CHANGES.txt Fri Jun 1 01:34:35 2012
@@ -25,6 +25,8 @@ branch-hadoop-1-win - unreleased
HADOOP-8440 HarFileSystem.decodeHarURI fails for URIs whose host contains
numbers (Ivan Mitic via Sanjay Radia)
+ HADOOP-8374 Improve support for hard link manipulation on Windows (Bikas
Saha via Sanjay)
+
Release 1.1.0 - unreleased
NEW FEATURES
Modified:
hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/fs/HardLink.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/fs/HardLink.java?rev=1344963&r1=1344962&r2=1344963&view=diff
==============================================================================
---
hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/fs/HardLink.java
(original)
+++
hadoop/common/branches/branch-1-win/src/core/org/apache/hadoop/fs/HardLink.java
Fri Jun 1 01:34:35 2012
@@ -25,9 +25,11 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
+import org.apache.hadoop.util.Shell;
+
/**
* 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,
* and the methods provided were blatantly non-thread-safe.
@@ -41,7 +43,7 @@ public class HardLink {
public enum OSType {
OS_TYPE_UNIX,
- OS_TYPE_WINXP,
+ OS_TYPE_WIN,
OS_TYPE_SOLARIS,
OS_TYPE_MAC
}
@@ -55,7 +57,7 @@ public class HardLink {
//methods without instantiating the HardLink object
static {
osType = getOSType();
- if (osType == OSType.OS_TYPE_WINXP) {
+ if (osType == OSType.OS_TYPE_WIN) {
// Windows
getHardLinkCommand = new HardLinkCGWin();
} else {
@@ -79,14 +81,8 @@ public class HardLink {
static private OSType getOSType() {
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")
|| osName.contains("Solaris")) {
@@ -254,11 +250,6 @@ public class HardLink {
/**
* Implementation of HardLinkCommandGetter class for Windows
- *
- * Note that the linkCount shell command for Windows is actually
- * a Cygwin shell command, and depends on ${cygwin}/bin
- * being in the Windows PATH environment variable, so
- * stat.exe can be found.
*/
static class HardLinkCGWin extends HardLinkCommandGetter {
//The Windows command getter impl class and its member fields are
@@ -266,14 +257,16 @@ public class HardLink {
//unit testing (sort of) on non-Win servers
static String[] hardLinkCommand = {
- "fsutil","hardlink","create", null, null};
+ Shell.WINUTILS,"hardlink","create", null, null};
static String[] hardLinkMultPrefix = {
"cmd","/q","/c","for", "%f", "in", "("};
static String hardLinkMultDir = "\\%f";
static String[] hardLinkMultSuffix = {
- ")", "do", "fsutil", "hardlink", "create", null,
+ ")", "do", Shell.WINUTILS, "hardlink", "create", null,
"%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.
//Subtract another 64b to allow for Java 'exec' overhead
static final int maxAllowedCmdArgLength = 8*1024 - 65;
@@ -324,12 +317,6 @@ public class HardLink {
String[] buf = new String[getLinkCountCommand.length];
System.arraycopy(getLinkCountCommand, 0, buf, 0,
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();
return buf;
}
@@ -350,7 +337,7 @@ public class HardLink {
//add the fixed overhead of the hardLinkMult command
//(prefix, suffix, and Dir suffix)
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;
}
@@ -577,14 +564,10 @@ public class HardLink {
/* Create an IOException for failing to get link count. */
private static IOException createIOException(File f, String message,
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
+ ": message=" + message
+ "; error=" + error
- + ((osType == OSType.OS_TYPE_WINXP) ? winErrMsg : "")
+ "; exit value=" + exitvalue;
return (cause == null) ? new IOException(s) : new IOException(s, cause);
}
Modified:
hadoop/common/branches/branch-1-win/src/test/org/apache/hadoop/fs/TestHardLink.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-1-win/src/test/org/apache/hadoop/fs/TestHardLink.java?rev=1344963&r1=1344962&r2=1344963&view=diff
==============================================================================
---
hadoop/common/branches/branch-1-win/src/test/org/apache/hadoop/fs/TestHardLink.java
(original)
+++
hadoop/common/branches/branch-1-win/src/test/org/apache/hadoop/fs/TestHardLink.java
Fri Jun 1 01:34:35 2012
@@ -54,17 +54,6 @@ import static org.apache.hadoop.fs.HardL
* NOTICE: This test class only tests the functionality of the OS
* upon which the test is run! (although you're pretty safe with the
* 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 {
@@ -221,9 +210,6 @@ public class TestHardLink {
* Sanity check the simplest case of HardLink.getLinkCount()
* to make sure we get back "1" for ordinary single-linked files.
* 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
public void testGetLinkCount() throws IOException {
@@ -404,7 +390,7 @@ public class TestHardLink {
assertEquals(5, win.hardLinkCommand.length);
assertEquals(7, win.hardLinkMultPrefix.length);
assertEquals(8, win.hardLinkMultSuffix.length);
- assertEquals(3, win.getLinkCountCommand.length);
+ assertEquals(4, win.getLinkCountCommand.length);
assertTrue(win.hardLinkMultPrefix[4].equals("%f"));
//make sure "%f" was not munged
@@ -415,7 +401,7 @@ public class TestHardLink {
assertTrue(win.hardLinkMultSuffix[7].equals("1>NUL"));
//make sure "1>NUL" was not munged
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
assertEquals(4, ("-c%h").length());
}