]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[3534] Commit and rollback the staging configuration.
authorMarcin Siodelski <marcin@isc.org>
Tue, 2 Sep 2014 18:47:10 +0000 (20:47 +0200)
committerMarcin Siodelski <marcin@isc.org>
Tue, 2 Sep 2014 18:47:10 +0000 (20:47 +0200)
src/bin/dhcp4/ctrl_dhcp4_srv.cc
src/bin/dhcp4/json_config_parser.cc
src/bin/dhcp4/kea_controller.cc
src/bin/dhcp6/ctrl_dhcp6_srv.cc
src/bin/dhcp6/json_config_parser.cc
src/bin/dhcp6/kea_controller.cc

index 10cf95b7f6ef7f77591c9ff5c42531e8f5e63899..a0c4aeecec64405e5f52a147a2571d19fa933f71 100644 (file)
@@ -145,19 +145,16 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
     }
 
     // Configuration may change active interfaces. Therefore, we have to reopen
-    // sockets according to new configuration. This operation is not exception
-    // safe and we really don't want to emit exceptions to whoever called this
-    // method. Instead, catch an exception and create appropriate answer.
-    try {
-        CfgMgr::instance().getCurrentCfg()->getCfgIface()
-            .openSockets(CfgIface::V4, srv->getPort(),
-                         getInstance()->useBroadcast());
+    // sockets according to new configuration. It is possible that this
+    // operation will fail for some interfaces but the openSockets function
+    // guards against exceptions and invokes a callback function to
+    // log warnings. Since we allow that this fails for some interfaces there
+    // is no need to rollback configuration if socket fails to open on any
+    // of the interfaces.
+    CfgMgr::instance().getStagingCfg()->
+        getCfgIface().openSockets(CfgIface::V4, srv->getPort(),
+                                  getInstance()->useBroadcast());
 
-    } catch (std::exception& ex) {
-        err << "failed to open sockets after server reconfiguration: "
-            << ex.what();
-        answer = isc::config::createAnswer(1, err.str());
-    }
     return (answer);
 }
 
@@ -177,7 +174,7 @@ void ControlledDhcpv4Srv::shutdown() {
 
 ControlledDhcpv4Srv::~ControlledDhcpv4Srv() {
     cleanup();
-    
+
     server_ = NULL; // forget this instance. Noone should call any handlers at
                     // this stage.
 }
index 7dc972490c5997acc2a1848483b8ee87c4693ede..abb54772d2359441a61c7b315034e27153207d4a 100644 (file)
@@ -648,7 +648,6 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
     // Rollback changes as the configuration parsing failed.
     if (rollback) {
         globalContext().reset(new ParserContext(original_context));
-        CfgMgr::instance().rollback();
         return (answer);
     }
 
index 2098eb1f368372304cf0a13473c355b9c0532d40..66317fb1b7698890b8fa28159ce84635965162b2 100644 (file)
@@ -102,7 +102,14 @@ void configure(const std::string& file_name) {
             isc_throw(isc::BadValue, reason);
         }
 
+        // Configuration successful.
+        CfgMgr::instance().commit();
+
     }  catch (const std::exception& ex) {
+        // If configuration failed at any stage, we drop the staging
+        // configuration and continue to use the previous one.
+        CfgMgr::instance().rollback();
+
         LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL)
             .arg(file_name).arg(ex.what());
         isc_throw(isc::BadValue, "configuration error using file '"
index 1ba9ba8934f066a7e96ffff51b1bab39c0d0cd98..e351e502b9ea8ec17ba929dfca09061b8573917e 100644 (file)
@@ -140,19 +140,14 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
     }
 
     // Configuration may change active interfaces. Therefore, we have to reopen
-    // sockets according to new configuration. This operation is not exception
-    // safe and we really don't want to emit exceptions to the callback caller.
-    // Instead, catch an exception and create appropriate answer.
-    try {
-        CfgMgr::instance().getCurrentCfg()->getCfgIface()
-            .openSockets(CfgIface::V6, srv->getPort());
-
-    } catch (const std::exception& ex) {
-        std::ostringstream err;
-        err << "failed to open sockets after server reconfiguration: "
-            << ex.what();
-        answer = isc::config::createAnswer(1, err.str());
-    }
+    // sockets according to new configuration. It is possible that this
+    // operation will fail for some interfaces but the openSockets function
+    // guards against exceptions and invokes a callback function to
+    // log warnings. Since we allow that this fails for some interfaces there
+    // is no need to rollback configuration if socket fails to open on any
+    // of the interfaces.
+    CfgMgr::instance().getStagingCfg()->
+        getCfgIface().openSockets(CfgIface::V6, srv->getPort());
 
     return (answer);
 }
index c45724f5ba10eee69682afd7ed6b02430993d166..ea98266bf3b0d751f9e0c693b63951178e7a20fa 100644 (file)
@@ -849,7 +849,6 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
     // Rollback changes as the configuration parsing failed.
     if (rollback) {
         globalContext().reset(new ParserContext(original_context));
-        CfgMgr::instance().rollback();
         return (answer);
     }
 
index 58ca5ad022ee75c00508a8010bd913b8fdbc93dc..603b3c7823edebfc351f581baa4ade682a1dcbe5 100644 (file)
@@ -106,7 +106,14 @@ void configure(const std::string& file_name) {
             isc_throw(isc::BadValue, reason);
         }
 
+        // Configuration successful.
+        CfgMgr::instance().commit();
+
     }  catch (const std::exception& ex) {
+        // If configuration failed at any stage, we drop the staging
+        // configuration and continue to use the previous one.
+        CfgMgr::instance().rollback();
+
         LOG_ERROR(dhcp6_logger, DHCP6_CONFIG_LOAD_FAIL)
             .arg(file_name).arg(ex.what());
         isc_throw(isc::BadValue, "configuration error using file '"