BIND 10 master, updated. d97165b66927e4a58979db9558e2b2f37fea17e9 Merge branch 'trac2852_3'

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Jun 4 06:17:54 UTC 2013


The branch, master has been updated
       via  d97165b66927e4a58979db9558e2b2f37fea17e9 (commit)
       via  ab78760e3dacab5fe2d4683fe991c2643fdf9877 (commit)
       via  b6925301471d003931305efa8e39c5704e1413c5 (commit)
       via  e58e863991709132601c263b8c04ea4e5a0593c5 (commit)
       via  425ee821bac86ed616075e2ac89946863132b46a (commit)
       via  66564c104a5c8a918a39e7da4cde9976160362f1 (commit)
       via  47a2fe257cc5d3d3902a7db667d1b5456bddc447 (commit)
       via  572c201a7d17bde8990ede8d986bf45e53d22842 (commit)
      from  dd34e731a3998c656995b178988e12cf0bd5c2b7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit d97165b66927e4a58979db9558e2b2f37fea17e9
Merge: dd34e73 ab78760
Author: Mukund Sivaraman <muks at isc.org>
Date:   Tue Jun 4 11:17:26 2013 +0530

    Merge branch 'trac2852_3'
    
    Conflicts:
    	src/lib/datasrc/client_list.h

-----------------------------------------------------------------------

Summary of changes:
 src/lib/datasrc/client_list.cc                     |   15 ++
 src/lib/datasrc/client_list.h                      |   17 +-
 src/lib/datasrc/tests/client_list_unittest.cc      |  176 +++++++++++++++-----
 .../isc/datasrc/configurableclientlist_python.cc   |   72 ++++++++
 4 files changed, 237 insertions(+), 43 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/client_list.cc b/src/lib/datasrc/client_list.cc
index 4302905..01f59f4 100644
--- a/src/lib/datasrc/client_list.cc
+++ b/src/lib/datasrc/client_list.cc
@@ -322,6 +322,21 @@ ConfigurableClientList::findInternal(MutableResult& candidate,
     // and the need_updater parameter is true, get the zone there.
 }
 
+void
+ConfigurableClientList::resetMemorySegment
+    (const std::string& datasrc_name,
+     ZoneTableSegment::MemorySegmentOpenMode mode,
+     ConstElementPtr config_params)
+{
+    BOOST_FOREACH(DataSourceInfo& info, data_sources_) {
+        if (info.name_ == datasrc_name) {
+            ZoneTableSegment& segment = *info.ztable_segment_;
+            segment.reset(mode, config_params);
+            break;
+        }
+    }
+}
+
 ConfigurableClientList::ZoneWriterPair
 ConfigurableClientList::getCachedZoneWriter(const Name& name,
                                             const std::string& datasrc_name)
diff --git a/src/lib/datasrc/client_list.h b/src/lib/datasrc/client_list.h
index 1887ed7..7917f3f 100644
--- a/src/lib/datasrc/client_list.h
+++ b/src/lib/datasrc/client_list.h
@@ -21,7 +21,7 @@
 #include <dns/rrclass.h>
 #include <cc/data.h>
 #include <exceptions/exceptions.h>
-#include "memory/zone_table_segment.h"
+#include <datasrc/memory/zone_table_segment.h>
 #include <datasrc/zone_table_accessor.h>
 
 #include <vector>
@@ -364,6 +364,21 @@ public:
         return (configuration_);
     }
 
+    /// \brief Resets the zone table segment for a datasource with a new
+    /// memory segment.
+    ///
+    /// See documentation of \c ZoneTableSegment interface
+    /// implementations (such as \c ZoneTableSegmentMapped) for the
+    /// syntax of \c config_params.
+    ///
+    /// \param datasrc_name The name of the data source whose segment to reset
+    /// \param mode The open mode for the new memory segment
+    /// \param config_params The configuration for the new memory segment.
+    void resetMemorySegment
+        (const std::string& datasrc_name,
+         memory::ZoneTableSegment::MemorySegmentOpenMode mode,
+         isc::data::ConstElementPtr config_params);
+
 private:
     /// \brief Convenience type shortcut
     typedef boost::shared_ptr<memory::ZoneWriter> ZoneWriterPtr;
