|
@@ -182,36 +182,48 @@ loadZoneDataInternal(util::MemorySegment& mem_sgmt,
|
|
|
const Name& zone_name,
|
|
|
boost::function<void(LoadCallback)> rrset_installer)
|
|
|
{
|
|
|
- SegmentObjectHolder<ZoneData, RRClass> holder(
|
|
|
- mem_sgmt, rrclass);
|
|
|
- holder.set(ZoneData::create(mem_sgmt, zone_name));
|
|
|
-
|
|
|
- ZoneDataLoader loader(mem_sgmt, rrclass, zone_name, *holder.get());
|
|
|
- rrset_installer(boost::bind(&ZoneDataLoader::addFromLoad, &loader, _1));
|
|
|
- // Add any last RRsets that were left
|
|
|
- loader.flushNodeRRsets();
|
|
|
-
|
|
|
- const ZoneNode* origin_node = holder.get()->getOriginNode();
|
|
|
- const RdataSet* rdataset = origin_node->getData();
|
|
|
- // If the zone is NSEC3-signed, check if it has NSEC3PARAM
|
|
|
- if (holder.get()->isNSEC3Signed()) {
|
|
|
- if (RdataSet::find(rdataset, RRType::NSEC3PARAM()) == NULL) {
|
|
|
- LOG_WARN(logger, DATASRC_MEMORY_MEM_NO_NSEC3PARAM).
|
|
|
- arg(zone_name).arg(rrclass);
|
|
|
+ while (true) { // Try as long as it takes to load and grow the segment
|
|
|
+ bool created = false;
|
|
|
+ try {
|
|
|
+ SegmentObjectHolder<ZoneData, RRClass> holder(
|
|
|
+ mem_sgmt, rrclass);
|
|
|
+ holder.set(ZoneData::create(mem_sgmt, zone_name));
|
|
|
+
|
|
|
+ // Nothing from this point on should throw MemorySegmentGrown.
|
|
|
+ // It is handled inside here.
|
|
|
+ created = true;
|
|
|
+
|
|
|
+ ZoneDataLoader loader(mem_sgmt, rrclass, zone_name, *holder.get());
|
|
|
+ rrset_installer(boost::bind(&ZoneDataLoader::addFromLoad, &loader,
|
|
|
+ _1));
|
|
|
+ // Add any last RRsets that were left
|
|
|
+ loader.flushNodeRRsets();
|
|
|
+
|
|
|
+ const ZoneNode* origin_node = holder.get()->getOriginNode();
|
|
|
+ const RdataSet* rdataset = origin_node->getData();
|
|
|
+ // If the zone is NSEC3-signed, check if it has NSEC3PARAM
|
|
|
+ if (holder.get()->isNSEC3Signed()) {
|
|
|
+ if (RdataSet::find(rdataset, RRType::NSEC3PARAM()) == NULL) {
|
|
|
+ LOG_WARN(logger, DATASRC_MEMORY_MEM_NO_NSEC3PARAM).
|
|
|
+ arg(zone_name).arg(rrclass);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ RRsetCollection collection(*(holder.get()), rrclass);
|
|
|
+ const dns::ZoneCheckerCallbacks
|
|
|
+ callbacks(boost::bind(&logError, &zone_name, &rrclass, _1),
|
|
|
+ boost::bind(&logWarning, &zone_name, &rrclass, _1));
|
|
|
+ if (!dns::checkZone(zone_name, rrclass, collection, callbacks)) {
|
|
|
+ isc_throw(ZoneValidationError,
|
|
|
+ "Errors found when validating zone: "
|
|
|
+ << zone_name << "/" << rrclass);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (holder.release());
|
|
|
+ } catch (const util::MemorySegmentGrown&) {
|
|
|
+ assert(!created);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- RRsetCollection collection(*(holder.get()), rrclass);
|
|
|
- const dns::ZoneCheckerCallbacks
|
|
|
- callbacks(boost::bind(&logError, &zone_name, &rrclass, _1),
|
|
|
- boost::bind(&logWarning, &zone_name, &rrclass, _1));
|
|
|
- if (!dns::checkZone(zone_name, rrclass, collection, callbacks)) {
|
|
|
- isc_throw(ZoneValidationError,
|
|
|
- "Errors found when validating zone: "
|
|
|
- << zone_name << "/" << rrclass);
|
|
|
- }
|
|
|
-
|
|
|
- return (holder.release());
|
|
|
}
|
|
|
|
|
|
// A wrapper for dns::MasterLoader used by loadZoneData() below. Essentially
|
|
@@ -257,7 +269,7 @@ loadZoneData(util::MemorySegment& mem_sgmt,
|
|
|
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEMORY_MEM_LOAD_FROM_FILE).
|
|
|
arg(zone_name).arg(rrclass).arg(zone_file);
|
|
|
|
|
|
- return (loadZoneDataInternal(mem_sgmt, rrclass, zone_name,
|
|
|
+ return (loadZoneDataInternal(mem_sgmt, rrclass, zone_name,
|
|
|
boost::bind(masterLoaderWrapper,
|
|
|
zone_file.c_str(),
|
|
|
zone_name, rrclass,
|