}
// 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);
}
ControlledDhcpv4Srv::~ControlledDhcpv4Srv() {
cleanup();
-
+
server_ = NULL; // forget this instance. Noone should call any handlers at
// this stage.
}
// Rollback changes as the configuration parsing failed.
if (rollback) {
globalContext().reset(new ParserContext(original_context));
- CfgMgr::instance().rollback();
return (answer);
}
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 '"
}
// 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);
}
// Rollback changes as the configuration parsing failed.
if (rollback) {
globalContext().reset(new ParserContext(original_context));
- CfgMgr::instance().rollback();
return (answer);
}
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 '"