use of org.corfudb.runtime.exceptions.DataCorruptionException in project CorfuDB by CorfuDB.
the class StreamLogFiles method verifyLogs.
private void verifyLogs() {
String[] extension = { "log" };
File dir = new File(logDir);
if (dir.exists()) {
Collection<File> files = FileUtils.listFiles(dir, extension, true);
for (File file : files) {
try {
FileInputStream fIn = new FileInputStream(file);
FileChannel fc = fIn.getChannel();
ByteBuffer metadataBuf = ByteBuffer.allocate(METADATA_SIZE);
fc.read(metadataBuf);
metadataBuf.flip();
Metadata metadata = Metadata.parseFrom(metadataBuf.array());
ByteBuffer headerBuf = ByteBuffer.allocate(metadata.getLength());
fc.read(headerBuf);
headerBuf.flip();
LogHeader header = LogHeader.parseFrom(headerBuf.array());
fc.close();
fIn.close();
if (metadata.getChecksum() != getChecksum(header.toByteArray())) {
log.error("Checksum mismatch detected while trying to read header for logfile {}", file);
throw new DataCorruptionException();
}
if (header.getVersion() != VERSION) {
String msg = String.format("Log version {} for {} should match the logunit log version {}", header.getVersion(), file.getAbsoluteFile(), VERSION);
throw new RuntimeException(msg);
}
if (!noVerify && !header.getVerifyChecksum()) {
String msg = String.format("Log file {} not generated with checksums, can't verify!", file.getAbsoluteFile());
throw new RuntimeException(msg);
}
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
}
use of org.corfudb.runtime.exceptions.DataCorruptionException in project CorfuDB by CorfuDB.
the class StreamLogFiles method readAddressSpace.
/**
* Reads an address space from a log file into a SegmentHandle
*
* @param sh
*/
private void readAddressSpace(SegmentHandle sh) throws IOException {
long logFileSize;
try (MultiReadWriteLock.AutoCloseableLock ignored = segmentLocks.acquireReadLock(sh.getSegment())) {
logFileSize = sh.logChannel.size();
}
FileChannel fc = getChannel(sh.fileName, true);
if (fc == null) {
log.trace("Can't read address space, {} doesn't exist", sh.fileName);
return;
}
// Skip the header
ByteBuffer headerMetadataBuf = ByteBuffer.allocate(METADATA_SIZE);
fc.read(headerMetadataBuf);
headerMetadataBuf.flip();
Metadata headerMetadata = Metadata.parseFrom(headerMetadataBuf.array());
fc.position(fc.position() + headerMetadata.getLength());
long channelOffset = fc.position();
ByteBuffer o = ByteBuffer.allocate((int) logFileSize - (int) fc.position());
fc.read(o);
fc.close();
o.flip();
while (o.hasRemaining()) {
short magic = o.getShort();
channelOffset += Short.BYTES;
if (magic != RECORD_DELIMITER) {
log.error("Expected a delimiter but found something else while trying to read file {}", sh.fileName);
throw new DataCorruptionException();
}
byte[] metadataBuf = new byte[METADATA_SIZE];
o.get(metadataBuf);
channelOffset += METADATA_SIZE;
try {
Metadata metadata = Metadata.parseFrom(metadataBuf);
byte[] logEntryBuf = new byte[metadata.getLength()];
o.get(logEntryBuf);
LogEntry entry = LogEntry.parseFrom(logEntryBuf);
if (!noVerify) {
if (metadata.getChecksum() != getChecksum(entry.toByteArray())) {
log.error("Checksum mismatch detected while trying to read file {}", sh.fileName);
throw new DataCorruptionException();
}
}
sh.knownAddresses.put(entry.getGlobalAddress(), new AddressMetaData(metadata.getChecksum(), metadata.getLength(), channelOffset));
channelOffset += metadata.getLength();
} catch (InvalidProtocolBufferException e) {
throw new DataCorruptionException();
}
}
}
use of org.corfudb.runtime.exceptions.DataCorruptionException in project CorfuDB by CorfuDB.
the class StreamLogFiles method readRecord.
/**
* Read a log entry in a file.
*
* @param sh The file handle to use.
* @param address The address of the entry.
* @return The log unit entry at that address, or NULL if there was no entry.
*/
private LogData readRecord(SegmentHandle sh, long address) throws IOException {
FileChannel fc = null;
try {
fc = getChannel(sh.fileName, true);
AddressMetaData metaData = sh.getKnownAddresses().get(address);
if (metaData == null) {
return null;
}
fc.position(metaData.offset);
try {
ByteBuffer entryBuf = ByteBuffer.allocate(metaData.length);
fc.read(entryBuf);
return getLogData(LogEntry.parseFrom(entryBuf.array()));
} catch (InvalidProtocolBufferException e) {
throw new DataCorruptionException();
}
} finally {
if (fc != null) {
fc.close();
}
}
}
use of org.corfudb.runtime.exceptions.DataCorruptionException in project CorfuDB by CorfuDB.
the class StreamLogFiles method getCompactedEntries.
private CompactedEntry getCompactedEntries(String filePath, Set<Long> pendingTrim) throws IOException {
FileChannel fc = getChannel(filePath, true);
// Skip the header
ByteBuffer headerMetadataBuf = ByteBuffer.allocate(METADATA_SIZE);
fc.read(headerMetadataBuf);
headerMetadataBuf.flip();
Metadata headerMetadata = Metadata.parseFrom(headerMetadataBuf.array());
ByteBuffer headerBuf = ByteBuffer.allocate(headerMetadata.getLength());
fc.read(headerBuf);
headerBuf.flip();
LogHeader header = LogHeader.parseFrom(headerBuf.array());
ByteBuffer o = ByteBuffer.allocate((int) fc.size() - (int) fc.position());
fc.read(o);
fc.close();
o.flip();
LinkedHashMap<Long, LogEntry> compacted = new LinkedHashMap<>();
while (o.hasRemaining()) {
//Skip delimiter
o.getShort();
byte[] metadataBuf = new byte[METADATA_SIZE];
o.get(metadataBuf);
try {
Metadata metadata = Metadata.parseFrom(metadataBuf);
byte[] logEntryBuf = new byte[metadata.getLength()];
o.get(logEntryBuf);
LogEntry entry = LogEntry.parseFrom(logEntryBuf);
if (!noVerify) {
if (metadata.getChecksum() != getChecksum(entry.toByteArray())) {
log.error("Checksum mismatch detected while trying to read address {}", entry.getGlobalAddress());
throw new DataCorruptionException();
}
}
if (!pendingTrim.contains(entry.getGlobalAddress())) {
compacted.put(entry.getGlobalAddress(), entry);
}
} catch (InvalidProtocolBufferException e) {
throw new DataCorruptionException();
}
}
return new CompactedEntry(header, compacted.values());
}
Aggregations