more checksum stuff

This commit is contained in:
Joe Thornber 2011-09-16 10:06:37 +01:00
parent 1f6f79782a
commit 478069c4ec
10 changed files with 114 additions and 13 deletions

View File

@ -6,6 +6,7 @@ SOURCE=\
checksum.cc \ checksum.cc \
endian_utils.cc \ endian_utils.cc \
error_set.cc \ error_set.cc \
hex_dump.cc \
metadata.cc \ metadata.cc \
metadata_disk_structures.cc \ metadata_disk_structures.cc \
space_map_disk.cc \ space_map_disk.cc \
@ -15,7 +16,7 @@ OBJECTS=$(subst .cc,.o,$(SOURCE))
TOP_DIR:=$(PWD) TOP_DIR:=$(PWD)
CPPFLAGS=-Wall -g -I$(TOP_DIR) CPPFLAGS=-Wall -g -I$(TOP_DIR)
#CPPFLAGS=-Wall -std=c++0x -g -I$(TOP_DIR) #CPPFLAGS=-Wall -std=c++0x -g -I$(TOP_DIR)
LIBS=-lz -lstdc++ LIBS=-lstdc++
.PHONEY: test-programs .PHONEY: test-programs

11
btree.h
View File

@ -38,6 +38,8 @@ namespace persistent_data {
using namespace std; using namespace std;
using namespace boost; using namespace boost;
uint32_t const BTREE_CSUM_XOR = 121107;
//------------------------------------------------ //------------------------------------------------
// On disk data layout for btree nodes // On disk data layout for btree nodes
enum node_flags { enum node_flags {
@ -74,6 +76,8 @@ namespace persistent_data {
public: public:
explicit node_ref(block_address b, disk_node *raw); explicit node_ref(block_address b, disk_node *raw);
uint32_t get_checksum() const;
block_address get_location() const { block_address get_location() const {
return location_; return location_;
} }
@ -125,8 +129,11 @@ namespace persistent_data {
template <typename RefCounter> template <typename RefCounter>
void inc_children(RefCounter &rc); void inc_children(RefCounter &rc);
// FIXME: remove disk_node *raw() {
void *raw() { return raw_;
}
disk_node const *raw() const {
return raw_; return raw_;
} }

View File

@ -16,6 +16,13 @@ node_ref<ValueTraits>::node_ref(block_address location, disk_node *raw)
{ {
} }
template <typename ValueTraits>
uint32_t
node_ref<ValueTraits>::get_checksum() const
{
return to_cpu<uint32_t>(raw_->header.csum);
}
template <typename ValueTraits> template <typename ValueTraits>
block_address block_address
node_ref<ValueTraits>::get_block_nr() const node_ref<ValueTraits>::get_block_nr() const

View File

@ -3,7 +3,9 @@
#include "btree.h" #include "btree.h"
#include "checksum.h"
#include "error_set.h" #include "error_set.h"
#include "hex_dump.h"
#include <sstream> #include <sstream>
#include <map> #include <map>
@ -78,6 +80,8 @@ namespace persistent_data {
if (already_visited(n)) if (already_visited(n))
return false; return false;
check_sum(n);
if (!key) if (!key)
new_root(level); new_root(level);
@ -95,6 +99,8 @@ namespace persistent_data {
if (already_visited(n)) if (already_visited(n))
return false; return false;
check_sum(n);
if (!key) if (!key)
new_root(level); new_root(level);
@ -104,7 +110,7 @@ namespace persistent_data {
check_ordered_keys(n); check_ordered_keys(n);
check_parent_key(key, n); check_parent_key(key, n);
check_leaf_key(level, n); check_leaf_key(level, n);
return true; return true;
} }
@ -114,6 +120,8 @@ namespace persistent_data {
if (already_visited(n)) if (already_visited(n))
return false; return false;
check_sum(n);
if (!key) if (!key)
new_root(level); new_root(level);
@ -149,6 +157,22 @@ namespace persistent_data {
return false; return false;
} }
template <typename node>
void check_sum(node const &n) const {
crc32c sum(BTREE_CSUM_XOR);
disk_node const *data = n.raw();
sum.append(&data->header.flags, MD_BLOCK_SIZE - sizeof(uint32_t));
if (sum.get_sum() != n.get_checksum()) {
std::ostringstream out;
out << "checksum error for block " << n.get_block_nr()
<< ", sum was " << sum.get_sum()
<< ", expected " << n.get_checksum();
errs_->add_child(out.str());
throw runtime_error(out.str());
}
}
template <typename node> template <typename node>
void check_block_nr(node const &n) const { void check_block_nr(node const &n) const {
if (n.get_location() != n.get_block_nr()) { if (n.get_location() != n.get_block_nr()) {

View File

@ -1,25 +1,31 @@
#include "checksum.h" #include "checksum.h"
#include <zlib.h> #include <boost/crc.hpp>
using namespace base; using namespace base;
//---------------------------------------------------------------- //----------------------------------------------------------------
crc32::crc32(uint32_t seed) crc32c::crc32c(uint32_t xor_value)
: sum_(seed) { : xor_value_(xor_value),
sum_(0)
{
} }
void void
crc32::append(void const *buffer, unsigned len) crc32c::append(void const *buffer, unsigned len)
{ {
sum_ = ::crc32(sum_, reinterpret_cast<Bytef const *>(buffer), len); uint32_t const powers = 0x1EDC6F41;
boost::crc_basic<32> crc(powers, 0xffffffff, 0, true, true);
crc.process_bytes(buffer, len);
sum_ = crc.checksum();
} }
uint32_t uint32_t
crc32::get_sum() const crc32c::get_sum() const
{ {
return sum_; return sum_ ^ xor_value_;
} }
//---------------------------------------------------------------- //----------------------------------------------------------------

View File

@ -6,13 +6,15 @@
//---------------------------------------------------------------- //----------------------------------------------------------------
namespace base { namespace base {
class crc32 { class crc32c {
crc32(uint32_t seed); public:
crc32c(uint32_t xor_value);
void append(void const *buffer, unsigned len); void append(void const *buffer, unsigned len);
uint32_t get_sum() const; uint32_t get_sum() const;
private: private:
uint32_t xor_value_;
uint32_t sum_; uint32_t sum_;
}; };
} }

24
hex_dump.cc Normal file
View File

@ -0,0 +1,24 @@
#include "hex_dump.h"
#include <iostream>
#include <iomanip>
using namespace std;
//----------------------------------------------------------------
void base::hex_dump(ostream &out, void const *data_, size_t len)
{
unsigned char const *data = reinterpret_cast<unsigned char const *>(data_),
*end = data + len;
out << hex;
while (data < end) {
for (unsigned i = 0; i < 16 && data < end; i++, data++)
out << setw(2) << setfill('0') << (unsigned) *data << " ";
out << endl;
}
out << dec;
}
//----------------------------------------------------------------

14
hex_dump.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef HEX_DUMP_H
#define HEX_DUMP_H
#include <iosfwd>
//----------------------------------------------------------------
namespace base {
void hex_dump(std::ostream &out, void const *data, size_t len);
}
//----------------------------------------------------------------
#endif

View File

@ -74,6 +74,17 @@ namespace {
superblock sb; superblock sb;
block_manager<>::read_ref r = bm->read_lock(SUPERBLOCK_LOCATION); block_manager<>::read_ref r = bm->read_lock(SUPERBLOCK_LOCATION);
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data()); superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data());
crc32c sum(160774);
sum.append(&sbd->flags_, MD_BLOCK_SIZE - sizeof(uint32_t));
if (sum.get_sum() != to_cpu<uint32_t>(sbd->csum_)) {
ostringstream out;
out << "bad checksum in superblock, calculated "
<< sum.get_sum()
<< ", superblock contains " << to_cpu<uint32_t>(sbd->csum_);
throw runtime_error(out.str());
}
superblock_traits::unpack(*sbd, sb); superblock_traits::unpack(*sbd, sb);
return sb; return sb;
} }

View File

@ -81,6 +81,11 @@ namespace {
} }
private: private:
void check_crc(transaction_manager::read_ref &rr) {
crc32c sum(240779);
// sum.append(reinterpret_cast<bitmap_header const *>(&rr.data()[0]);
}
void *bitmap_data(transaction_manager::write_ref &wr) { void *bitmap_data(transaction_manager::write_ref &wr) {
bitmap_header *h = reinterpret_cast<bitmap_header *>(&wr.data()[0]); bitmap_header *h = reinterpret_cast<bitmap_header *>(&wr.data()[0]);
return h + 1; return h + 1;