summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp
diff options
context:
space:
mode:
authorKim van der Riet <kpvdr@apache.org>2013-12-03 21:46:39 +0000
committerKim van der Riet <kpvdr@apache.org>2013-12-03 21:46:39 +0000
commitc4adf22274caee4d3d6869d97e6f1a98717c7df4 (patch)
treee9a055d1bd52677c473cf2e9964a2b3d033272b7 /cpp/src/qpid/linearstore/journal/RecoveryManager.cpp
parentd4ac61b877597d35caf9163467bcb218003064a2 (diff)
downloadqpid-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.cpp27
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);