Commit 615df6d2 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3534] Commit and rollback the staging configuration.

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