diff --git a/src/lib/datasrc/tests/client_list_unittest.cc b/src/lib/datasrc/tests/client_list_unittest.cc
index 2701f39..a686aee 100644
--- a/src/lib/datasrc/tests/client_list_unittest.cc
+++ b/src/lib/datasrc/tests/client_list_unittest.cc
@@ -32,7 +32,9 @@
 
 #include <gtest/gtest.h>
 
+#include <boost/format.hpp>
 #include <boost/shared_ptr.hpp>
+#include <boost/interprocess/file_mapping.hpp>
 
 #include <set>
 #include <fstream>
@@ -105,7 +107,18 @@ const char* ds_zones[][3] = {
 
 const size_t ds_count = (sizeof(ds_zones) / sizeof(*ds_zones));
 
-class ListTest : public ::testing::Test {
+class SegmentType {
+public:
+    virtual ~SegmentType() {}
+    virtual ConstElementPtr getCacheConfig(bool enabled, const Name& zone)
+        const = 0;
+    virtual void reset(ConfigurableClientList& list,
+                       const std::string& datasrc_name,
+                       ZoneTableSegment::MemorySegmentOpenMode mode,
+                       ConstElementPtr config_params) = 0;
+};
+
+class ListTest : public ::testing::TestWithParam<SegmentType*> {
 public:
     ListTest() :
         rrclass_(RRClass::IN()),
@@ -121,8 +134,7 @@ public:
             "   \"type\": \"test_type\","
             "   \"params\": [\"example.org\", \"example.com\", "
             "                \"noiter.org\", \"null.org\"]"
-            "}]")),
-        ztable_segment_(ZoneTableSegment::create(rrclass_, "local"))
+            "}]"))
     {
         for (size_t i(0); i < ds_count; ++ i) {
             shared_ptr<MockDataSourceClient>
@@ -135,6 +147,24 @@ public:
         }
     }
 
+    ~ListTest() {
+        ds_info_.clear();
+        for (size_t i(0); i < ds_count; ++ i) {
+            ds_[i].reset();
+        }
+        ds_.clear();
+
+        for (size_t i(0); i < ds_count; ++ i) {
+            boost::interprocess::file_mapping::remove(
+                getMappedFilename(i).c_str());
+        }
+    }
+
+    static std::string getMappedFilename(size_t index) {
+         return (boost::str(boost::format(TEST_DATA_BUILDDIR "/test%d.mapped")
+                            % index));
+    }
+
     // Install a "fake" cached zone using a temporary underlying data source
     // client.  If 'enabled' is set to false, emulate a disabled cache, in
     // which case there will be no data in memory.
@@ -152,11 +182,7 @@ public:
         // Build new cache config to load the specified zone, and replace
         // the data source info with the new config.
         ConstElementPtr cache_conf_elem =
-            Element::fromJSON("{\"type\": \"mock\","
-                              " \"cache-enable\": " +
-                              string(enabled ? "true," : "false,") +
-                              " \"cache-zones\": "
-                              "   [\"" + zone.toText() + "\"]}");
+            GetParam()->getCacheConfig(enabled, zone);
         boost::shared_ptr<internal::CacheConfig> cache_conf(
             new internal::CacheConfig("mock", mock_client, *cache_conf_elem,
                                       true));
