Commit 6bb2e2de authored by Mukund Sivaraman's avatar Mukund Sivaraman
Browse files

[2850] Handle the case where setNamedAddress() may invalidate the passed address

This doesn't handle the issue at a higher level yet.
parent 366cf13a
......@@ -41,7 +41,7 @@ ZoneTableSegmentMapped::ZoneTableSegmentMapped(const RRClass& rrclass) :
{
}
void
bool
ZoneTableSegmentMapped::processChecksum(MemorySegmentMapped& segment,
bool createMode)
{
......@@ -68,15 +68,35 @@ ZoneTableSegmentMapped::processChecksum(MemorySegmentMapped& segment,
"Saved checksum doesn't match mapped segment data");
}
}
return (true);
} else {
// Allocate space for a checksum (which is saved during close).
void* checksum = segment.allocate(sizeof(uint32_t));
// First allocate a ZONE_TABLE_CHECKSUM_NAME, so that we can set
// it without growing the segment (and changing the checksum's
// address).
segment.setNamedAddress(ZONE_TABLE_CHECKSUM_NAME, NULL);
void* checksum = NULL;
while (!checksum) {
try {
checksum = segment.allocate(sizeof(uint32_t));
} catch (const MemorySegmentGrown&) {
// Do nothing and try again.
}
}
*static_cast<uint32_t*>(checksum) = 0;
segment.setNamedAddress(ZONE_TABLE_CHECKSUM_NAME, checksum);
const bool grew = segment.setNamedAddress(ZONE_TABLE_CHECKSUM_NAME,
checksum);
// If the segment grew here, we have a problem as the checksum
// address may no longer be valid. In this case, we cannot
// recover. This case is extremely unlikely as we reserved
// memory for the ZONE_TABLE_CHECKSUM_NAME above. It indicates a
// very restrictive MemorySegment which we should not use.
return (!grew);
}
}
void
bool
ZoneTableSegmentMapped::processHeader(MemorySegmentMapped& segment,
bool createMode)
{
......@@ -93,12 +113,31 @@ ZoneTableSegmentMapped::processHeader(MemorySegmentMapped& segment,
header_ = static_cast<ZoneTableHeader*>(result.second);
}
} else {
void* ptr = segment.allocate(sizeof(ZoneTableHeader));
segment.setNamedAddress(ZONE_TABLE_HEADER_NAME, NULL);
void* ptr = NULL;
while (!ptr) {
try {
ptr = segment.allocate(sizeof(ZoneTableHeader));
} catch (const MemorySegmentGrown&) {
// Do nothing and try again.
}
}
ZoneTableHeader* new_header = new(ptr)
ZoneTableHeader(ZoneTable::create(segment, rrclass_));
segment.setNamedAddress(ZONE_TABLE_HEADER_NAME, new_header);
const bool grew = segment.setNamedAddress(ZONE_TABLE_HEADER_NAME,
new_header);
if (grew) {
// If the segment grew here, we have a problem as the table
// header address may no longer be valid. In this case, we
// cannot recover. This case is extremely unlikely as we
// reserved memory for the ZONE_TABLE_HEADER_NAME above. It
// indicates a very restrictive MemorySegment which we
// should not use.
return (false);
}
header_ = new_header;
}
return (true);
}
void
......
......@@ -101,8 +101,8 @@ public:
virtual void clear();
private:
void processChecksum(isc::util::MemorySegmentMapped& segment, bool create);
void processHeader(isc::util::MemorySegmentMapped& segment, bool create);
bool processChecksum(isc::util::MemorySegmentMapped& segment, bool create);
bool processHeader(isc::util::MemorySegmentMapped& segment, bool create);
void openCreate(const std::string& filename);
void openReadWrite(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