diff options
| author | Kim van der Riet <kpvdr@apache.org> | 2013-12-03 21:46:39 +0000 |
|---|---|---|
| committer | Kim van der Riet <kpvdr@apache.org> | 2013-12-03 21:46:39 +0000 |
| commit | c4adf22274caee4d3d6869d97e6f1a98717c7df4 (patch) | |
| tree | e9a055d1bd52677c473cf2e9964a2b3d033272b7 /cpp/src/qpid/linearstore/journal/RecoveryManager.cpp | |
| parent | d4ac61b877597d35caf9163467bcb218003064a2 (diff) | |
| download | qpid-python-c4adf22274caee4d3d6869d97e6f1a98717c7df4.tar.gz | |
QPID-5358: Checksum not implemented in record tail, not checked during read. Implemented the Alder-32 algorithm to check every record from the start of the header to the start of the record tail. Upon recovery, the recovered record checksum is compared to the record tail checksum. This should detect the condition where a multi-page record may have its header and tail written, but one or more of its inbetween pages may not be fully written.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1547601 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/linearstore/journal/RecoveryManager.cpp')
| -rw-r--r-- | cpp/src/qpid/linearstore/journal/RecoveryManager.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp b/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp index 22241aa164..a8d24366de 100644 --- a/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp +++ b/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp @@ -24,6 +24,7 @@ #include <algorithm> #include <cstdlib> #include <iomanip> +#include "qpid/linearstore/journal/Checksum.h" #include "qpid/linearstore/journal/data_tok.h" #include "qpid/linearstore/journal/deq_rec.h" #include "qpid/linearstore/journal/EmptyFilePool.h" @@ -201,6 +202,32 @@ bool RecoveryManager::readNextRemainingRecord(void** const dataPtrPtr, } readJournalData((char*)*dataPtrPtr, dataSize); + // Check enqueue record checksum + Checksum checksum; + checksum.addData((unsigned char*)&enqueueHeader, sizeof(::enq_hdr_t)); + if (xidSize > 0) { + checksum.addData((unsigned char*)*xidPtrPtr, xidSize); + } + if (dataSize > 0) { + checksum.addData((unsigned char*)*dataPtrPtr, dataSize); + } + ::rec_tail_t enqueueTail; + inFileStream_.read((char*)&enqueueTail, sizeof(::rec_tail_t)); + uint32_t cs = checksum.getChecksum(); +//std::cout << std::hex << "### rid=0x" << enqueueHeader._rhdr._rid << " rtcs=0x" << enqueueTail._checksum << " cs=0x" << cs << std::dec << std::endl; // DEBUG + int res = ::rec_tail_check(&enqueueTail, &enqueueHeader._rhdr, cs); + if (res != 0) { + std::stringstream oss; + switch (res) { + case 1: oss << std::hex << "Magic: expected 0x" << ~enqueueHeader._rhdr._magic << "; found 0x" << enqueueTail._xmagic; break; + case 2: oss << std::hex << "Serial: expected 0x" << enqueueHeader._rhdr._serial << "; found 0x" << enqueueTail._serial; break; + case 3: oss << std::hex << "Record Id: expected 0x" << enqueueHeader._rhdr._rid << "; found 0x" << enqueueTail._rid; break; + case 4: oss << std::hex << "Checksum: expected 0x" << cs << "; found 0x" << enqueueTail._checksum; break; + default: oss << "Unknown error " << res; + } + throw jexception(jerrno::JERR_JREC_BADRECTAIL, oss.str(), "enq_rec", "decode"); // TODO: Don't throw exception, log info + } + // Set data token dtokp->set_wstate(data_tok::ENQ); dtokp->set_rid(enqueueHeader._rhdr._rid); |