@@ -167,6 +193,15 @@ public:
 
         // Load the data into the zone table.
         if (enabled) {
+            const ConstElementPtr config_ztable_segment(
+                Element::fromJSON("{\"mapped-file\": \"" +
+                                  getMappedFilename(index) +
+                                  "\"}"));
+
+            GetParam()->reset(*list_, dsrc_info.name_,
+                              memory::ZoneTableSegment::CREATE,
+                              config_ztable_segment);
+
             boost::scoped_ptr<memory::ZoneWriter> writer(
                 new memory::ZoneWriter(
                     *dsrc_info.ztable_segment_,
@@ -175,6 +210,10 @@ public:
             writer->load();
             writer->install();
             writer->cleanup(); // not absolutely necessary, but just in case
+
+            GetParam()->reset(*list_, dsrc_info.name_,
+                              memory::ZoneTableSegment::READ_WRITE,
+                              config_ztable_segment);
         }
 
         // On completion of load revert to the previous state of underlying
@@ -275,11 +314,64 @@ public:
     vector<shared_ptr<MockDataSourceClient> > ds_;
     vector<ConfigurableClientList::DataSourceInfo> ds_info_;
     const ConstElementPtr config_elem_, config_elem_zones_;
-    shared_ptr<ZoneTableSegment> ztable_segment_;
 };
 
+class LocalSegmentType : public SegmentType {
+public:
+    virtual ConstElementPtr getCacheConfig(bool enabled, const Name& zone)
+        const
+    {
+        return (Element::fromJSON("{\"type\": \"mock\","
+                                  " \"cache-enable\": " +
+                                  string(enabled ? "true," : "false,") +
+                                  " \"cache-zones\": "
+                                  "   [\"" + zone.toText() + "\"]}"));
+    }
+    virtual void reset(ConfigurableClientList&, const std::string&,
+                       ZoneTableSegment::MemorySegmentOpenMode,
+                       ConstElementPtr) {
+        // We must not call reset on local ZoneTableSegments.
+    }
+};
+
+LocalSegmentType local_segment_type;
+
+INSTANTIATE_TEST_CASE_P(ListTestLocal, ListTest,
+                        ::testing::Values(static_cast<SegmentType*>(
+                                              &local_segment_type)));
+
+#ifdef USE_SHARED_MEMORY
+
+class MappedSegmentType : public SegmentType {
+public:
+    virtual ConstElementPtr getCacheConfig(bool enabled, const Name& zone)
+        const
+    {
+        return (Element::fromJSON("{\"type\": \"mock\","
+                                  " \"cache-enable\": " +
+                                  string(enabled ? "true," : "false,") +
+                                  " \"cache-type\": \"mapped\"," +
+                                  " \"cache-zones\": "
+                                  "   [\"" + zone.toText() + "\"]}"));
+    }
+    virtual void reset(ConfigurableClientList& list,
+                       const std::string& datasrc_name,
+                       ZoneTableSegment::MemorySegmentOpenMode mode,
+                       ConstElementPtr config_params) {
+        list.resetMemorySegment(datasrc_name, mode, config_params);
+    }
+};
+
+MappedSegmentType mapped_segment_type;
+
+INSTANTIATE_TEST_CASE_P(ListTestMapped, ListTest,
+                        ::testing::Values(static_cast<SegmentType*>(
+                                              &mapped_segment_type)));
+
+#endif
+
 // Test the test itself
-TEST_F(ListTest, selfTest) {
+TEST_P(ListTest, selfTest) {
     EXPECT_EQ(result::SUCCESS, ds_[0]->findZone(Name("example.org")).code);
     EXPECT_EQ(result::PARTIALMATCH,
               ds_[0]->findZone(Name("sub.example.org")).code);
@@ -293,14 +385,14 @@ TEST_F(ListTest, selfTest) {
 }
 
 // Test the list we create with empty configuration is, in fact, empty
-TEST_F(ListTest, emptyList) {
+TEST_P(ListTest, emptyList) {
     EXPECT_TRUE(list_->getDataSources().empty());
 }
 
 // Check the values returned by a find on an empty list. It should be
 // a negative answer (nothing found) no matter if we want an exact or inexact
 // match.
-TEST_F(ListTest, emptySearch) {
+TEST_P(ListTest, emptySearch) {
     // No matter what we try, we don't get an answer.
 
     // Note: we don't have operator<< for the result class, so we cannot use
@@ -317,7 +409,7 @@ TEST_F(ListTest, emptySearch) {
 
 // Put a single data source inside the list and check it can find an
 // exact match if there's one.
-TEST_F(ListTest, singleDSExactMatch) {
+TEST_P(ListTest, singleDSExactMatch) {
     list_->getDataSources().push_back(ds_info_[0]);
     // This zone is not there
     EXPECT_TRUE(negative_result_ == list_->find(Name("org."), true));
@@ -331,7 +423,7 @@ TEST_F(ListTest, singleDSExactMatch) {
 }
 
 // When asking for a partial match, we get all that the exact one, but more.
-TEST_F(ListTest, singleDSBestMatch) {
+TEST_P(ListTest, singleDSBestMatch) {
     list_->getDataSources().push_back(ds_info_[0]);
     // This zone is not there
     EXPECT_TRUE(negative_result_ == list_->find(Name("org.")));
@@ -351,7 +443,7 @@ const char* const test_names[] = {
     "With a duplicity"
 };
 
-TEST_F(ListTest, multiExactMatch) {
+TEST_P(ListTest, multiExactMatch) {
     // Run through all the multi-configurations
     for (size_t i(0); i < sizeof(test_names) / sizeof(*test_names); ++i) {
         SCOPED_TRACE(test_names[i]);
@@ -370,7 +462,7 @@ TEST_F(ListTest, multiExactMatch) {
     }
 }
 
-TEST_F(ListTest, multiBestMatch) {
+TEST_P(ListTest, multiBestMatch) {
     // Run through all the multi-configurations
     for (size_t i(0); i < 4; ++ i) {
         SCOPED_TRACE(test_names[i]);
@@ -391,7 +483,7 @@ TEST_F(ListTest, multiBestMatch) {
 }
 
 // Check the configuration is empty when the list is empty
-TEST_F(ListTest, configureEmpty) {
+TEST_P(ListTest, configureEmpty) {
     const ConstElementPtr elem(new ListElement);
     list_->configure(elem, true);
     EXPECT_TRUE(list_->getDataSources().empty());
@@ -400,7 +492,7 @@ TEST_F(ListTest, configureEmpty) {
 }
 
 // Check we can get multiple data sources and they are in the right order.
-TEST_F(ListTest, configureMulti) {
+TEST_P(ListTest, configureMulti) {
     const ConstElementPtr elem(Element::fromJSON("["
         "{"
         "   \"type\": \"type1\","
@@ -422,7 +514,7 @@ TEST_F(ListTest, configureMulti) {
 }
 
 // Check we can pass whatever we want to the params
-TEST_F(ListTest, configureParams) {
+TEST_P(ListTest, configureParams) {
     const char* params[] = {
         "true",
         "false",
@@ -447,7 +539,7 @@ TEST_F(ListTest, configureParams) {
     }
 }
 
-TEST_F(ListTest, status) {
+TEST_P(ListTest, status) {
     EXPECT_TRUE(list_->getStatus().empty());
     const ConstElementPtr elem(Element::fromJSON("["
         "{"
@@ -474,7 +566,7 @@ TEST_F(ListTest, status) {
     EXPECT_EQ("local", statuses[1].getSegmentType());
 }
 
-TEST_F(ListTest, wrongConfig) {
+TEST_P(ListTest, wrongConfig) {
     const char* configs[] = {
         // A lot of stuff missing from there
         "[{\"type\": \"test_type\", \"params\": 13}, {}]",
@@ -572,7 +664,7 @@ TEST_F(ListTest, wrongConfig) {
 }
 
 // The param thing defaults to null. Cache is not used yet.
-TEST_F(ListTest, defaults) {
+TEST_P(ListTest, defaults) {
     const ConstElementPtr elem(Element::fromJSON("["
         "{"
         "   \"type\": \"type1\""
@@ -583,7 +675,7 @@ TEST_F(ListTest, defaults) {
 }
 
 // Check we can call the configure multiple times, to change the configuration
-TEST_F(ListTest, reconfigure) {
+TEST_P(ListTest, reconfigure) {
     const ConstElementPtr empty(new ListElement);
     list_->configure(config_elem_, true);
     checkDS(0, "test_type", "{}", false);
@@ -594,7 +686,7 @@ TEST_F(ListTest, reconfigure) {
 }
 
 // Make sure the data source error exception from the factory is propagated
-TEST_F(ListTest, dataSrcError) {
+TEST_P(ListTest, dataSrcError) {
     const ConstElementPtr elem(Element::fromJSON("["
         "{"
         "   \"type\": \"error\""
@@ -606,7 +698,7 @@ TEST_F(ListTest, dataSrcError) {
 }
 
 // Check we can get the cache
-TEST_F(ListTest, configureCacheEmpty) {
+TEST_P(ListTest, configureCacheEmpty) {
     const ConstElementPtr elem(Element::fromJSON("["
         "{"
         "   \"type\": \"type1\","
@@ -628,7 +720,7 @@ TEST_F(ListTest, configureCacheEmpty) {
 }
 
 // But no cache if we disallow it globally
-TEST_F(ListTest, configureCacheDisabled) {
+TEST_P(ListTest, configureCacheDisabled) {
     const ConstElementPtr elem(Element::fromJSON("["
         "{"
         "   \"type\": \"type1\","
@@ -650,7 +742,7 @@ TEST_F(ListTest, configureCacheDisabled) {
 }
 
 // Put some zones into the cache
-TEST_F(ListTest, cacheZones) {
+TEST_P(ListTest, cacheZones) {
     const ConstElementPtr elem(Element::fromJSON("["
         "{"
         "   \"type\": \"type1\","
@@ -684,7 +776,7 @@ TEST_F(ListTest, cacheZones) {
 
 // Check the caching handles misbehaviour from the data source and
 // misconfiguration gracefully
-TEST_F(ListTest, badCache) {
+TEST_P(ListTest, badCache) {
     list_->configure(config_elem_, true);
     checkDS(0, "test_type", "{}", false);
     // First, the zone is not in the data source. configure() should still
@@ -733,7 +825,7 @@ TEST_F(ListTest, badCache) {
 }
 
 // This test relies on the property of mapped type of cache.
-TEST_F(ListTest,
+TEST_P(ListTest,
 #ifdef USE_SHARED_MEMORY
        cacheInNonWritableSegment
 #else
@@ -760,7 +852,7 @@ TEST_F(ListTest,
               doReload(Name("example.org")));
 }
 
-TEST_F(ListTest, masterFiles) {
+TEST_P(ListTest, masterFiles) {
     const ConstElementPtr elem(Element::fromJSON("["
         "{"
         "   \"type\": \"MasterFiles\","
@@ -785,7 +877,7 @@ TEST_F(ListTest, masterFiles) {
 }
 
 // Test the names are set correctly and collission is detected.
-TEST_F(ListTest, names) {
+TEST_P(ListTest, names) {
     // Explicit name
     const ConstElementPtr elem1(Element::fromJSON("["
         "{"
@@ -832,7 +924,7 @@ TEST_F(ListTest, names) {
                  ConfigurableClientList::ConfigurationError);
 }
 
-TEST_F(ListTest, BadMasterFile) {
+TEST_P(ListTest, BadMasterFile) {
     // Configuration should succeed, and the good zones in the list
     // below should be loaded.  Bad zones won't be "loaded" in its usual sense,
     // but are still recognized with conceptual "empty" data.
@@ -908,7 +1000,7 @@ ListTest::doReload(const Name& origin, const string& datasrc_name) {
 }
 
 // Test we can reload a zone
-TEST_F(ListTest, reloadSuccess) {
+TEST_P(ListTest, reloadSuccess) {
     list_->configure(config_elem_zones_, true);
     const Name name("example.org");
     prepareCache(0, name);
@@ -928,7 +1020,7 @@ TEST_F(ListTest, reloadSuccess) {
 }
 
 // The cache is not enabled. The load should be rejected.
-TEST_F(ListTest, reloadNotAllowed) {
+TEST_P(ListTest, reloadNotAllowed) {
     list_->configure(config_elem_zones_, false);
     const Name name("example.org");
     // We put the cache in even when not enabled. This won't confuse the thing.
@@ -948,7 +1040,7 @@ TEST_F(ListTest, reloadNotAllowed) {
 }
 
 // Similar to the previous case, but the cache is disabled in config.
-TEST_F(ListTest, reloadNotEnabled) {
+TEST_P(ListTest, reloadNotEnabled) {
     list_->configure(config_elem_zones_, true);
     const Name name("example.org");
     // We put the cache, actually disabling it.
@@ -959,7 +1051,7 @@ TEST_F(ListTest, reloadNotEnabled) {
 }
 
 // Test several cases when the zone does not exist
-TEST_F(ListTest, reloadNoSuchZone) {
+TEST_P(ListTest, reloadNoSuchZone) {
     list_->configure(config_elem_zones_, true);
     const Name name("example.org");
     // We put the cache in even when not enabled. This won't confuse the
@@ -990,7 +1082,7 @@ TEST_F(ListTest, reloadNoSuchZone) {
 
 // Check we gracefully reject reloading (i.e. no exception) when a zone
 // disappeared in the underlying data source when we want to reload it
-TEST_F(ListTest, reloadZoneGone) {
+TEST_P(ListTest, reloadZoneGone) {
     list_->configure(config_elem_zones_, true);
     const Name name("example.org");
     // We put in a cache for non-existent zone. This emulates being loaded
@@ -1011,7 +1103,7 @@ TEST_F(ListTest, reloadZoneGone) {
               list_->find(name).finder_->find(name, RRType::SOA())->code);
 }
 
-TEST_F(ListTest, reloadNewZone) {
+TEST_P(ListTest, reloadNewZone) {
     // Test the case where a zone to be cached originally doesn't exist
     // in the underlying data source and is added later.  reload() will
     // succeed once it's available in the data source.
@@ -1038,7 +1130,7 @@ TEST_F(ListTest, reloadNewZone) {
 }
 
 // The underlying data source throws. Check we don't modify the state.
-TEST_F(ListTest, reloadZoneThrow) {
+TEST_P(ListTest, reloadZoneThrow) {
     list_->configure(config_elem_zones_, true);
     const Name name("noiter.org");
     prepareCache(0, name);
@@ -1052,7 +1144,7 @@ TEST_F(ListTest, reloadZoneThrow) {
               list_->find(name).finder_->find(name, RRType::SOA())->code);
 }
 
-TEST_F(ListTest, reloadNullIterator) {
+TEST_P(ListTest, reloadNullIterator) {
     list_->configure(config_elem_zones_, true);
     const Name name("null.org");
     prepareCache(0, name);
@@ -1067,7 +1159,7 @@ TEST_F(ListTest, reloadNullIterator) {
 }
 
 // Test we can reload the master files too (special-cased)
-TEST_F(ListTest, reloadMasterFile) {
+TEST_P(ListTest, reloadMasterFile) {
     const char* const install_cmd = INSTALL_PROG " -c " TEST_DATA_DIR
         "/root.zone " TEST_DATA_BUILDDIR "/root.zone.copied";
     if (system(install_cmd) != 0) {
@@ -1102,7 +1194,7 @@ TEST_F(ListTest, reloadMasterFile) {
                                                    RRType::TXT())->code);
 }
 
-TEST_F(ListTest, reloadByDataSourceName) {
+TEST_P(ListTest, reloadByDataSourceName) {
     // We use three data sources (and their clients).  2nd and 3rd have
     // the same name of the zones.
     const ConstElementPtr config_elem = Element::fromJSON(
diff --git a/src/lib/python/isc/datasrc/configurableclientlist_python.cc b/src/lib/python/isc/datasrc/configurableclientlist_python.cc
index 81da7d8..875d7e0 100644
--- a/src/lib/python/isc/datasrc/configurableclientlist_python.cc
+++ b/src/lib/python/isc/datasrc/configurableclientlist_python.cc
@@ -27,6 +27,7 @@
 
 #include <dns/python/rrclass_python.h>
 #include <dns/python/name_python.h>
+#include <dns/python/pydnspp_common.h>
 
 #include <datasrc/client_list.h>
 
@@ -38,7 +39,9 @@
 using namespace std;
 using namespace isc::util::python;
 using namespace isc::datasrc;
+using namespace isc::datasrc::memory;
 using namespace isc::datasrc::python;
+using namespace isc::dns::python;
 
 //
 // ConfigurableClientList
@@ -116,6 +119,39 @@ ConfigurableClientList_configure(PyObject* po_self, PyObject* args) {
 }
 
 PyObject*
+ConfigurableClientList_resetMemorySegment(PyObject* po_self, PyObject* args) {
+    s_ConfigurableClientList* self =
+        static_cast<s_ConfigurableClientList*>(po_self);
+    try {
+        const char* datasrc_name_p;
+        int mode_int;
+        const char* config_p;
+        if (PyArg_ParseTuple(args, "sis", &datasrc_name_p, &mode_int,
+                             &config_p)) {
+            const std::string datasrc_name(datasrc_name_p);
+            const isc::data::ConstElementPtr
+                config(isc::data::Element::fromJSON(std::string(config_p)));
+            ZoneTableSegment::MemorySegmentOpenMode mode =
+                static_cast<ZoneTableSegment::MemorySegmentOpenMode>
+                    (mode_int);
+            self->cppobj->resetMemorySegment(datasrc_name, mode, config);
+            Py_RETURN_NONE;
+        }
+    } catch (const isc::data::JSONError& jse) {
+        const string ex_what(std::string("JSON parse error in memory segment"
+                               " configuration: ") + jse.what());
+        PyErr_SetString(getDataSourceException("Error"), ex_what.c_str());
+    } catch (const std::exception& exc) {
+        PyErr_SetString(getDataSourceException("Error"), exc.what());
+    } catch (...) {
+        PyErr_SetString(getDataSourceException("Error"),
+                        "Unknown C++ exception");
+    }
+
+    return (NULL);
+}
+
+PyObject*
 ConfigurableClientList_find(PyObject* po_self, PyObject* args) {
     s_ConfigurableClientList* self =
         static_cast<s_ConfigurableClientList*>(po_self);
@@ -191,6 +227,19 @@ configuration preserved.\n\
 Parameters:\n\
   configuration     The configuration, as a JSON encoded string.\
   allow_cache       If caching is allowed." },
+    { "reset_memory_segment", ConfigurableClientList_resetMemorySegment,
+      METH_VARARGS,
+        "reset_memory_segment(datasrc_name, mode, config_params) -> None\n\
+\n\
+Wrapper around C++ ConfigurableClientList::resetMemorySegment\n\
+\n\
+This resets the zone table segment for a datasource with a new\n\
+memory segment.\n\
+\n\
+Parameters:\n\
+  datasrc_name      The name of the data source whose segment to reset.\
+  mode              The open mode for the new memory segment.\
+  config_params     The configuration for the new memory segment, as a JSON encoded string." },
     { "find", ConfigurableClientList_find, METH_VARARGS,
 "find(zone, want_exact_match=False, want_finder=True) -> datasrc_client,\
 zone_finder, exact_match\n\
@@ -300,6 +349,29 @@ initModulePart_ConfigurableClientList(PyObject* mod) {
     }
     Py_INCREF(&configurableclientlist_type);
 
+    // FIXME: These should eventually be moved to the ZoneTableSegment
+    // class when we add Python bindings for the memory data source
+    // specific bits. But for now, we add these enums here to support
+    // reloading a zone table segment.
+    try {
+        installClassVariable(configurableclientlist_type, "CREATE",
+                             Py_BuildValue("I", ZoneTableSegment::CREATE));
+        installClassVariable(configurableclientlist_type, "READ_WRITE",
+                             Py_BuildValue("I", ZoneTableSegment::READ_WRITE));
+        installClassVariable(configurableclientlist_type, "READ_ONLY",
+                             Py_BuildValue("I", ZoneTableSegment::READ_ONLY));
+    } catch (const std::exception& ex) {
+        const std::string ex_what =
+            "Unexpected failure in ConfigurableClientList initialization: " +
+            std::string(ex.what());
+        PyErr_SetString(po_IscException, ex_what.c_str());
+        return (false);
+    } catch (...) {
+        PyErr_SetString(PyExc_SystemError,
+            "Unexpected failure in ConfigurableClientList initialization");
+        return (false);
+    }
+
     return (true);
 }
 



More information about the bind10-changes mailing list