/// <summary>Verifies the block's checksum.</summary> /// <remarks>Verifies the block's checksum. This is an I/O intensive operation.</remarks> /// <exception cref="System.IO.IOException"/> /// <exception cref="Org.Apache.Hadoop.FS.ChecksumException"/> private static void VerifyChecksum(long length, FileInputStream metaIn, FileChannel blockChannel, string blockFileName) { // Verify the checksum from the block's meta file // Get the DataChecksum from the meta file header BlockMetadataHeader header = BlockMetadataHeader.ReadHeader(new DataInputStream(new BufferedInputStream(metaIn, BlockMetadataHeader.GetHeaderSize()))); FileChannel metaChannel = null; try { metaChannel = metaIn.GetChannel(); if (metaChannel == null) { throw new IOException("Block InputStream meta file has no FileChannel."); } DataChecksum checksum = header.GetChecksum(); int bytesPerChecksum = checksum.GetBytesPerChecksum(); int checksumSize = checksum.GetChecksumSize(); int numChunks = (8 * 1024 * 1024) / bytesPerChecksum; ByteBuffer blockBuf = ByteBuffer.Allocate(numChunks * bytesPerChecksum); ByteBuffer checksumBuf = ByteBuffer.Allocate(numChunks * checksumSize); // Verify the checksum int bytesVerified = 0; while (bytesVerified < length) { Preconditions.CheckState(bytesVerified % bytesPerChecksum == 0, "Unexpected partial chunk before EOF" ); System.Diagnostics.Debug.Assert(bytesVerified % bytesPerChecksum == 0); int bytesRead = FillBuffer(blockChannel, blockBuf); if (bytesRead == -1) { throw new IOException("checksum verification failed: premature EOF"); } blockBuf.Flip(); // Number of read chunks, including partial chunk at end int chunks = (bytesRead + bytesPerChecksum - 1) / bytesPerChecksum; checksumBuf.Limit(chunks * checksumSize); FillBuffer(metaChannel, checksumBuf); checksumBuf.Flip(); checksum.VerifyChunkedSums(blockBuf, checksumBuf, blockFileName, bytesVerified); // Success bytesVerified += bytesRead; blockBuf.Clear(); checksumBuf.Clear(); } } finally { IOUtils.CloseQuietly(metaChannel); } }
/// <exception cref="System.IO.IOException"/> internal override int Run(IList <string> args) { if (args.Count == 0) { System.Console.Out.WriteLine(this.usageText); System.Console.Out.WriteLine(this.helpText + "\n"); return(1); } string blockFile = StringUtils.PopOptionWithArgument("-block", args); string metaFile = StringUtils.PopOptionWithArgument("-meta", args); if (metaFile == null) { System.Console.Error.WriteLine("You must specify a meta file with -meta"); return(1); } FileInputStream metaStream = null; FileInputStream dataStream = null; FileChannel metaChannel = null; FileChannel dataChannel = null; DataInputStream checksumStream = null; try { BlockMetadataHeader header; try { metaStream = new FileInputStream(metaFile); checksumStream = new DataInputStream(metaStream); header = BlockMetadataHeader.ReadHeader(checksumStream); metaChannel = metaStream.GetChannel(); metaChannel.Position(DebugAdmin.HeaderLen); } catch (RuntimeException e) { System.Console.Error.WriteLine("Failed to read HDFS metadata file header for " + metaFile + ": " + StringUtils.StringifyException(e)); return(1); } catch (IOException e) { System.Console.Error.WriteLine("Failed to read HDFS metadata file header for " + metaFile + ": " + StringUtils.StringifyException(e)); return(1); } DataChecksum checksum = header.GetChecksum(); System.Console.Out.WriteLine("Checksum type: " + checksum.ToString()); if (blockFile == null) { return(0); } ByteBuffer metaBuf; ByteBuffer dataBuf; try { dataStream = new FileInputStream(blockFile); dataChannel = dataStream.GetChannel(); int ChecksumsPerBuf = 1024 * 32; metaBuf = ByteBuffer.Allocate(checksum.GetChecksumSize() * ChecksumsPerBuf); dataBuf = ByteBuffer.Allocate(checksum.GetBytesPerChecksum() * ChecksumsPerBuf); } catch (IOException e) { System.Console.Error.WriteLine("Failed to open HDFS block file for " + blockFile + ": " + StringUtils.StringifyException(e)); return(1); } long offset = 0; while (true) { dataBuf.Clear(); int dataRead = -1; try { dataRead = dataChannel.Read(dataBuf); if (dataRead < 0) { break; } } catch (IOException e) { System.Console.Error.WriteLine("Got I/O error reading block file " + blockFile + "from disk at offset " + dataChannel.Position() + ": " + StringUtils.StringifyException (e)); return(1); } try { int csumToRead = (((checksum.GetBytesPerChecksum() - 1) + dataRead) / checksum.GetBytesPerChecksum ()) * checksum.GetChecksumSize(); metaBuf.Clear(); metaBuf.Limit(csumToRead); metaChannel.Read(metaBuf); dataBuf.Flip(); metaBuf.Flip(); } catch (IOException e) { System.Console.Error.WriteLine("Got I/O error reading metadata file " + metaFile + "from disk at offset " + metaChannel.Position() + ": " + StringUtils.StringifyException (e)); return(1); } try { checksum.VerifyChunkedSums(dataBuf, metaBuf, blockFile, offset); } catch (IOException e) { System.Console.Out.WriteLine("verifyChunkedSums error: " + StringUtils.StringifyException (e)); return(1); } offset += dataRead; } System.Console.Out.WriteLine("Checksum verification succeeded on block file " + blockFile ); return(0); } finally { IOUtils.Cleanup(null, metaStream, dataStream, checksumStream); } }