Browse Source

[2836] More retries on segment growing

Michal 'vorner' Vaner 12 years ago
parent
commit
cdb6afba87

+ 41 - 29
src/lib/datasrc/memory/zone_data_loader.cc

@@ -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,

+ 6 - 0
src/lib/datasrc/memory/zone_data_updater.cc

@@ -234,6 +234,12 @@ ZoneDataUpdater::setupNSEC3(const ConstRRsetPtr rrset) {
     NSEC3Data* nsec3_data = zone_data_->getNSEC3Data();
     if (nsec3_data == NULL) {
         nsec3_data = NSEC3Data::create(mem_sgmt_, zone_name_, nsec3_rdata);
+        // The create above might have relocated data. So get it again,
+        // just to make sure.
+        zone_data_ =
+            static_cast<ZoneData*>(mem_sgmt_.
+                                   getNamedAddress("updater_zone_data").
+                                   second);
         zone_data_->setNSEC3Data(nsec3_data);
         zone_data_->setSigned(true);
     } else {