Commit 6548cfed authored by Mukund Sivaraman's avatar Mukund Sivaraman
Browse files

[2850] Unify checksum and header processing code

parent 02c2f7f8
......@@ -42,36 +42,74 @@ ZoneTableSegmentMapped::ZoneTableSegmentMapped(const RRClass& rrclass) :
}
void
ZoneTableSegmentMapped::openCreate(const std::string& filename) {
// In case there is a checksum mismatch, we throw. We want the
// segment to be automatically destroyed then.
std::auto_ptr<MemorySegmentMapped> segment
(new MemorySegmentMapped(filename, MemorySegmentMapped::CREATE_ONLY));
// There must be no previously saved checksum.
ZoneTableSegmentMapped::processChecksum(MemorySegmentMapped& segment,
bool createMode)
{
MemorySegment::NamedAddressResult result =
segment->getNamedAddress(ZONE_TABLE_CHECKSUM_NAME);
segment.getNamedAddress(ZONE_TABLE_CHECKSUM_NAME);
if (result.first) {
isc_throw(isc::Unexpected,
"There is already a saved checksum in a mapped segment "
"opened in create mode.");
if (createMode) {
// There must be no previously saved checksum.
isc_throw(isc::Unexpected,
"There is already a saved checksum in a mapped segment "
"opened in create mode.");
} else {
// The segment was already shrunk when it was last
// closed. Check that its checksum is consistent.
assert(result.second);
uint32_t* checksum = static_cast<uint32_t*>(result.second);
const uint32_t saved_checksum = *checksum;
// First, clear the checksum so that getCheckSum() returns a
// consistent value.
*checksum = 0;
const uint32_t new_checksum = segment.getCheckSum();
if (saved_checksum != new_checksum) {
isc_throw(isc::Unexpected,
"Saved checksum doesn't match mapped segment data");
}
}
} else {
// Allocate space for a checksum (which is saved during close).
void* checksum = segment.allocate(sizeof(uint32_t));
*static_cast<uint32_t*>(checksum) = 0;
segment.setNamedAddress(ZONE_TABLE_CHECKSUM_NAME, checksum);
}
// Allocate space for a checksum (which is saved during close).
void* checksum = segment->allocate(sizeof(uint32_t));
*static_cast<uint32_t*>(checksum) = 0;
segment->setNamedAddress(ZONE_TABLE_CHECKSUM_NAME, checksum);
}
// There must be no previously saved ZoneTableHeader.
result = segment->getNamedAddress(ZONE_TABLE_HEADER_NAME);
void
ZoneTableSegmentMapped::processHeader(MemorySegmentMapped& segment,
bool createMode)
{
MemorySegment::NamedAddressResult result =
segment.getNamedAddress(ZONE_TABLE_HEADER_NAME);
if (result.first) {
isc_throw(isc::Unexpected,
"There is already a saved ZoneTableHeader in a "
"mapped segment opened in create mode.");
if (createMode) {
// There must be no previously saved checksum.
isc_throw(isc::Unexpected,
"There is already a saved ZoneTableHeader in a "
"mapped segment opened in create mode.");
} else {
assert(result.second);
header_ = static_cast<ZoneTableHeader*>(result.second);
}
} else {
void* ptr = segment.allocate(sizeof(ZoneTableHeader));
ZoneTableHeader* new_header = new(ptr)
ZoneTableHeader(ZoneTable::create(segment, rrclass_));
segment.setNamedAddress(ZONE_TABLE_HEADER_NAME, new_header);
header_ = new_header;
}
void* ptr = segment->allocate(sizeof(ZoneTableHeader));
ZoneTableHeader* new_header = new(ptr)
ZoneTableHeader(ZoneTable::create(*segment, rrclass_));
segment->setNamedAddress(ZONE_TABLE_HEADER_NAME, new_header);
header_ = new_header;
}
void
ZoneTableSegmentMapped::openCreate(const std::string& filename) {
// In case there is a checksum mismatch, we throw. We want the
// segment to be automatically destroyed then.
std::auto_ptr<MemorySegmentMapped> segment
(new MemorySegmentMapped(filename, MemorySegmentMapped::CREATE_ONLY));
processChecksum(*segment, true);
processHeader(*segment, true);
mem_sgmt_.reset(segment.release());
}
......@@ -83,44 +121,9 @@ ZoneTableSegmentMapped::openReadWrite(const std::string& filename) {
std::auto_ptr<MemorySegmentMapped> segment
(new MemorySegmentMapped(filename,
MemorySegmentMapped::OPEN_OR_CREATE));
// If there is a previously saved checksum, verify that it is
// consistent. Otherwise, allocate space for a checksum (which is
// saved during close).
MemorySegment::NamedAddressResult result =
segment->getNamedAddress(ZONE_TABLE_CHECKSUM_NAME);
if (result.first) {
// The segment was already shrunk when it was last closed. Check
// that its checksum is consistent.
assert(result.second);
uint32_t* checksum = static_cast<uint32_t*>(result.second);
const uint32_t saved_checksum = *checksum;
// First, clear the checksum so that getCheckSum() returns a
// consistent value.
*checksum = 0;
const uint32_t new_checksum = segment->getCheckSum();
if (saved_checksum != new_checksum) {
isc_throw(isc::Unexpected,
"Saved checksum doesn't match mapped segment data");
}
} else {
void* checksum = segment->allocate(sizeof(uint32_t));
*static_cast<uint32_t*>(checksum) = 0;
segment->setNamedAddress(ZONE_TABLE_CHECKSUM_NAME, checksum);
}
// If there is a previously saved ZoneTableHeader, use
// it. Otherwise, allocate a new header.
result = segment->getNamedAddress(ZONE_TABLE_HEADER_NAME);
if (result.first) {
assert(result.second);
header_ = static_cast<ZoneTableHeader*>(result.second);
} else {
void* ptr = segment->allocate(sizeof(ZoneTableHeader));
ZoneTableHeader* new_header = new(ptr)
ZoneTableHeader(ZoneTable::create(*segment, rrclass_));
segment->setNamedAddress(ZONE_TABLE_HEADER_NAME, new_header);
header_ = new_header;
}
processChecksum(*segment, false);
processHeader(*segment, false);
mem_sgmt_.reset(segment.release());
}
......
......@@ -98,6 +98,9 @@ public:
isc::data::ConstElementPtr params);
private:
void processChecksum(isc::util::MemorySegmentMapped& segment, bool create);
void processHeader(isc::util::MemorySegmentMapped& segment, bool create);
void openCreate(const std::string& filename);
void openReadWrite(const std::string& filename);
void openReadOnly(const std::string& filename);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment