Search in sources :

Example 1 with DataCorruptionException

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);
            }
        }
    }
}
Also used : FileChannel(java.nio.channels.FileChannel) IMetadata(org.corfudb.protocols.wireprotocol.IMetadata) Metadata(org.corfudb.format.Types.Metadata) ByteString(com.google.protobuf.ByteString) DataCorruptionException(org.corfudb.runtime.exceptions.DataCorruptionException) IOException(java.io.IOException) File(java.io.File) ByteBuffer(java.nio.ByteBuffer) FileInputStream(java.io.FileInputStream) LogHeader(org.corfudb.format.Types.LogHeader)

Example 2 with DataCorruptionException

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();
        }
    }
}
Also used : FileChannel(java.nio.channels.FileChannel) IMetadata(org.corfudb.protocols.wireprotocol.IMetadata) Metadata(org.corfudb.format.Types.Metadata) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) DataCorruptionException(org.corfudb.runtime.exceptions.DataCorruptionException) ByteBuffer(java.nio.ByteBuffer) LogEntry(org.corfudb.format.Types.LogEntry)

Example 3 with 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();
        }
    }
}
Also used : FileChannel(java.nio.channels.FileChannel) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) DataCorruptionException(org.corfudb.runtime.exceptions.DataCorruptionException) ByteBuffer(java.nio.ByteBuffer)

Example 4 with DataCorruptionException

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());
}
Also used : FileChannel(java.nio.channels.FileChannel) IMetadata(org.corfudb.protocols.wireprotocol.IMetadata) Metadata(org.corfudb.format.Types.Metadata) AtomicLong(java.util.concurrent.atomic.AtomicLong) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) DataCorruptionException(org.corfudb.runtime.exceptions.DataCorruptionException) ByteBuffer(java.nio.ByteBuffer) LogHeader(org.corfudb.format.Types.LogHeader) LogEntry(org.corfudb.format.Types.LogEntry) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

ByteBuffer (java.nio.ByteBuffer)4 FileChannel (java.nio.channels.FileChannel)4 DataCorruptionException (org.corfudb.runtime.exceptions.DataCorruptionException)4 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)3 Metadata (org.corfudb.format.Types.Metadata)3 IMetadata (org.corfudb.protocols.wireprotocol.IMetadata)3 LogEntry (org.corfudb.format.Types.LogEntry)2 LogHeader (org.corfudb.format.Types.LogHeader)2 ByteString (com.google.protobuf.ByteString)1 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 IOException (java.io.IOException)1 LinkedHashMap (java.util.LinkedHashMap)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1