HDFS-4595. Merging 1456047 from trunk.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1456048 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Suresh Srinivas 2013-03-13 16:54:10 +00:00
parent 7f75863029
commit e81ffd1705
6 changed files with 165 additions and 83 deletions

View File

@ -74,6 +74,9 @@ Release 2.0.5-beta - UNRELEASED
HDFS-4484. libwebhdfs compilation broken with gcc 4.6.2. (Colin Patrick HDFS-4484. libwebhdfs compilation broken with gcc 4.6.2. (Colin Patrick
McCabe via atm) McCabe via atm)
HDFS-4595. When short circuit read is fails, DFSClient does not fallback
to regular reads. (suresh)
Release 2.0.4-alpha - UNRELEASED Release 2.0.4-alpha - UNRELEASED
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -23,6 +23,7 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.PrivilegedExceptionAction;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -31,6 +32,7 @@ import java.util.Map;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.hdfs.protocol.BlockLocalPathInfo; import org.apache.hadoop.hdfs.protocol.BlockLocalPathInfo;
import org.apache.hadoop.hdfs.protocol.ClientDatanodeProtocol; import org.apache.hadoop.hdfs.protocol.ClientDatanodeProtocol;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo; import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
@ -41,6 +43,7 @@ import org.apache.hadoop.hdfs.server.datanode.BlockMetadataHeader;
import org.apache.hadoop.hdfs.util.DirectBufferPool; import org.apache.hadoop.hdfs.util.DirectBufferPool;
import org.apache.hadoop.ipc.RPC; import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.token.Token; import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.util.DataChecksum; import org.apache.hadoop.util.DataChecksum;
@ -86,11 +89,21 @@ class BlockReaderLocal implements BlockReader {
} }
private synchronized ClientDatanodeProtocol getDatanodeProxy( private synchronized ClientDatanodeProtocol getDatanodeProxy(
DatanodeInfo node, Configuration conf, int socketTimeout, UserGroupInformation ugi, final DatanodeInfo node,
boolean connectToDnViaHostname) throws IOException { final Configuration conf, final int socketTimeout,
final boolean connectToDnViaHostname) throws IOException {
if (proxy == null) { if (proxy == null) {
proxy = DFSUtil.createClientDatanodeProtocolProxy(node, conf, try {
socketTimeout, connectToDnViaHostname); proxy = ugi.doAs(new PrivilegedExceptionAction<ClientDatanodeProtocol>() {
@Override
public ClientDatanodeProtocol run() throws Exception {
return DFSUtil.createClientDatanodeProtocolProxy(node, conf,
socketTimeout, connectToDnViaHostname);
}
});
} catch (InterruptedException e) {
LOG.warn("encountered exception ", e);
}
} }
return proxy; return proxy;
} }
@ -154,17 +167,18 @@ class BlockReaderLocal implements BlockReader {
/** /**
* The only way this object can be instantiated. * The only way this object can be instantiated.
*/ */
static BlockReaderLocal newBlockReader(Configuration conf, String file, static BlockReaderLocal newBlockReader(UserGroupInformation ugi,
ExtendedBlock blk, Token<BlockTokenIdentifier> token, DatanodeInfo node, Configuration conf, String file, ExtendedBlock blk,
int socketTimeout, long startOffset, long length, Token<BlockTokenIdentifier> token, DatanodeInfo node, int socketTimeout,
boolean connectToDnViaHostname) throws IOException { long startOffset, long length, boolean connectToDnViaHostname)
throws IOException {
LocalDatanodeInfo localDatanodeInfo = getLocalDatanodeInfo(node LocalDatanodeInfo localDatanodeInfo = getLocalDatanodeInfo(node
.getIpcPort()); .getIpcPort());
// check the cache first // check the cache first
BlockLocalPathInfo pathinfo = localDatanodeInfo.getBlockLocalPathInfo(blk); BlockLocalPathInfo pathinfo = localDatanodeInfo.getBlockLocalPathInfo(blk);
if (pathinfo == null) { if (pathinfo == null) {
pathinfo = getBlockPathInfo(blk, node, conf, socketTimeout, token, pathinfo = getBlockPathInfo(ugi, blk, node, conf, socketTimeout, token,
connectToDnViaHostname); connectToDnViaHostname);
} }
@ -241,13 +255,13 @@ class BlockReaderLocal implements BlockReader {
return ldInfo; return ldInfo;
} }
private static BlockLocalPathInfo getBlockPathInfo(ExtendedBlock blk, private static BlockLocalPathInfo getBlockPathInfo(UserGroupInformation ugi,
DatanodeInfo node, Configuration conf, int timeout, ExtendedBlock blk, DatanodeInfo node, Configuration conf, int timeout,
Token<BlockTokenIdentifier> token, boolean connectToDnViaHostname) Token<BlockTokenIdentifier> token, boolean connectToDnViaHostname)
throws IOException { throws IOException {
LocalDatanodeInfo localDatanodeInfo = getLocalDatanodeInfo(node.getIpcPort()); LocalDatanodeInfo localDatanodeInfo = getLocalDatanodeInfo(node.getIpcPort());
BlockLocalPathInfo pathinfo = null; BlockLocalPathInfo pathinfo = null;
ClientDatanodeProtocol proxy = localDatanodeInfo.getDatanodeProxy(node, ClientDatanodeProtocol proxy = localDatanodeInfo.getDatanodeProxy(ugi, node,
conf, timeout, connectToDnViaHostname); conf, timeout, connectToDnViaHostname);
try { try {
// make RPC to local datanode to find local pathnames of blocks // make RPC to local datanode to find local pathnames of blocks

View File

@ -414,6 +414,7 @@ public class DFSClient implements java.io.Closeable {
"null URI"); "null URI");
NameNodeProxies.ProxyAndInfo<ClientProtocol> proxyInfo = NameNodeProxies.ProxyAndInfo<ClientProtocol> proxyInfo =
NameNodeProxies.createProxy(conf, nameNodeUri, ClientProtocol.class); NameNodeProxies.createProxy(conf, nameNodeUri, ClientProtocol.class);
this.dtService = proxyInfo.getDelegationTokenService(); this.dtService = proxyInfo.getDelegationTokenService();
this.namenode = proxyInfo.getProxy(); this.namenode = proxyInfo.getProxy();
} }
@ -782,12 +783,13 @@ public class DFSClient implements java.io.Closeable {
/** /**
* Get {@link BlockReader} for short circuited local reads. * Get {@link BlockReader} for short circuited local reads.
*/ */
static BlockReader getLocalBlockReader(Configuration conf, static BlockReader getLocalBlockReader(UserGroupInformation ugi,
String src, ExtendedBlock blk, Token<BlockTokenIdentifier> accessToken, Configuration conf, String src, ExtendedBlock blk,
DatanodeInfo chosenNode, int socketTimeout, long offsetIntoBlock, Token<BlockTokenIdentifier> accessToken, DatanodeInfo chosenNode,
boolean connectToDnViaHostname) throws InvalidToken, IOException { int socketTimeout, long offsetIntoBlock, boolean connectToDnViaHostname)
throws InvalidToken, IOException {
try { try {
return BlockReaderLocal.newBlockReader(conf, src, blk, accessToken, return BlockReaderLocal.newBlockReader(ugi, conf, src, blk, accessToken,
chosenNode, socketTimeout, offsetIntoBlock, blk.getNumBytes() chosenNode, socketTimeout, offsetIntoBlock, blk.getNumBytes()
- offsetIntoBlock, connectToDnViaHostname); - offsetIntoBlock, connectToDnViaHostname);
} catch (RemoteException re) { } catch (RemoteException re) {
@ -1638,7 +1640,7 @@ public class DFSClient implements java.io.Closeable {
* @param socketFactory to create sockets to connect to DNs * @param socketFactory to create sockets to connect to DNs
* @param socketTimeout timeout to use when connecting and waiting for a response * @param socketTimeout timeout to use when connecting and waiting for a response
* @param encryptionKey the key needed to communicate with DNs in this cluster * @param encryptionKey the key needed to communicate with DNs in this cluster
* @param connectToDnViaHostname {@see #connectToDnViaHostname()} * @param connectToDnViaHostname {@link #connectToDnViaHostname()}
* @return The checksum * @return The checksum
*/ */
static MD5MD5CRC32FileChecksum getFileChecksum(String src, static MD5MD5CRC32FileChecksum getFileChecksum(String src,
@ -2250,6 +2252,12 @@ public class DFSClient implements java.io.Closeable {
} }
void disableShortCircuit() { void disableShortCircuit() {
LOG.info("Short circuit is disabled");
shortCircuitLocalReads = false; shortCircuitLocalReads = false;
} }
@VisibleForTesting
boolean getShortCircuitLocalReads() {
return shortCircuitLocalReads;
}
} }

View File

@ -460,6 +460,10 @@ public class DFSInputStream extends FSInputStream implements ByteBufferReadable
" for " + blk); " for " + blk);
} }
return chosenNode; return chosenNode;
} catch (AccessControlException ex) {
DFSClient.LOG.warn("Short circuit access failed " + ex);
dfsClient.disableShortCircuit();
continue;
} catch (IOException ex) { } catch (IOException ex) {
if (ex instanceof InvalidEncryptionKeyException && refetchEncryptionKey > 0) { if (ex instanceof InvalidEncryptionKeyException && refetchEncryptionKey > 0) {
DFSClient.LOG.info("Will fetch a new encryption key and retry, " DFSClient.LOG.info("Will fetch a new encryption key and retry, "
@ -806,7 +810,7 @@ public class DFSInputStream extends FSInputStream implements ByteBufferReadable
// we want to remember what we have tried // we want to remember what we have tried
addIntoCorruptedBlockMap(block.getBlock(), chosenNode, corruptedBlockMap); addIntoCorruptedBlockMap(block.getBlock(), chosenNode, corruptedBlockMap);
} catch (AccessControlException ex) { } catch (AccessControlException ex) {
DFSClient.LOG.warn("Short circuit access failed ", ex); DFSClient.LOG.warn("Short circuit access failed " + ex);
dfsClient.disableShortCircuit(); dfsClient.disableShortCircuit();
continue; continue;
} catch (IOException e) { } catch (IOException e) {
@ -885,9 +889,9 @@ public class DFSInputStream extends FSInputStream implements ByteBufferReadable
// Can't local read a block under construction, see HDFS-2757 // Can't local read a block under construction, see HDFS-2757
if (dfsClient.shouldTryShortCircuitRead(dnAddr) && if (dfsClient.shouldTryShortCircuitRead(dnAddr) &&
!blockUnderConstruction()) { !blockUnderConstruction()) {
return DFSClient.getLocalBlockReader(dfsClient.conf, src, block, return DFSClient.getLocalBlockReader(dfsClient.ugi, dfsClient.conf,
blockToken, chosenNode, dfsClient.hdfsTimeout, startOffset, src, block, blockToken, chosenNode, dfsClient.hdfsTimeout,
dfsClient.connectToDnViaHostname()); startOffset, dfsClient.connectToDnViaHostname());
} }
IOException err = null; IOException err = null;
@ -1027,8 +1031,8 @@ public class DFSInputStream extends FSInputStream implements ByteBufferReadable
* only report if the total number of replica is 1. We do not * only report if the total number of replica is 1. We do not
* report otherwise since this maybe due to the client is a handicapped client * report otherwise since this maybe due to the client is a handicapped client
* (who can not read). * (who can not read).
* @param corruptedBlockMap, map of corrupted blocks * @param corruptedBlockMap map of corrupted blocks
* @param dataNodeCount, number of data nodes who contains the block replicas * @param dataNodeCount number of data nodes who contains the block replicas
*/ */
private void reportCheckSumFailure( private void reportCheckSumFailure(
Map<ExtendedBlock, Set<DatanodeInfo>> corruptedBlockMap, Map<ExtendedBlock, Set<DatanodeInfo>> corruptedBlockMap,

View File

@ -67,6 +67,8 @@ import org.apache.hadoop.security.token.SecretManager.InvalidToken;
import org.apache.hadoop.security.token.Token; import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.util.Progressable; import org.apache.hadoop.util.Progressable;
import com.google.common.annotations.VisibleForTesting;
/**************************************************************** /****************************************************************
* Implementation of the abstract FileSystem for the DFS system. * Implementation of the abstract FileSystem for the DFS system.
@ -564,9 +566,8 @@ public class DistributedFileSystem extends FileSystem {
return "DFS[" + dfs + "]"; return "DFS[" + dfs + "]";
} }
/** @deprecated DFSClient should not be accessed directly. */
@InterfaceAudience.Private @InterfaceAudience.Private
@Deprecated @VisibleForTesting
public DFSClient getClient() { public DFSClient getClient() {
return dfs; return dfs;
} }

View File

@ -18,9 +18,11 @@
package org.apache.hadoop.hdfs; package org.apache.hadoop.hdfs;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
@ -32,6 +34,7 @@ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DFSClient.DFSDataInputStream; import org.apache.hadoop.hdfs.DFSClient.DFSDataInputStream;
import org.apache.hadoop.hdfs.protocol.BlockLocalPathInfo; import org.apache.hadoop.hdfs.protocol.BlockLocalPathInfo;
import org.apache.hadoop.hdfs.protocol.ClientDatanodeProtocol; import org.apache.hadoop.hdfs.protocol.ClientDatanodeProtocol;
import org.apache.hadoop.hdfs.protocol.DatanodeID;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo; import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.hdfs.protocol.ExtendedBlock; import org.apache.hadoop.hdfs.protocol.ExtendedBlock;
import org.apache.hadoop.hdfs.protocol.LocatedBlocks; import org.apache.hadoop.hdfs.protocol.LocatedBlocks;
@ -85,9 +88,20 @@ public class TestShortCircuitLocalRead {
} }
} }
} }
private static String getCurrentUser() throws IOException {
return UserGroupInformation.getCurrentUser().getShortUserName();
}
static void checkFileContent(FileSystem fs, Path name, byte[] expected, /** Check file content, reading as user {@code readingUser} */
int readOffset) throws IOException { static void checkFileContent(URI uri, Path name, byte[] expected,
int readOffset, String readingUser, Configuration conf,
boolean shortCircuitFails)
throws IOException, InterruptedException {
// Ensure short circuit is enabled
DistributedFileSystem fs = getFileSystem(readingUser, uri, conf);
assertTrue(fs.getClient().getShortCircuitLocalReads());
FSDataInputStream stm = fs.open(name); FSDataInputStream stm = fs.open(name);
byte[] actual = new byte[expected.length-readOffset]; byte[] actual = new byte[expected.length-readOffset];
stm.readFully(readOffset, actual); stm.readFully(readOffset, actual);
@ -112,6 +126,11 @@ public class TestShortCircuitLocalRead {
nread += nbytes; nread += nbytes;
} }
checkData(actual, readOffset, expected, "Read 3"); checkData(actual, readOffset, expected, "Read 3");
if (shortCircuitFails) {
// short circuit should be disabled due to failure
assertFalse(fs.getClient().getShortCircuitLocalReads());
}
stm.close(); stm.close();
} }
@ -123,11 +142,15 @@ public class TestShortCircuitLocalRead {
return arr; return arr;
} }
/** /** Check the file content, reading as user {@code readingUser} */
* Verifies that reading a file with the direct read(ByteBuffer) api gives the expected set of bytes. static void checkFileContentDirect(URI uri, Path name, byte[] expected,
*/ int readOffset, String readingUser, Configuration conf,
static void checkFileContentDirect(FileSystem fs, Path name, byte[] expected, boolean shortCircuitFails)
int readOffset) throws IOException { throws IOException, InterruptedException {
// Ensure short circuit is enabled
DistributedFileSystem fs = getFileSystem(readingUser, uri, conf);
assertTrue(fs.getClient().getShortCircuitLocalReads());
DFSDataInputStream stm = (DFSDataInputStream)fs.open(name); DFSDataInputStream stm = (DFSDataInputStream)fs.open(name);
ByteBuffer actual = ByteBuffer.allocateDirect(expected.length - readOffset); ByteBuffer actual = ByteBuffer.allocateDirect(expected.length - readOffset);
@ -157,21 +180,33 @@ public class TestShortCircuitLocalRead {
nread += nbytes; nread += nbytes;
} }
checkData(arrayFromByteBuffer(actual), readOffset, expected, "Read 3"); checkData(arrayFromByteBuffer(actual), readOffset, expected, "Read 3");
if (shortCircuitFails) {
// short circuit should be disabled due to failure
assertFalse(fs.getClient().getShortCircuitLocalReads());
}
stm.close(); stm.close();
} }
public void doTestShortCircuitRead(boolean ignoreChecksum, int size,
int readOffset) throws IOException, InterruptedException {
String shortCircuitUser = getCurrentUser();
doTestShortCircuitRead(ignoreChecksum, size, readOffset, shortCircuitUser,
shortCircuitUser, false);
}
/** /**
* Test that file data can be read by reading the block file * Test that file data can be read by reading the block file
* directly from the local store. * directly from the local store.
*/ */
public void doTestShortCircuitRead(boolean ignoreChecksum, int size, public void doTestShortCircuitRead(boolean ignoreChecksum, int size,
int readOffset) throws IOException { int readOffset, String shortCircuitUser, String readingUser,
boolean shortCircuitFails) throws IOException, InterruptedException {
Configuration conf = new Configuration(); Configuration conf = new Configuration();
conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_KEY, true); conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_KEY, true);
conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_SKIP_CHECKSUM_KEY, conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_SKIP_CHECKSUM_KEY,
ignoreChecksum); ignoreChecksum);
conf.set(DFSConfigKeys.DFS_BLOCK_LOCAL_PATH_ACCESS_USER_KEY, conf.set(DFSConfigKeys.DFS_BLOCK_LOCAL_PATH_ACCESS_USER_KEY,
UserGroupInformation.getCurrentUser().getShortUserName()); shortCircuitUser);
if (simulatedStorage) { if (simulatedStorage) {
SimulatedFSDataset.setFactory(conf); SimulatedFSDataset.setFactory(conf);
} }
@ -184,53 +219,88 @@ public class TestShortCircuitLocalRead {
assertTrue("/ should be a directory", fs.getFileStatus(path) assertTrue("/ should be a directory", fs.getFileStatus(path)
.isDirectory() == true); .isDirectory() == true);
byte[] fileData = AppendTestUtil.randomBytes(seed, size);
// create a new file in home directory. Do not close it. // create a new file in home directory. Do not close it.
Path file1 = new Path("filelocal.dat"); byte[] fileData = AppendTestUtil.randomBytes(seed, size);
Path file1 = fs.makeQualified(new Path("filelocal.dat"));
FSDataOutputStream stm = createFile(fs, file1, 1); FSDataOutputStream stm = createFile(fs, file1, 1);
// write to file
stm.write(fileData); stm.write(fileData);
stm.close(); stm.close();
checkFileContent(fs, file1, fileData, readOffset);
checkFileContentDirect(fs, file1, fileData, readOffset); URI uri = cluster.getURI();
checkFileContent(uri, file1, fileData, readOffset, readingUser, conf,
shortCircuitFails);
checkFileContentDirect(uri, file1, fileData, readOffset, readingUser,
conf, shortCircuitFails);
} finally { } finally {
fs.close(); fs.close();
cluster.shutdown(); cluster.shutdown();
} }
} }
@Test @Test(timeout=10000)
public void testFileLocalReadNoChecksum() throws IOException { public void testFileLocalReadNoChecksum() throws Exception {
doTestShortCircuitRead(true, 3*blockSize+100, 0); doTestShortCircuitRead(true, 3*blockSize+100, 0);
} }
@Test @Test(timeout=10000)
public void testFileLocalReadChecksum() throws IOException { public void testFileLocalReadChecksum() throws Exception {
doTestShortCircuitRead(false, 3*blockSize+100, 0); doTestShortCircuitRead(false, 3*blockSize+100, 0);
} }
@Test @Test(timeout=10000)
public void testSmallFileLocalRead() throws IOException { public void testSmallFileLocalRead() throws Exception {
doTestShortCircuitRead(false, 13, 0); doTestShortCircuitRead(false, 13, 0);
doTestShortCircuitRead(false, 13, 5); doTestShortCircuitRead(false, 13, 5);
doTestShortCircuitRead(true, 13, 0); doTestShortCircuitRead(true, 13, 0);
doTestShortCircuitRead(true, 13, 5); doTestShortCircuitRead(true, 13, 5);
} }
@Test /**
public void testReadFromAnOffset() throws IOException { * Try a short circuit from a reader that is not allowed to
* to use short circuit. The test ensures reader falls back to non
* shortcircuit reads when shortcircuit is disallowed.
*/
@Test(timeout=10000)
public void testLocalReadFallback() throws Exception {
doTestShortCircuitRead(true, 13, 0, getCurrentUser(), "notallowed", true);
}
@Test(timeout=10000)
public void testReadFromAnOffset() throws Exception {
doTestShortCircuitRead(false, 3*blockSize+100, 777); doTestShortCircuitRead(false, 3*blockSize+100, 777);
doTestShortCircuitRead(true, 3*blockSize+100, 777); doTestShortCircuitRead(true, 3*blockSize+100, 777);
} }
@Test @Test(timeout=10000)
public void testLongFile() throws IOException { public void testLongFile() throws Exception {
doTestShortCircuitRead(false, 10*blockSize+100, 777); doTestShortCircuitRead(false, 10*blockSize+100, 777);
doTestShortCircuitRead(true, 10*blockSize+100, 777); doTestShortCircuitRead(true, 10*blockSize+100, 777);
} }
@Test private ClientDatanodeProtocol getProxy(UserGroupInformation ugi,
final DatanodeID dnInfo, final Configuration conf) throws IOException,
InterruptedException {
return ugi.doAs(new PrivilegedExceptionAction<ClientDatanodeProtocol>() {
@Override
public ClientDatanodeProtocol run() throws Exception {
return DFSUtil.createClientDatanodeProtocolProxy(dnInfo, conf, 60000,
false);
}
});
}
private static DistributedFileSystem getFileSystem(String user, final URI uri,
final Configuration conf) throws InterruptedException, IOException {
UserGroupInformation ugi = UserGroupInformation.createRemoteUser(user);
return ugi.doAs(new PrivilegedExceptionAction<DistributedFileSystem>() {
@Override
public DistributedFileSystem run() throws Exception {
return (DistributedFileSystem)FileSystem.get(uri, conf);
}
});
}
@Test(timeout=10000)
public void testGetBlockLocalPathInfo() throws IOException, InterruptedException { public void testGetBlockLocalPathInfo() throws IOException, InterruptedException {
final Configuration conf = new Configuration(); final Configuration conf = new Configuration();
conf.set(DFSConfigKeys.DFS_BLOCK_LOCAL_PATH_ACCESS_USER_KEY, conf.set(DFSConfigKeys.DFS_BLOCK_LOCAL_PATH_ACCESS_USER_KEY,
@ -253,15 +323,7 @@ public class TestShortCircuitLocalRead {
ExtendedBlock blk = new ExtendedBlock(lb.get(0).getBlock()); ExtendedBlock blk = new ExtendedBlock(lb.get(0).getBlock());
Token<BlockTokenIdentifier> token = lb.get(0).getBlockToken(); Token<BlockTokenIdentifier> token = lb.get(0).getBlockToken();
final DatanodeInfo dnInfo = lb.get(0).getLocations()[0]; final DatanodeInfo dnInfo = lb.get(0).getLocations()[0];
ClientDatanodeProtocol proxy = aUgi1 ClientDatanodeProtocol proxy = getProxy(aUgi1, dnInfo, conf);
.doAs(new PrivilegedExceptionAction<ClientDatanodeProtocol>() {
@Override
public ClientDatanodeProtocol run() throws Exception {
return DFSUtil.createClientDatanodeProtocolProxy(dnInfo, conf,
60000, false);
}
});
// This should succeed // This should succeed
BlockLocalPathInfo blpi = proxy.getBlockLocalPathInfo(blk, token); BlockLocalPathInfo blpi = proxy.getBlockLocalPathInfo(blk, token);
Assert.assertEquals( Assert.assertEquals(
@ -269,14 +331,7 @@ public class TestShortCircuitLocalRead {
blpi.getBlockPath()); blpi.getBlockPath());
// Try with the other allowed user // Try with the other allowed user
proxy = aUgi2 proxy = getProxy(aUgi2, dnInfo, conf);
.doAs(new PrivilegedExceptionAction<ClientDatanodeProtocol>() {
@Override
public ClientDatanodeProtocol run() throws Exception {
return DFSUtil.createClientDatanodeProtocolProxy(dnInfo, conf,
60000, false);
}
});
// This should succeed as well // This should succeed as well
blpi = proxy.getBlockLocalPathInfo(blk, token); blpi = proxy.getBlockLocalPathInfo(blk, token);
@ -287,14 +342,7 @@ public class TestShortCircuitLocalRead {
// Now try with a disallowed user // Now try with a disallowed user
UserGroupInformation bUgi = UserGroupInformation UserGroupInformation bUgi = UserGroupInformation
.createRemoteUser("notalloweduser"); .createRemoteUser("notalloweduser");
proxy = bUgi proxy = getProxy(bUgi, dnInfo, conf);
.doAs(new PrivilegedExceptionAction<ClientDatanodeProtocol>() {
@Override
public ClientDatanodeProtocol run() throws Exception {
return DFSUtil.createClientDatanodeProtocolProxy(dnInfo, conf,
60000, false);
}
});
try { try {
proxy.getBlockLocalPathInfo(blk, token); proxy.getBlockLocalPathInfo(blk, token);
Assert.fail("The call should have failed as " + bUgi.getShortUserName() Assert.fail("The call should have failed as " + bUgi.getShortUserName()
@ -309,14 +357,14 @@ public class TestShortCircuitLocalRead {
} }
} }
@Test @Test(timeout=10000)
public void testSkipWithVerifyChecksum() throws IOException { public void testSkipWithVerifyChecksum() throws IOException {
int size = blockSize; int size = blockSize;
Configuration conf = new Configuration(); Configuration conf = new Configuration();
conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_KEY, true); conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_KEY, true);
conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_SKIP_CHECKSUM_KEY, false); conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_SKIP_CHECKSUM_KEY, false);
conf.set(DFSConfigKeys.DFS_BLOCK_LOCAL_PATH_ACCESS_USER_KEY, conf.set(DFSConfigKeys.DFS_BLOCK_LOCAL_PATH_ACCESS_USER_KEY,
UserGroupInformation.getCurrentUser().getShortUserName()); getCurrentUser());
if (simulatedStorage) { if (simulatedStorage) {
SimulatedFSDataset.setFactory(conf); SimulatedFSDataset.setFactory(conf);
} }
@ -356,7 +404,7 @@ public class TestShortCircuitLocalRead {
} }
/** /**
* Test to run benchmarks between shortcircuit read vs regular read with * Test to run benchmarks between short circuit read vs regular read with
* specified number of threads simultaneously reading. * specified number of threads simultaneously reading.
* <br> * <br>
* Run this using the following command: * Run this using the following command:
@ -374,7 +422,7 @@ public class TestShortCircuitLocalRead {
int threadCount = Integer.valueOf(args[2]); int threadCount = Integer.valueOf(args[2]);
// Setup create a file // Setup create a file
Configuration conf = new Configuration(); final Configuration conf = new Configuration();
conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_KEY, shortcircuit); conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_KEY, shortcircuit);
conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_SKIP_CHECKSUM_KEY, conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_SKIP_CHECKSUM_KEY,
checksum); checksum);
@ -400,9 +448,13 @@ public class TestShortCircuitLocalRead {
public void run() { public void run() {
for (int i = 0; i < iteration; i++) { for (int i = 0; i < iteration; i++) {
try { try {
checkFileContent(fs, file1, dataToWrite, 0); String user = getCurrentUser();
checkFileContent(fs.getUri(), file1, dataToWrite, 0, user, conf,
true);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} }
} }
} }