|
@@ -39,6 +39,7 @@ import java.nio.channels.ClosedChannelException;
|
|
import java.util.Arrays;
|
|
import java.util.Arrays;
|
|
|
|
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.Log;
|
|
|
|
+import org.apache.hadoop.hdfs.net.Peer;
|
|
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.HdfsConstants;
|
|
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
|
|
@@ -64,7 +65,6 @@ import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration;
|
|
import org.apache.hadoop.io.IOUtils;
|
|
import org.apache.hadoop.io.IOUtils;
|
|
import org.apache.hadoop.io.MD5Hash;
|
|
import org.apache.hadoop.io.MD5Hash;
|
|
import org.apache.hadoop.net.NetUtils;
|
|
import org.apache.hadoop.net.NetUtils;
|
|
-import org.apache.hadoop.net.SocketInputWrapper;
|
|
|
|
import org.apache.hadoop.security.token.SecretManager.InvalidToken;
|
|
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.DataChecksum;
|
|
import org.apache.hadoop.util.DataChecksum;
|
|
@@ -79,8 +79,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
public static final Log LOG = DataNode.LOG;
|
|
public static final Log LOG = DataNode.LOG;
|
|
static final Log ClientTraceLog = DataNode.ClientTraceLog;
|
|
static final Log ClientTraceLog = DataNode.ClientTraceLog;
|
|
|
|
|
|
- private final Socket s;
|
|
|
|
- private final boolean isLocal; //is a local connection?
|
|
|
|
|
|
+ private final Peer peer;
|
|
private final String remoteAddress; // address of remote side
|
|
private final String remoteAddress; // address of remote side
|
|
private final String localAddress; // local address of this daemon
|
|
private final String localAddress; // local address of this daemon
|
|
private final DataNode datanode;
|
|
private final DataNode datanode;
|
|
@@ -88,7 +87,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
private final DataXceiverServer dataXceiverServer;
|
|
private final DataXceiverServer dataXceiverServer;
|
|
private final boolean connectToDnViaHostname;
|
|
private final boolean connectToDnViaHostname;
|
|
private long opStartTime; //the start time of receiving an Op
|
|
private long opStartTime; //the start time of receiving an Op
|
|
- private final SocketInputWrapper socketIn;
|
|
|
|
|
|
+ private final InputStream socketIn;
|
|
private OutputStream socketOut;
|
|
private OutputStream socketOut;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -97,25 +96,23 @@ class DataXceiver extends Receiver implements Runnable {
|
|
*/
|
|
*/
|
|
private String previousOpClientName;
|
|
private String previousOpClientName;
|
|
|
|
|
|
- public static DataXceiver create(Socket s, DataNode dn,
|
|
|
|
|
|
+ public static DataXceiver create(Peer peer, DataNode dn,
|
|
DataXceiverServer dataXceiverServer) throws IOException {
|
|
DataXceiverServer dataXceiverServer) throws IOException {
|
|
- return new DataXceiver(s, dn, dataXceiverServer);
|
|
|
|
|
|
+ return new DataXceiver(peer, dn, dataXceiverServer);
|
|
}
|
|
}
|
|
|
|
|
|
- private DataXceiver(Socket s,
|
|
|
|
- DataNode datanode,
|
|
|
|
|
|
+ private DataXceiver(Peer peer, DataNode datanode,
|
|
DataXceiverServer dataXceiverServer) throws IOException {
|
|
DataXceiverServer dataXceiverServer) throws IOException {
|
|
|
|
|
|
- this.s = s;
|
|
|
|
|
|
+ this.peer = peer;
|
|
this.dnConf = datanode.getDnConf();
|
|
this.dnConf = datanode.getDnConf();
|
|
- this.socketIn = NetUtils.getInputStream(s);
|
|
|
|
- this.socketOut = NetUtils.getOutputStream(s, dnConf.socketWriteTimeout);
|
|
|
|
- this.isLocal = s.getInetAddress().equals(s.getLocalAddress());
|
|
|
|
|
|
+ this.socketIn = peer.getInputStream();
|
|
|
|
+ this.socketOut = peer.getOutputStream();
|
|
this.datanode = datanode;
|
|
this.datanode = datanode;
|
|
this.dataXceiverServer = dataXceiverServer;
|
|
this.dataXceiverServer = dataXceiverServer;
|
|
this.connectToDnViaHostname = datanode.getDnConf().connectToDnViaHostname;
|
|
this.connectToDnViaHostname = datanode.getDnConf().connectToDnViaHostname;
|
|
- remoteAddress = s.getRemoteSocketAddress().toString();
|
|
|
|
- localAddress = s.getLocalSocketAddress().toString();
|
|
|
|
|
|
+ remoteAddress = peer.getRemoteAddressString();
|
|
|
|
+ localAddress = peer.getLocalAddressString();
|
|
|
|
|
|
if (LOG.isDebugEnabled()) {
|
|
if (LOG.isDebugEnabled()) {
|
|
LOG.debug("Number of active connections is: "
|
|
LOG.debug("Number of active connections is: "
|
|
@@ -155,11 +152,10 @@ class DataXceiver extends Receiver implements Runnable {
|
|
public void run() {
|
|
public void run() {
|
|
int opsProcessed = 0;
|
|
int opsProcessed = 0;
|
|
Op op = null;
|
|
Op op = null;
|
|
-
|
|
|
|
- dataXceiverServer.childSockets.add(s);
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ dataXceiverServer.addPeer(peer);
|
|
try {
|
|
try {
|
|
-
|
|
|
|
|
|
+ peer.setWriteTimeout(datanode.getDnConf().socketWriteTimeout);
|
|
InputStream input = socketIn;
|
|
InputStream input = socketIn;
|
|
if (dnConf.encryptDataTransfer) {
|
|
if (dnConf.encryptDataTransfer) {
|
|
IOStreamPair encryptedStreams = null;
|
|
IOStreamPair encryptedStreams = null;
|
|
@@ -169,8 +165,9 @@ class DataXceiver extends Receiver implements Runnable {
|
|
dnConf.encryptionAlgorithm);
|
|
dnConf.encryptionAlgorithm);
|
|
} catch (InvalidMagicNumberException imne) {
|
|
} catch (InvalidMagicNumberException imne) {
|
|
LOG.info("Failed to read expected encryption handshake from client " +
|
|
LOG.info("Failed to read expected encryption handshake from client " +
|
|
- "at " + s.getInetAddress() + ". Perhaps the client is running an " +
|
|
|
|
- "older version of Hadoop which does not support encryption");
|
|
|
|
|
|
+ "at " + peer.getRemoteAddressString() + ". Perhaps the client " +
|
|
|
|
+ "is running an older version of Hadoop which does not support " +
|
|
|
|
+ "encryption");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
input = encryptedStreams.in;
|
|
input = encryptedStreams.in;
|
|
@@ -189,9 +186,9 @@ class DataXceiver extends Receiver implements Runnable {
|
|
try {
|
|
try {
|
|
if (opsProcessed != 0) {
|
|
if (opsProcessed != 0) {
|
|
assert dnConf.socketKeepaliveTimeout > 0;
|
|
assert dnConf.socketKeepaliveTimeout > 0;
|
|
- socketIn.setTimeout(dnConf.socketKeepaliveTimeout);
|
|
|
|
|
|
+ peer.setReadTimeout(dnConf.socketKeepaliveTimeout);
|
|
} else {
|
|
} else {
|
|
- socketIn.setTimeout(dnConf.socketTimeout);
|
|
|
|
|
|
+ peer.setReadTimeout(dnConf.socketTimeout);
|
|
}
|
|
}
|
|
op = readOp();
|
|
op = readOp();
|
|
} catch (InterruptedIOException ignored) {
|
|
} catch (InterruptedIOException ignored) {
|
|
@@ -202,7 +199,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
if (opsProcessed > 0 &&
|
|
if (opsProcessed > 0 &&
|
|
(err instanceof EOFException || err instanceof ClosedChannelException)) {
|
|
(err instanceof EOFException || err instanceof ClosedChannelException)) {
|
|
if (LOG.isDebugEnabled()) {
|
|
if (LOG.isDebugEnabled()) {
|
|
- LOG.debug("Cached " + s.toString() + " closing after " + opsProcessed + " ops");
|
|
|
|
|
|
+ LOG.debug("Cached " + peer + " closing after " + opsProcessed + " ops");
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
throw err;
|
|
throw err;
|
|
@@ -212,13 +209,13 @@ class DataXceiver extends Receiver implements Runnable {
|
|
|
|
|
|
// restore normal timeout
|
|
// restore normal timeout
|
|
if (opsProcessed != 0) {
|
|
if (opsProcessed != 0) {
|
|
- s.setSoTimeout(dnConf.socketTimeout);
|
|
|
|
|
|
+ peer.setReadTimeout(dnConf.socketTimeout);
|
|
}
|
|
}
|
|
|
|
|
|
opStartTime = now();
|
|
opStartTime = now();
|
|
processOp(op);
|
|
processOp(op);
|
|
++opsProcessed;
|
|
++opsProcessed;
|
|
- } while (!s.isClosed() && dnConf.socketKeepaliveTimeout > 0);
|
|
|
|
|
|
+ } while (!peer.isClosed() && dnConf.socketKeepaliveTimeout > 0);
|
|
} catch (Throwable t) {
|
|
} catch (Throwable t) {
|
|
LOG.error(datanode.getDisplayName() + ":DataXceiver error processing " +
|
|
LOG.error(datanode.getDisplayName() + ":DataXceiver error processing " +
|
|
((op == null) ? "unknown" : op.name()) + " operation " +
|
|
((op == null) ? "unknown" : op.name()) + " operation " +
|
|
@@ -230,9 +227,8 @@ class DataXceiver extends Receiver implements Runnable {
|
|
+ datanode.getXceiverCount());
|
|
+ datanode.getXceiverCount());
|
|
}
|
|
}
|
|
updateCurrentThreadName("Cleaning up");
|
|
updateCurrentThreadName("Cleaning up");
|
|
|
|
+ dataXceiverServer.closePeer(peer);
|
|
IOUtils.closeStream(in);
|
|
IOUtils.closeStream(in);
|
|
- IOUtils.closeSocket(s);
|
|
|
|
- dataXceiverServer.childSockets.remove(s);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -286,8 +282,9 @@ class DataXceiver extends Receiver implements Runnable {
|
|
ClientReadStatusProto stat = ClientReadStatusProto.parseFrom(
|
|
ClientReadStatusProto stat = ClientReadStatusProto.parseFrom(
|
|
HdfsProtoUtil.vintPrefixed(in));
|
|
HdfsProtoUtil.vintPrefixed(in));
|
|
if (!stat.hasStatus()) {
|
|
if (!stat.hasStatus()) {
|
|
- LOG.warn("Client " + s.getInetAddress() + " did not send a valid status " +
|
|
|
|
- "code after reading. Will close connection.");
|
|
|
|
|
|
+ LOG.warn("Client " + peer.getRemoteAddressString() +
|
|
|
|
+ " did not send a valid status code after reading. " +
|
|
|
|
+ "Will close connection.");
|
|
IOUtils.closeStream(out);
|
|
IOUtils.closeStream(out);
|
|
}
|
|
}
|
|
} catch (IOException ioe) {
|
|
} catch (IOException ioe) {
|
|
@@ -320,7 +317,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
|
|
|
|
//update metrics
|
|
//update metrics
|
|
datanode.metrics.addReadBlockOp(elapsed());
|
|
datanode.metrics.addReadBlockOp(elapsed());
|
|
- datanode.metrics.incrReadsFromClient(isLocal);
|
|
|
|
|
|
+ datanode.metrics.incrReadsFromClient(peer.isLocal());
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -358,8 +355,8 @@ class DataXceiver extends Receiver implements Runnable {
|
|
LOG.debug("isDatanode=" + isDatanode
|
|
LOG.debug("isDatanode=" + isDatanode
|
|
+ ", isClient=" + isClient
|
|
+ ", isClient=" + isClient
|
|
+ ", isTransfer=" + isTransfer);
|
|
+ ", isTransfer=" + isTransfer);
|
|
- LOG.debug("writeBlock receive buf size " + s.getReceiveBufferSize() +
|
|
|
|
- " tcp no delay " + s.getTcpNoDelay());
|
|
|
|
|
|
+ LOG.debug("writeBlock receive buf size " + peer.getReceiveBufferSize() +
|
|
|
|
+ " tcp no delay " + peer.getTcpNoDelay());
|
|
}
|
|
}
|
|
|
|
|
|
// We later mutate block's generation stamp and length, but we need to
|
|
// We later mutate block's generation stamp and length, but we need to
|
|
@@ -390,8 +387,8 @@ class DataXceiver extends Receiver implements Runnable {
|
|
stage != BlockConstructionStage.PIPELINE_CLOSE_RECOVERY) {
|
|
stage != BlockConstructionStage.PIPELINE_CLOSE_RECOVERY) {
|
|
// open a block receiver
|
|
// open a block receiver
|
|
blockReceiver = new BlockReceiver(block, in,
|
|
blockReceiver = new BlockReceiver(block, in,
|
|
- s.getRemoteSocketAddress().toString(),
|
|
|
|
- s.getLocalSocketAddress().toString(),
|
|
|
|
|
|
+ peer.getRemoteAddressString(),
|
|
|
|
+ peer.getLocalAddressString(),
|
|
stage, latestGenerationStamp, minBytesRcvd, maxBytesRcvd,
|
|
stage, latestGenerationStamp, minBytesRcvd, maxBytesRcvd,
|
|
clientname, srcDataNode, datanode, requestedChecksum);
|
|
clientname, srcDataNode, datanode, requestedChecksum);
|
|
} else {
|
|
} else {
|
|
@@ -546,7 +543,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
|
|
|
|
//update metrics
|
|
//update metrics
|
|
datanode.metrics.addWriteBlockOp(elapsed());
|
|
datanode.metrics.addWriteBlockOp(elapsed());
|
|
- datanode.metrics.incrWritesFromClient(isLocal);
|
|
|
|
|
|
+ datanode.metrics.incrWritesFromClient(peer.isLocal());
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -554,7 +551,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
final Token<BlockTokenIdentifier> blockToken,
|
|
final Token<BlockTokenIdentifier> blockToken,
|
|
final String clientName,
|
|
final String clientName,
|
|
final DatanodeInfo[] targets) throws IOException {
|
|
final DatanodeInfo[] targets) throws IOException {
|
|
- checkAccess(null, true, blk, blockToken,
|
|
|
|
|
|
+ checkAccess(socketOut, true, blk, blockToken,
|
|
Op.TRANSFER_BLOCK, BlockTokenSecretManager.AccessMode.COPY);
|
|
Op.TRANSFER_BLOCK, BlockTokenSecretManager.AccessMode.COPY);
|
|
previousOpClientName = clientName;
|
|
previousOpClientName = clientName;
|
|
updateCurrentThreadName(Op.TRANSFER_BLOCK + " " + blk);
|
|
updateCurrentThreadName(Op.TRANSFER_BLOCK + " " + blk);
|
|
@@ -641,8 +638,9 @@ class DataXceiver extends Receiver implements Runnable {
|
|
}
|
|
}
|
|
|
|
|
|
if (!dataXceiverServer.balanceThrottler.acquire()) { // not able to start
|
|
if (!dataXceiverServer.balanceThrottler.acquire()) { // not able to start
|
|
- String msg = "Not able to copy block " + block.getBlockId() + " to "
|
|
|
|
- + s.getRemoteSocketAddress() + " because threads quota is exceeded.";
|
|
|
|
|
|
+ String msg = "Not able to copy block " + block.getBlockId() + " " +
|
|
|
|
+ "to " + peer.getRemoteAddressString() + " because threads " +
|
|
|
|
+ "quota is exceeded.";
|
|
LOG.info(msg);
|
|
LOG.info(msg);
|
|
sendResponse(ERROR, msg);
|
|
sendResponse(ERROR, msg);
|
|
return;
|
|
return;
|
|
@@ -671,7 +669,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
datanode.metrics.incrBytesRead((int) read);
|
|
datanode.metrics.incrBytesRead((int) read);
|
|
datanode.metrics.incrBlocksRead();
|
|
datanode.metrics.incrBlocksRead();
|
|
|
|
|
|
- LOG.info("Copied " + block + " to " + s.getRemoteSocketAddress());
|
|
|
|
|
|
+ LOG.info("Copied " + block + " to " + peer.getRemoteAddressString());
|
|
} catch (IOException ioe) {
|
|
} catch (IOException ioe) {
|
|
isOpSuccess = false;
|
|
isOpSuccess = false;
|
|
LOG.info("opCopyBlock " + block + " received exception " + ioe);
|
|
LOG.info("opCopyBlock " + block + " received exception " + ioe);
|
|
@@ -716,8 +714,9 @@ class DataXceiver extends Receiver implements Runnable {
|
|
}
|
|
}
|
|
|
|
|
|
if (!dataXceiverServer.balanceThrottler.acquire()) { // not able to start
|
|
if (!dataXceiverServer.balanceThrottler.acquire()) { // not able to start
|
|
- String msg = "Not able to receive block " + block.getBlockId() + " from "
|
|
|
|
- + s.getRemoteSocketAddress() + " because threads quota is exceeded.";
|
|
|
|
|
|
+ String msg = "Not able to receive block " + block.getBlockId() +
|
|
|
|
+ " from " + peer.getRemoteAddressString() + " because threads " +
|
|
|
|
+ "quota is exceeded.";
|
|
LOG.warn(msg);
|
|
LOG.warn(msg);
|
|
sendResponse(ERROR, msg);
|
|
sendResponse(ERROR, msg);
|
|
return;
|
|
return;
|
|
@@ -794,7 +793,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
// notify name node
|
|
// notify name node
|
|
datanode.notifyNamenodeReceivedBlock(block, delHint);
|
|
datanode.notifyNamenodeReceivedBlock(block, delHint);
|
|
|
|
|
|
- LOG.info("Moved " + block + " from " + s.getRemoteSocketAddress());
|
|
|
|
|
|
+ LOG.info("Moved " + block + " from " + peer.getRemoteAddressString());
|
|
|
|
|
|
} catch (IOException ioe) {
|
|
} catch (IOException ioe) {
|
|
opStatus = ERROR;
|
|
opStatus = ERROR;
|
|
@@ -817,7 +816,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
try {
|
|
try {
|
|
sendResponse(opStatus, errMsg);
|
|
sendResponse(opStatus, errMsg);
|
|
} catch (IOException ioe) {
|
|
} catch (IOException ioe) {
|
|
- LOG.warn("Error writing reply back to " + s.getRemoteSocketAddress());
|
|
|
|
|
|
+ LOG.warn("Error writing reply back to " + peer.getRemoteAddressString());
|
|
}
|
|
}
|
|
IOUtils.closeStream(proxyOut);
|
|
IOUtils.closeStream(proxyOut);
|
|
IOUtils.closeStream(blockReceiver);
|
|
IOUtils.closeStream(blockReceiver);
|
|
@@ -871,7 +870,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
- private void checkAccess(DataOutputStream out, final boolean reply,
|
|
|
|
|
|
+ private void checkAccess(OutputStream out, final boolean reply,
|
|
final ExtendedBlock blk,
|
|
final ExtendedBlock blk,
|
|
final Token<BlockTokenIdentifier> t,
|
|
final Token<BlockTokenIdentifier> t,
|
|
final Op op,
|
|
final Op op,
|
|
@@ -886,11 +885,6 @@ class DataXceiver extends Receiver implements Runnable {
|
|
} catch(InvalidToken e) {
|
|
} catch(InvalidToken e) {
|
|
try {
|
|
try {
|
|
if (reply) {
|
|
if (reply) {
|
|
- if (out == null) {
|
|
|
|
- out = new DataOutputStream(
|
|
|
|
- NetUtils.getOutputStream(s, dnConf.socketWriteTimeout));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
BlockOpResponseProto.Builder resp = BlockOpResponseProto.newBuilder()
|
|
BlockOpResponseProto.Builder resp = BlockOpResponseProto.newBuilder()
|
|
.setStatus(ERROR_ACCESS_TOKEN);
|
|
.setStatus(ERROR_ACCESS_TOKEN);
|
|
if (mode == BlockTokenSecretManager.AccessMode.WRITE) {
|
|
if (mode == BlockTokenSecretManager.AccessMode.WRITE) {
|