|
@@ -109,7 +109,7 @@ import com.google.common.annotations.VisibleForTesting;
|
|
@InterfaceAudience.Private
|
|
@InterfaceAudience.Private
|
|
public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
public static final Log LOG = LogFactory.getLog(NameNode.class.getName());
|
|
public static final Log LOG = LogFactory.getLog(NameNode.class.getName());
|
|
-
|
|
|
|
|
|
+
|
|
// return string marking fsck status
|
|
// return string marking fsck status
|
|
public static final String CORRUPT_STATUS = "is CORRUPT";
|
|
public static final String CORRUPT_STATUS = "is CORRUPT";
|
|
public static final String HEALTHY_STATUS = "is HEALTHY";
|
|
public static final String HEALTHY_STATUS = "is HEALTHY";
|
|
@@ -117,7 +117,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
public static final String DECOMMISSIONED_STATUS = "is DECOMMISSIONED";
|
|
public static final String DECOMMISSIONED_STATUS = "is DECOMMISSIONED";
|
|
public static final String NONEXISTENT_STATUS = "does not exist";
|
|
public static final String NONEXISTENT_STATUS = "does not exist";
|
|
public static final String FAILURE_STATUS = "FAILED";
|
|
public static final String FAILURE_STATUS = "FAILED";
|
|
-
|
|
|
|
|
|
+
|
|
private final NameNode namenode;
|
|
private final NameNode namenode;
|
|
private final NetworkTopology networktopology;
|
|
private final NetworkTopology networktopology;
|
|
private final int totalDatanodes;
|
|
private final int totalDatanodes;
|
|
@@ -142,14 +142,14 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
*/
|
|
*/
|
|
private boolean internalError = false;
|
|
private boolean internalError = false;
|
|
|
|
|
|
- /**
|
|
|
|
|
|
+ /**
|
|
* True if the user specified the -move option.
|
|
* True if the user specified the -move option.
|
|
*
|
|
*
|
|
* Whe this option is in effect, we will copy salvaged blocks into the lost
|
|
* Whe this option is in effect, we will copy salvaged blocks into the lost
|
|
* and found. */
|
|
* and found. */
|
|
private boolean doMove = false;
|
|
private boolean doMove = false;
|
|
|
|
|
|
- /**
|
|
|
|
|
|
+ /**
|
|
* True if the user specified the -delete option.
|
|
* True if the user specified the -delete option.
|
|
*
|
|
*
|
|
* Whe this option is in effect, we will delete corrupted files.
|
|
* Whe this option is in effect, we will delete corrupted files.
|
|
@@ -182,7 +182,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
* @param remoteAddress source address of the fsck request
|
|
* @param remoteAddress source address of the fsck request
|
|
*/
|
|
*/
|
|
NamenodeFsck(Configuration conf, NameNode namenode,
|
|
NamenodeFsck(Configuration conf, NameNode namenode,
|
|
- NetworkTopology networktopology,
|
|
|
|
|
|
+ NetworkTopology networktopology,
|
|
Map<String,String[]> pmap, PrintWriter out,
|
|
Map<String,String[]> pmap, PrintWriter out,
|
|
int totalDatanodes, InetAddress remoteAddress) {
|
|
int totalDatanodes, InetAddress remoteAddress) {
|
|
this.conf = conf;
|
|
this.conf = conf;
|
|
@@ -198,7 +198,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
this.staleInterval =
|
|
this.staleInterval =
|
|
conf.getLong(DFSConfigKeys.DFS_NAMENODE_STALE_DATANODE_INTERVAL_KEY,
|
|
conf.getLong(DFSConfigKeys.DFS_NAMENODE_STALE_DATANODE_INTERVAL_KEY,
|
|
DFSConfigKeys.DFS_NAMENODE_STALE_DATANODE_INTERVAL_DEFAULT);
|
|
DFSConfigKeys.DFS_NAMENODE_STALE_DATANODE_INTERVAL_DEFAULT);
|
|
-
|
|
|
|
|
|
+
|
|
for (Iterator<String> it = pmap.keySet().iterator(); it.hasNext();) {
|
|
for (Iterator<String> it = pmap.keySet().iterator(); it.hasNext();) {
|
|
String key = it.next();
|
|
String key = it.next();
|
|
if (key.equals("path")) { this.path = pmap.get("path")[0]; }
|
|
if (key.equals("path")) { this.path = pmap.get("path")[0]; }
|
|
@@ -249,7 +249,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
}
|
|
}
|
|
BlockCollection bc = bm.getBlockCollection(blockInfo);
|
|
BlockCollection bc = bm.getBlockCollection(blockInfo);
|
|
INode iNode = (INode) bc;
|
|
INode iNode = (INode) bc;
|
|
- NumberReplicas numberReplicas= bm.countNodes(block);
|
|
|
|
|
|
+ NumberReplicas numberReplicas= bm.countNodes(blockInfo);
|
|
out.println("Block Id: " + blockId);
|
|
out.println("Block Id: " + blockId);
|
|
out.println("Block belongs to: "+iNode.getFullPathName());
|
|
out.println("Block belongs to: "+iNode.getFullPathName());
|
|
out.println("No. of Expected Replica: " +
|
|
out.println("No. of Expected Replica: " +
|
|
@@ -348,7 +348,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
listCorruptFileBlocks();
|
|
listCorruptFileBlocks();
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if (this.showStoragePolcies) {
|
|
if (this.showStoragePolcies) {
|
|
storageTypeSummary = new StoragePolicySummary(
|
|
storageTypeSummary = new StoragePolicySummary(
|
|
namenode.getNamesystem().getBlockManager().getStoragePolicies());
|
|
namenode.getNamesystem().getBlockManager().getStoragePolicies());
|
|
@@ -378,7 +378,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
|
|
|
|
// DFSck client scans for the string HEALTHY/CORRUPT to check the status
|
|
// DFSck client scans for the string HEALTHY/CORRUPT to check the status
|
|
// of file system and return appropriate code. Changing the output
|
|
// of file system and return appropriate code. Changing the output
|
|
- // string might break testcases. Also note this must be the last line
|
|
|
|
|
|
+ // string might break testcases. Also note this must be the last line
|
|
// of the report.
|
|
// of the report.
|
|
if (res.isHealthy()) {
|
|
if (res.isHealthy()) {
|
|
out.print("\n\nThe filesystem under path '" + path + "' " + HEALTHY_STATUS);
|
|
out.print("\n\nThe filesystem under path '" + path + "' " + HEALTHY_STATUS);
|
|
@@ -421,7 +421,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
+ " CORRUPT files");
|
|
+ " CORRUPT files");
|
|
out.println();
|
|
out.println();
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@VisibleForTesting
|
|
@VisibleForTesting
|
|
void check(String parent, HdfsFileStatus file, Result res) throws IOException {
|
|
void check(String parent, HdfsFileStatus file, Result res) throws IOException {
|
|
String path = file.getFullName(parent);
|
|
String path = file.getFullName(parent);
|
|
@@ -478,7 +478,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
throws IOException {
|
|
throws IOException {
|
|
long fileLen = file.getLen();
|
|
long fileLen = file.getLen();
|
|
LocatedBlocks blocks = null;
|
|
LocatedBlocks blocks = null;
|
|
- FSNamesystem fsn = namenode.getNamesystem();
|
|
|
|
|
|
+ final FSNamesystem fsn = namenode.getNamesystem();
|
|
fsn.readLock();
|
|
fsn.readLock();
|
|
try {
|
|
try {
|
|
blocks = FSDirStatAndListingOp.getBlockLocations(
|
|
blocks = FSDirStatAndListingOp.getBlockLocations(
|
|
@@ -534,8 +534,10 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
ExtendedBlock block = lBlk.getBlock();
|
|
ExtendedBlock block = lBlk.getBlock();
|
|
BlockManager bm = namenode.getNamesystem().getBlockManager();
|
|
BlockManager bm = namenode.getNamesystem().getBlockManager();
|
|
|
|
|
|
|
|
+ final BlockInfo storedBlock = bm.getStoredBlock(
|
|
|
|
+ block.getLocalBlock());
|
|
// count decommissionedReplicas / decommissioningReplicas
|
|
// count decommissionedReplicas / decommissioningReplicas
|
|
- NumberReplicas numberReplicas = bm.countNodes(block.getLocalBlock());
|
|
|
|
|
|
+ NumberReplicas numberReplicas = bm.countNodes(storedBlock);
|
|
int decommissionedReplicas = numberReplicas.decommissioned();;
|
|
int decommissionedReplicas = numberReplicas.decommissioned();;
|
|
int decommissioningReplicas = numberReplicas.decommissioning();
|
|
int decommissioningReplicas = numberReplicas.decommissioning();
|
|
res.decommissionedReplicas += decommissionedReplicas;
|
|
res.decommissionedReplicas += decommissionedReplicas;
|
|
@@ -602,7 +604,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
out.println();
|
|
out.println();
|
|
out.print(path + ": ");
|
|
out.print(path + ": ");
|
|
}
|
|
}
|
|
- out.println(" Replica placement policy is violated for " +
|
|
|
|
|
|
+ out.println(" Replica placement policy is violated for " +
|
|
block + ". " + blockPlacementStatus.getErrorDescription());
|
|
block + ". " + blockPlacementStatus.getErrorDescription());
|
|
}
|
|
}
|
|
|
|
|
|
@@ -720,7 +722,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
private void copyBlocksToLostFound(String parent, HdfsFileStatus file,
|
|
private void copyBlocksToLostFound(String parent, HdfsFileStatus file,
|
|
LocatedBlocks blocks) throws IOException {
|
|
LocatedBlocks blocks) throws IOException {
|
|
final DFSClient dfs = new DFSClient(NameNode.getAddress(conf), conf);
|
|
final DFSClient dfs = new DFSClient(NameNode.getAddress(conf), conf);
|
|
@@ -761,7 +763,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
fos = dfs.create(target + "/" + chain, true);
|
|
fos = dfs.create(target + "/" + chain, true);
|
|
chain++;
|
|
chain++;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
// copy the block. It's a pity it's not abstracted from DFSInputStream ...
|
|
// copy the block. It's a pity it's not abstracted from DFSInputStream ...
|
|
try {
|
|
try {
|
|
copyBlock(dfs, lblock, fos);
|
|
copyBlock(dfs, lblock, fos);
|
|
@@ -779,7 +781,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
LOG.warn("Fsck: there were errors copying the remains of the " +
|
|
LOG.warn("Fsck: there were errors copying the remains of the " +
|
|
"corrupted file " + fullName + " to /lost+found");
|
|
"corrupted file " + fullName + " to /lost+found");
|
|
} else {
|
|
} else {
|
|
- LOG.info("Fsck: copied the remains of the corrupted file " +
|
|
|
|
|
|
+ LOG.info("Fsck: copied the remains of the corrupted file " +
|
|
fullName + " to /lost+found");
|
|
fullName + " to /lost+found");
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
@@ -790,7 +792,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
dfs.close();
|
|
dfs.close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* XXX (ab) Bulk of this method is copied verbatim from {@link DFSClient}, which is
|
|
* XXX (ab) Bulk of this method is copied verbatim from {@link DFSClient}, which is
|
|
* bad. Both places should be refactored to provide a method to copy blocks
|
|
* bad. Both places should be refactored to provide a method to copy blocks
|
|
@@ -801,12 +803,12 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
int failures = 0;
|
|
int failures = 0;
|
|
InetSocketAddress targetAddr = null;
|
|
InetSocketAddress targetAddr = null;
|
|
TreeSet<DatanodeInfo> deadNodes = new TreeSet<DatanodeInfo>();
|
|
TreeSet<DatanodeInfo> deadNodes = new TreeSet<DatanodeInfo>();
|
|
- BlockReader blockReader = null;
|
|
|
|
- ExtendedBlock block = lblock.getBlock();
|
|
|
|
|
|
+ BlockReader blockReader = null;
|
|
|
|
+ ExtendedBlock block = lblock.getBlock();
|
|
|
|
|
|
while (blockReader == null) {
|
|
while (blockReader == null) {
|
|
DatanodeInfo chosenNode;
|
|
DatanodeInfo chosenNode;
|
|
-
|
|
|
|
|
|
+
|
|
try {
|
|
try {
|
|
chosenNode = bestNode(dfs, lblock.getLocations(), deadNodes);
|
|
chosenNode = bestNode(dfs, lblock.getLocations(), deadNodes);
|
|
targetAddr = NetUtils.createSocketAddr(chosenNode.getXferAddr());
|
|
targetAddr = NetUtils.createSocketAddr(chosenNode.getXferAddr());
|
|
@@ -877,7 +879,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
bytesRead += cnt;
|
|
bytesRead += cnt;
|
|
}
|
|
}
|
|
if ( bytesRead != block.getNumBytes() ) {
|
|
if ( bytesRead != block.getNumBytes() ) {
|
|
- throw new IOException("Recorded block size is " + block.getNumBytes() +
|
|
|
|
|
|
+ throw new IOException("Recorded block size is " + block.getNumBytes() +
|
|
", but datanode returned " +bytesRead+" bytes");
|
|
", but datanode returned " +bytesRead+" bytes");
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
@@ -914,12 +916,12 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
} while (deadNodes.contains(chosenNode));
|
|
} while (deadNodes.contains(chosenNode));
|
|
return chosenNode;
|
|
return chosenNode;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
private void lostFoundInit(DFSClient dfs) {
|
|
private void lostFoundInit(DFSClient dfs) {
|
|
lfInited = true;
|
|
lfInited = true;
|
|
try {
|
|
try {
|
|
String lfName = "/lost+found";
|
|
String lfName = "/lost+found";
|
|
-
|
|
|
|
|
|
+
|
|
final HdfsFileStatus lfStatus = dfs.getFileInfo(lfName);
|
|
final HdfsFileStatus lfStatus = dfs.getFileInfo(lfName);
|
|
if (lfStatus == null) { // not exists
|
|
if (lfStatus == null) { // not exists
|
|
lfInitedOk = dfs.mkdirs(lfName, null, true);
|
|
lfInitedOk = dfs.mkdirs(lfName, null, true);
|
|
@@ -973,21 +975,21 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
|
|
|
|
final short replication;
|
|
final short replication;
|
|
final int minReplication;
|
|
final int minReplication;
|
|
-
|
|
|
|
|
|
+
|
|
Result(Configuration conf) {
|
|
Result(Configuration conf) {
|
|
- this.replication = (short)conf.getInt(DFSConfigKeys.DFS_REPLICATION_KEY,
|
|
|
|
|
|
+ this.replication = (short)conf.getInt(DFSConfigKeys.DFS_REPLICATION_KEY,
|
|
DFSConfigKeys.DFS_REPLICATION_DEFAULT);
|
|
DFSConfigKeys.DFS_REPLICATION_DEFAULT);
|
|
this.minReplication = (short)conf.getInt(DFSConfigKeys.DFS_NAMENODE_REPLICATION_MIN_KEY,
|
|
this.minReplication = (short)conf.getInt(DFSConfigKeys.DFS_NAMENODE_REPLICATION_MIN_KEY,
|
|
DFSConfigKeys.DFS_NAMENODE_REPLICATION_MIN_DEFAULT);
|
|
DFSConfigKeys.DFS_NAMENODE_REPLICATION_MIN_DEFAULT);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* DFS is considered healthy if there are no missing blocks.
|
|
* DFS is considered healthy if there are no missing blocks.
|
|
*/
|
|
*/
|
|
boolean isHealthy() {
|
|
boolean isHealthy() {
|
|
return ((missingIds.size() == 0) && (corruptBlocks == 0));
|
|
return ((missingIds.size() == 0) && (corruptBlocks == 0));
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
/** Add a missing block name, plus its size. */
|
|
/** Add a missing block name, plus its size. */
|
|
void addMissing(String id, long size) {
|
|
void addMissing(String id, long size) {
|
|
missingIds.add(id);
|
|
missingIds.add(id);
|
|
@@ -1000,7 +1002,7 @@ public class NamenodeFsck implements DataEncryptionKeyFactory {
|
|
return 0.0f;
|
|
return 0.0f;
|
|
return (float) (totalReplicas) / (float) totalBlocks;
|
|
return (float) (totalReplicas) / (float) totalBlocks;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public String toString() {
|
|
public String toString() {
|
|
StringBuilder res = new StringBuilder();
|
|
StringBuilder res = new StringBuilder();
|