InjectionHandler.processEventIO(InjectionEvent.DATANODE_APPEND_BLOCK);
// Read in the header
long startTime = System.currentTimeMillis();
AppendBlockHeader headerToReceive = new AppendBlockHeader(versionAndOpcode);
headerToReceive.readFields(in);
int namespaceid = headerToReceive.getNamespaceId();
Block block = new Block(headerToReceive.getBlockId(),
headerToReceive.getNumBytes(), headerToReceive.getGenStamp());
if (LOG.isInfoEnabled()) {
if (remoteAddress == null) {
getAddresses();
}
LOG.info("Receiving block " + block +
" src: " + remoteAddress +
" dest: " + localAddress);
}
int pipelineSize = headerToReceive.getPipelineDepth();
String client = headerToReceive.getWritePipelineInfo().getClientName();
boolean hasSrcDataNode = headerToReceive.getWritePipelineInfo()
.hasSrcDataNode();
if (hasSrcDataNode) {
srcDataNode = headerToReceive.getWritePipelineInfo().getSrcDataNode();
}
int numTargets = headerToReceive.getWritePipelineInfo().getNumTargets();
DatanodeInfo targets[] = headerToReceive.getWritePipelineInfo().getNodes();
DataOutputStream mirrorOut = null; // stream to next target
DataInputStream mirrorIn = null; // reply from next target
DataOutputStream replyOut = null; // stream to prev target
Socket mirrorSock = null; // socket to next target
BlockReceiver blockReceiver = null; // responsible for data handling
String mirrorNode = null; // the name:port of next target
String firstBadLink = ""; // first datanode that failed in connection setup
updateCurrentThreadName("receiving append block " + block + " client=" + client);
try {
// update the block
Block oldBlock = new Block(headerToReceive.getBlockId());
oldBlock = datanode.getBlockInfo(namespaceid, oldBlock);
boolean isSecondary = (targets.length + 1 != pipelineSize);
// open a block receiver and check if the block does not exist
// append doesn't support per block fadvise
blockReceiver = new BlockReceiver(namespaceid, oldBlock, block, in,
s.getRemoteSocketAddress().toString(),
s.getLocalSocketAddress().toString(),
true, client, srcDataNode, datanode, isSecondary, 0, false,
versionAndOpcode.getDataTransferVersion() >=
DataTransferProtocol.PACKET_INCLUDE_VERSION_VERSION,
headerToReceive.getWritePipelineInfo().getWriteOptions().getSyncFileRange());
// get a connection back to the previous target
replyOut = new DataOutputStream(new BufferedOutputStream(
NetUtils.getOutputStream(s, datanode.socketWriteTimeout),
SMALL_BUFFER_SIZE));
//
// Open network conn to backup machine, if
// appropriate
//
if (targets.length > 0) {
InetSocketAddress mirrorTarget = null;
// Connect to backup machine
mirrorNode = targets[0].getName();
mirrorTarget = NetUtils.createSocketAddr(mirrorNode);
mirrorSock = datanode.newSocket();
try {
int timeoutValue = datanode.socketTimeout +
(datanode.socketReadExtentionTimeout * numTargets);
int writeTimeout = datanode.socketWriteTimeout +
(datanode.socketWriteExtentionTimeout * numTargets);
NetUtils.connect(mirrorSock, mirrorTarget, timeoutValue);
mirrorSock.setSoTimeout(timeoutValue);
mirrorSock.setSendBufferSize(DEFAULT_DATA_SOCKET_SIZE);
mirrorOut = new DataOutputStream(
new BufferedOutputStream(
NetUtils.getOutputStream(mirrorSock, writeTimeout),
SMALL_BUFFER_SIZE));
mirrorIn = new DataInputStream(NetUtils.getInputStream(mirrorSock));
// Write header: Copied from DFSClient.java!
AppendBlockHeader headerToSend = new AppendBlockHeader(
versionAndOpcode.getDataTransferVersion(), namespaceid,
block.getBlockId(), block.getNumBytes(), block.getGenerationStamp(), pipelineSize,
hasSrcDataNode, srcDataNode, targets.length - 1, targets,
client);
headerToSend.writeVersionAndOpCode(mirrorOut);
headerToSend.write(mirrorOut);
blockReceiver.writeChecksumHeader(mirrorOut);
mirrorOut.flush();
// read connect ack (only for clients, not for replication req)
if (client.length() != 0) {