|
@@ -1007,7 +1007,6 @@ class DataXceiver extends Receiver implements Runnable {
|
|
|
updateCurrentThreadName("Replacing block " + block + " from " + delHint);
|
|
|
|
|
|
/* read header */
|
|
|
- block.setNumBytes(dataXceiverServer.estimateBlockSize);
|
|
|
if (datanode.isBlockTokenEnabled) {
|
|
|
try {
|
|
|
datanode.blockPoolTokenSecretManager.checkAccess(blockToken, null, block,
|
|
@@ -1039,73 +1038,83 @@ class DataXceiver extends Receiver implements Runnable {
|
|
|
DataOutputStream replyOut = new DataOutputStream(getOutputStream());
|
|
|
boolean IoeDuringCopyBlockOperation = false;
|
|
|
try {
|
|
|
- // get the output stream to the proxy
|
|
|
- final String dnAddr = proxySource.getXferAddr(connectToDnViaHostname);
|
|
|
- if (LOG.isDebugEnabled()) {
|
|
|
- LOG.debug("Connecting to datanode " + dnAddr);
|
|
|
- }
|
|
|
- InetSocketAddress proxyAddr = NetUtils.createSocketAddr(dnAddr);
|
|
|
- proxySock = datanode.newSocket();
|
|
|
- NetUtils.connect(proxySock, proxyAddr, dnConf.socketTimeout);
|
|
|
- proxySock.setSoTimeout(dnConf.socketTimeout);
|
|
|
-
|
|
|
- OutputStream unbufProxyOut = NetUtils.getOutputStream(proxySock,
|
|
|
- dnConf.socketWriteTimeout);
|
|
|
- InputStream unbufProxyIn = NetUtils.getInputStream(proxySock);
|
|
|
- DataEncryptionKeyFactory keyFactory =
|
|
|
- datanode.getDataEncryptionKeyFactoryForBlock(block);
|
|
|
- IOStreamPair saslStreams = datanode.saslClient.socketSend(proxySock,
|
|
|
- unbufProxyOut, unbufProxyIn, keyFactory, blockToken, proxySource);
|
|
|
- unbufProxyOut = saslStreams.out;
|
|
|
- unbufProxyIn = saslStreams.in;
|
|
|
-
|
|
|
- proxyOut = new DataOutputStream(new BufferedOutputStream(unbufProxyOut,
|
|
|
- HdfsConstants.SMALL_BUFFER_SIZE));
|
|
|
- proxyReply = new DataInputStream(new BufferedInputStream(unbufProxyIn,
|
|
|
- HdfsConstants.IO_FILE_BUFFER_SIZE));
|
|
|
-
|
|
|
- /* send request to the proxy */
|
|
|
- IoeDuringCopyBlockOperation = true;
|
|
|
- new Sender(proxyOut).copyBlock(block, blockToken);
|
|
|
- IoeDuringCopyBlockOperation = false;
|
|
|
-
|
|
|
- // receive the response from the proxy
|
|
|
-
|
|
|
- BlockOpResponseProto copyResponse = BlockOpResponseProto.parseFrom(
|
|
|
- PBHelper.vintPrefixed(proxyReply));
|
|
|
-
|
|
|
- if (copyResponse.getStatus() != SUCCESS) {
|
|
|
- if (copyResponse.getStatus() == ERROR_ACCESS_TOKEN) {
|
|
|
+ // Move the block to different storage in the same datanode
|
|
|
+ if (proxySource.equals(datanode.getDatanodeId())) {
|
|
|
+ ReplicaInfo oldReplica = datanode.data.moveBlockAcrossStorage(block,
|
|
|
+ storageType);
|
|
|
+ if (oldReplica != null) {
|
|
|
+ LOG.info("Moved " + block + " from StorageType "
|
|
|
+ + oldReplica.getVolume().getStorageType() + " to " + storageType);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ block.setNumBytes(dataXceiverServer.estimateBlockSize);
|
|
|
+ // get the output stream to the proxy
|
|
|
+ final String dnAddr = proxySource.getXferAddr(connectToDnViaHostname);
|
|
|
+ if (LOG.isDebugEnabled()) {
|
|
|
+ LOG.debug("Connecting to datanode " + dnAddr);
|
|
|
+ }
|
|
|
+ InetSocketAddress proxyAddr = NetUtils.createSocketAddr(dnAddr);
|
|
|
+ proxySock = datanode.newSocket();
|
|
|
+ NetUtils.connect(proxySock, proxyAddr, dnConf.socketTimeout);
|
|
|
+ proxySock.setSoTimeout(dnConf.socketTimeout);
|
|
|
+
|
|
|
+ OutputStream unbufProxyOut = NetUtils.getOutputStream(proxySock,
|
|
|
+ dnConf.socketWriteTimeout);
|
|
|
+ InputStream unbufProxyIn = NetUtils.getInputStream(proxySock);
|
|
|
+ DataEncryptionKeyFactory keyFactory =
|
|
|
+ datanode.getDataEncryptionKeyFactoryForBlock(block);
|
|
|
+ IOStreamPair saslStreams = datanode.saslClient.socketSend(proxySock,
|
|
|
+ unbufProxyOut, unbufProxyIn, keyFactory, blockToken, proxySource);
|
|
|
+ unbufProxyOut = saslStreams.out;
|
|
|
+ unbufProxyIn = saslStreams.in;
|
|
|
+
|
|
|
+ proxyOut = new DataOutputStream(new BufferedOutputStream(unbufProxyOut,
|
|
|
+ HdfsConstants.SMALL_BUFFER_SIZE));
|
|
|
+ proxyReply = new DataInputStream(new BufferedInputStream(unbufProxyIn,
|
|
|
+ HdfsConstants.IO_FILE_BUFFER_SIZE));
|
|
|
+
|
|
|
+ /* send request to the proxy */
|
|
|
+ IoeDuringCopyBlockOperation = true;
|
|
|
+ new Sender(proxyOut).copyBlock(block, blockToken);
|
|
|
+ IoeDuringCopyBlockOperation = false;
|
|
|
+
|
|
|
+ // receive the response from the proxy
|
|
|
+
|
|
|
+ BlockOpResponseProto copyResponse = BlockOpResponseProto.parseFrom(
|
|
|
+ PBHelper.vintPrefixed(proxyReply));
|
|
|
+
|
|
|
+ if (copyResponse.getStatus() != SUCCESS) {
|
|
|
+ if (copyResponse.getStatus() == ERROR_ACCESS_TOKEN) {
|
|
|
+ throw new IOException("Copy block " + block + " from "
|
|
|
+ + proxySock.getRemoteSocketAddress()
|
|
|
+ + " failed due to access token error");
|
|
|
+ }
|
|
|
throw new IOException("Copy block " + block + " from "
|
|
|
- + proxySock.getRemoteSocketAddress()
|
|
|
- + " failed due to access token error");
|
|
|
+ + proxySock.getRemoteSocketAddress() + " failed");
|
|
|
}
|
|
|
- throw new IOException("Copy block " + block + " from "
|
|
|
- + proxySock.getRemoteSocketAddress() + " failed");
|
|
|
+
|
|
|
+ // get checksum info about the block we're copying
|
|
|
+ ReadOpChecksumInfoProto checksumInfo = copyResponse.getReadOpChecksumInfo();
|
|
|
+ DataChecksum remoteChecksum = DataTransferProtoUtil.fromProto(
|
|
|
+ checksumInfo.getChecksum());
|
|
|
+ // open a block receiver and check if the block does not exist
|
|
|
+ blockReceiver = new BlockReceiver(block, storageType,
|
|
|
+ proxyReply, proxySock.getRemoteSocketAddress().toString(),
|
|
|
+ proxySock.getLocalSocketAddress().toString(),
|
|
|
+ null, 0, 0, 0, "", null, datanode, remoteChecksum,
|
|
|
+ CachingStrategy.newDropBehind(), false);
|
|
|
+
|
|
|
+ // receive a block
|
|
|
+ blockReceiver.receiveBlock(null, null, replyOut, null,
|
|
|
+ dataXceiverServer.balanceThrottler, null, true);
|
|
|
+
|
|
|
+ // notify name node
|
|
|
+ datanode.notifyNamenodeReceivedBlock(
|
|
|
+ block, delHint, blockReceiver.getStorageUuid());
|
|
|
+
|
|
|
+ LOG.info("Moved " + block + " from " + peer.getRemoteAddressString()
|
|
|
+ + ", delHint=" + delHint);
|
|
|
}
|
|
|
-
|
|
|
- // get checksum info about the block we're copying
|
|
|
- ReadOpChecksumInfoProto checksumInfo = copyResponse.getReadOpChecksumInfo();
|
|
|
- DataChecksum remoteChecksum = DataTransferProtoUtil.fromProto(
|
|
|
- checksumInfo.getChecksum());
|
|
|
- // open a block receiver and check if the block does not exist
|
|
|
- blockReceiver = new BlockReceiver(block, storageType,
|
|
|
- proxyReply, proxySock.getRemoteSocketAddress().toString(),
|
|
|
- proxySock.getLocalSocketAddress().toString(),
|
|
|
- null, 0, 0, 0, "", null, datanode, remoteChecksum,
|
|
|
- CachingStrategy.newDropBehind(), false);
|
|
|
-
|
|
|
- // receive a block
|
|
|
- blockReceiver.receiveBlock(null, null, replyOut, null,
|
|
|
- dataXceiverServer.balanceThrottler, null, true);
|
|
|
-
|
|
|
- // notify name node
|
|
|
- datanode.notifyNamenodeReceivedBlock(
|
|
|
- block, delHint, blockReceiver.getStorageUuid());
|
|
|
-
|
|
|
- LOG.info("Moved " + block + " from " + peer.getRemoteAddressString()
|
|
|
- + ", delHint=" + delHint);
|
|
|
-
|
|
|
} catch (IOException ioe) {
|
|
|
opStatus = ERROR;
|
|
|
errMsg = "opReplaceBlock " + block + " received exception " + ioe;
|
|
@@ -1117,7 +1126,7 @@ class DataXceiver extends Receiver implements Runnable {
|
|
|
throw ioe;
|
|
|
} finally {
|
|
|
// receive the last byte that indicates the proxy released its thread resource
|
|
|
- if (opStatus == SUCCESS) {
|
|
|
+ if (opStatus == SUCCESS && proxyReply != null) {
|
|
|
try {
|
|
|
proxyReply.readChar();
|
|
|
} catch (IOException ignored) {
|