HADOOP-8957. Merge r1420965 from trunk
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1490115 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0cb5e152d4
commit
a35a2ca335
|
@ -239,6 +239,9 @@ Release 2.1.0-beta - UNRELEASED
|
||||||
HADOOP-9593. stack trace printed at ERROR for all yarn clients without
|
HADOOP-9593. stack trace printed at ERROR for all yarn clients without
|
||||||
hadoop.home set (stevel)
|
hadoop.home set (stevel)
|
||||||
|
|
||||||
|
HADOOP-8957 AbstractFileSystem#IsValidName should be overridden for
|
||||||
|
embedded file systems like ViewFs (Chris Nauroth via Sanjay Radia)
|
||||||
|
|
||||||
BREAKDOWN OF HADOOP-8562 SUBTASKS AND RELATED JIRAS
|
BREAKDOWN OF HADOOP-8562 SUBTASKS AND RELATED JIRAS
|
||||||
|
|
||||||
HADOOP-8924. Hadoop Common creating package-info.java must not depend on
|
HADOOP-8924. Hadoop Common creating package-info.java must not depend on
|
||||||
|
|
|
@ -85,14 +85,20 @@ public abstract class AbstractFileSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prohibits names which contain a ".", "..", ":" or "/"
|
* Returns true if the specified string is considered valid in the path part
|
||||||
|
* of a URI by this file system. The default implementation enforces the rules
|
||||||
|
* of HDFS, but subclasses may override this method to implement specific
|
||||||
|
* validation rules for specific file systems.
|
||||||
|
*
|
||||||
|
* @param src String source filename to check, path part of the URI
|
||||||
|
* @return boolean true if the specified string is considered valid
|
||||||
*/
|
*/
|
||||||
private static boolean isValidName(String src) {
|
public boolean isValidName(String src) {
|
||||||
// Check for ".." "." ":" "/"
|
// Prohibit ".." "." and anything containing ":"
|
||||||
StringTokenizer tokens = new StringTokenizer(src, Path.SEPARATOR);
|
StringTokenizer tokens = new StringTokenizer(src, Path.SEPARATOR);
|
||||||
while(tokens.hasMoreTokens()) {
|
while(tokens.hasMoreTokens()) {
|
||||||
String element = tokens.nextToken();
|
String element = tokens.nextToken();
|
||||||
if (element.equals("target/generated-sources") ||
|
if (element.equals("..") ||
|
||||||
element.equals(".") ||
|
element.equals(".") ||
|
||||||
(element.indexOf(":") >= 0)) {
|
(element.indexOf(":") >= 0)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -278,4 +278,9 @@ public abstract class FilterFs extends AbstractFileSystem {
|
||||||
public List<Token<?>> getDelegationTokens(String renewer) throws IOException {
|
public List<Token<?>> getDelegationTokens(String renewer) throws IOException {
|
||||||
return myFs.getDelegationTokens(renewer);
|
return myFs.getDelegationTokens(renewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidName(String src) {
|
||||||
|
return myFs.isValidName(src);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,14 @@ public class RawLocalFs extends DelegateToFileSystem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidName(String src) {
|
||||||
|
// Different local file systems have different validation rules. Skip
|
||||||
|
// validation here and just let the OS handle it. This is consistent with
|
||||||
|
// RawLocalFileSystem.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getLinkTarget(Path f) throws IOException {
|
public Path getLinkTarget(Path f) throws IOException {
|
||||||
/* We should never get here. Valid local links are resolved transparently
|
/* We should never get here. Valid local links are resolved transparently
|
||||||
|
|
|
@ -83,7 +83,12 @@ class ChRootedFs extends AbstractFileSystem {
|
||||||
return new Path((chRootPathPart.isRoot() ? "" : chRootPathPartString)
|
return new Path((chRootPathPart.isRoot() ? "" : chRootPathPartString)
|
||||||
+ path.toUri().getPath());
|
+ path.toUri().getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidName(String src) {
|
||||||
|
return myFs.isValidName(fullPath(new Path(src)).toUri().toString());
|
||||||
|
}
|
||||||
|
|
||||||
public ChRootedFs(final AbstractFileSystem fs, final Path theRoot)
|
public ChRootedFs(final AbstractFileSystem fs, final Path theRoot)
|
||||||
throws URISyntaxException {
|
throws URISyntaxException {
|
||||||
super(fs.getUri(), fs.getUri().getScheme(),
|
super(fs.getUri(), fs.getUri().getScheme(),
|
||||||
|
@ -103,7 +108,7 @@ class ChRootedFs extends AbstractFileSystem {
|
||||||
// scheme:/// and scheme://authority/
|
// scheme:/// and scheme://authority/
|
||||||
myUri = new URI(myFs.getUri().toString() +
|
myUri = new URI(myFs.getUri().toString() +
|
||||||
(myFs.getUri().getAuthority() == null ? "" : Path.SEPARATOR) +
|
(myFs.getUri().getAuthority() == null ? "" : Path.SEPARATOR) +
|
||||||
chRootPathPart.toString().substring(1));
|
chRootPathPart.toUri().getPath().substring(1));
|
||||||
super.checkPath(theRoot);
|
super.checkPath(theRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,9 @@ import org.apache.hadoop.util.Time;
|
||||||
@InterfaceAudience.Public
|
@InterfaceAudience.Public
|
||||||
@InterfaceStability.Evolving /*Evolving for a release,to be changed to Stable */
|
@InterfaceStability.Evolving /*Evolving for a release,to be changed to Stable */
|
||||||
public class ViewFileSystem extends FileSystem {
|
public class ViewFileSystem extends FileSystem {
|
||||||
|
|
||||||
|
private static final Path ROOT_PATH = new Path(Path.SEPARATOR);
|
||||||
|
|
||||||
static AccessControlException readOnlyMountTable(final String operation,
|
static AccessControlException readOnlyMountTable(final String operation,
|
||||||
final String p) {
|
final String p) {
|
||||||
return new AccessControlException(
|
return new AccessControlException(
|
||||||
|
@ -98,23 +101,6 @@ public class ViewFileSystem extends FileSystem {
|
||||||
InodeTree<FileSystem> fsState; // the fs state; ie the mount table
|
InodeTree<FileSystem> fsState; // the fs state; ie the mount table
|
||||||
Path homeDir = null;
|
Path homeDir = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* Prohibits names which contain a ".", "..", ":" or "/"
|
|
||||||
*/
|
|
||||||
private static boolean isValidName(final String src) {
|
|
||||||
// Check for ".." "." ":" "/"
|
|
||||||
final StringTokenizer tokens = new StringTokenizer(src, Path.SEPARATOR);
|
|
||||||
while(tokens.hasMoreTokens()) {
|
|
||||||
String element = tokens.nextToken();
|
|
||||||
if (element.equals("..") ||
|
|
||||||
element.equals(".") ||
|
|
||||||
(element.indexOf(":") >= 0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the path Absolute and get the path-part of a pathname.
|
* Make the path Absolute and get the path-part of a pathname.
|
||||||
* Checks that URI matches this file system
|
* Checks that URI matches this file system
|
||||||
|
@ -126,10 +112,6 @@ public class ViewFileSystem extends FileSystem {
|
||||||
private String getUriPath(final Path p) {
|
private String getUriPath(final Path p) {
|
||||||
checkPath(p);
|
checkPath(p);
|
||||||
String s = makeAbsolute(p).toUri().getPath();
|
String s = makeAbsolute(p).toUri().getPath();
|
||||||
if (!isValidName(s)) {
|
|
||||||
throw new InvalidPathException("Path part " + s + " from URI" + p
|
|
||||||
+ " is not a valid filename.");
|
|
||||||
}
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,7 +671,7 @@ public class ViewFileSystem extends FileSystem {
|
||||||
PERMISSION_RRR, ugi.getUserName(), ugi.getGroupNames()[0],
|
PERMISSION_RRR, ugi.getUserName(), ugi.getGroupNames()[0],
|
||||||
|
|
||||||
new Path(theInternalDir.fullPath).makeQualified(
|
new Path(theInternalDir.fullPath).makeQualified(
|
||||||
myUri, null));
|
myUri, ROOT_PATH));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -597,6 +597,12 @@ public class ViewFs extends AbstractFileSystem {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidName(String src) {
|
||||||
|
// Prefix validated at mount time and rest of path validated by mount target.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.EnumSet;
|
||||||
import static org.apache.hadoop.fs.FileContextTestHelper.*;
|
import static org.apache.hadoop.fs.FileContextTestHelper.*;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.fs.AbstractFileSystem;
|
||||||
import org.apache.hadoop.fs.CreateFlag;
|
import org.apache.hadoop.fs.CreateFlag;
|
||||||
import org.apache.hadoop.fs.FileContext;
|
import org.apache.hadoop.fs.FileContext;
|
||||||
import org.apache.hadoop.fs.FileContextTestHelper;
|
import org.apache.hadoop.fs.FileContextTestHelper;
|
||||||
|
@ -36,6 +37,7 @@ import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
public class TestChRootedFs {
|
public class TestChRootedFs {
|
||||||
FileContextTestHelper fileContextTestHelper = new FileContextTestHelper();
|
FileContextTestHelper fileContextTestHelper = new FileContextTestHelper();
|
||||||
|
@ -308,4 +310,21 @@ public class TestChRootedFs {
|
||||||
fc.getDefaultFileSystem().resolvePath(new Path("/nonExisting"));
|
fc.getDefaultFileSystem().resolvePath(new Path("/nonExisting"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsValidNameValidInBaseFs() throws Exception {
|
||||||
|
AbstractFileSystem baseFs = Mockito.spy(fc.getDefaultFileSystem());
|
||||||
|
ChRootedFs chRootedFs = new ChRootedFs(baseFs, new Path("/chroot"));
|
||||||
|
Mockito.doReturn(true).when(baseFs).isValidName(Mockito.anyString());
|
||||||
|
Assert.assertTrue(chRootedFs.isValidName("/test"));
|
||||||
|
Mockito.verify(baseFs).isValidName("/chroot/test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsValidNameInvalidInBaseFs() throws Exception {
|
||||||
|
AbstractFileSystem baseFs = Mockito.spy(fc.getDefaultFileSystem());
|
||||||
|
ChRootedFs chRootedFs = new ChRootedFs(baseFs, new Path("/chroot"));
|
||||||
|
Mockito.doReturn(false).when(baseFs).isValidName(Mockito.anyString());
|
||||||
|
Assert.assertFalse(chRootedFs.isValidName("/test"));
|
||||||
|
Mockito.verify(baseFs).isValidName("/chroot/test");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,6 +345,9 @@ Release 2.1.0-beta - UNRELEASED
|
||||||
HDFS-4815. TestRBWBlockInvalidation: Double call countReplicas() to fetch
|
HDFS-4815. TestRBWBlockInvalidation: Double call countReplicas() to fetch
|
||||||
corruptReplicas and liveReplicas is not needed. (Tian Hong Wang via atm)
|
corruptReplicas and liveReplicas is not needed. (Tian Hong Wang via atm)
|
||||||
|
|
||||||
|
HADOOP-8957 HDFS tests for AbstractFileSystem#IsValidName should be overridden for
|
||||||
|
embedded file systems like ViewFs (Chris Nauroth via Sanjay Radia)
|
||||||
|
|
||||||
BREAKDOWN OF HDFS-347 SUBTASKS AND RELATED JIRAS
|
BREAKDOWN OF HDFS-347 SUBTASKS AND RELATED JIRAS
|
||||||
|
|
||||||
HDFS-4353. Encapsulate connections to peers in Peer and PeerServer classes.
|
HDFS-4353. Encapsulate connections to peers in Peer and PeerServer classes.
|
||||||
|
|
|
@ -257,7 +257,22 @@ public class TestHDFSFileContextMainOperations extends
|
||||||
Assert.assertFalse(fs.exists(src1)); // ensure src1 is already renamed
|
Assert.assertFalse(fs.exists(src1)); // ensure src1 is already renamed
|
||||||
Assert.assertTrue(fs.exists(dst1)); // ensure rename dst exists
|
Assert.assertTrue(fs.exists(dst1)); // ensure rename dst exists
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsValidNameInvalidNames() {
|
||||||
|
String[] invalidNames = {
|
||||||
|
"/foo/../bar",
|
||||||
|
"/foo/./bar",
|
||||||
|
"/foo/:/bar",
|
||||||
|
"/foo:bar"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (String invalidName: invalidNames) {
|
||||||
|
Assert.assertFalse(invalidName + " is not valid",
|
||||||
|
fc.getDefaultFileSystem().isValidName(invalidName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void oldRename(Path src, Path dst, boolean renameSucceeds,
|
private void oldRename(Path src, Path dst, boolean renameSucceeds,
|
||||||
boolean exception) throws Exception {
|
boolean exception) throws Exception {
|
||||||
DistributedFileSystem fs = (DistributedFileSystem) cluster.getFileSystem();
|
DistributedFileSystem fs = (DistributedFileSystem) cluster.getFileSystem();
|
||||||
|
|
|
@ -640,9 +640,12 @@ public class TestDFSUtil {
|
||||||
@Test (timeout=15000)
|
@Test (timeout=15000)
|
||||||
public void testIsValidName() {
|
public void testIsValidName() {
|
||||||
assertFalse(DFSUtil.isValidName("/foo/../bar"));
|
assertFalse(DFSUtil.isValidName("/foo/../bar"));
|
||||||
|
assertFalse(DFSUtil.isValidName("/foo/./bar"));
|
||||||
assertFalse(DFSUtil.isValidName("/foo//bar"));
|
assertFalse(DFSUtil.isValidName("/foo//bar"));
|
||||||
assertTrue(DFSUtil.isValidName("/"));
|
assertTrue(DFSUtil.isValidName("/"));
|
||||||
assertTrue(DFSUtil.isValidName("/bar/"));
|
assertTrue(DFSUtil.isValidName("/bar/"));
|
||||||
|
assertFalse(DFSUtil.isValidName("/foo/:/bar"));
|
||||||
|
assertFalse(DFSUtil.isValidName("/foo:bar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=5000)
|
@Test(timeout=5000)
|
||||||
|
|
Loading…
Reference in New Issue