Commit 7e7ea275 authored by Marcin Siodelski's avatar Marcin Siodelski

[3971] DHCPv6 server uses TimerMgr to run LFC timers.

parent 7f5f1a8a
......@@ -118,8 +118,34 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
return (no_srv);
}
// We're going to modify the timers configuration. This is not allowed
// when the thread is running.
try {
TimerMgr::instance()->stopThread();
} catch (const std::exception& ex) {
std::ostringstream err;
err << "Unable to stop worker thread running timers: "
<< ex.what() << ".";
return (isc::config::createAnswer(1, err.str()));
}
ConstElementPtr answer = configureDhcp6Server(*srv, config);
// Start worker thread if there are any timers installed. Note that
// we also start worker thread when the reconfiguration failed, because
// in that case we continue using an old configuration and the server
// should still run installed timers.
if (TimerMgr::instance()->timersCount() > 0) {
try {
TimerMgr::instance()->startThread();
} catch (const std::exception& ex) {
std::ostringstream err;
err << "Unable to start worker thread running timers: "
<< ex.what() << ".";
return (isc::config::createAnswer(1, err.str()));
}
}
// Check that configuration was successful. If not, do not reopen sockets
// and don't bother with DDNS stuff.
try {
......@@ -156,7 +182,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
}
ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t port)
: Dhcpv6Srv(port) {
: Dhcpv6Srv(port), io_service_(), timer_mgr_(TimerMgr::instance()) {
if (server_) {
isc_throw(InvalidOperation,
"There is another Dhcpv6Srv instance already.");
......@@ -198,6 +224,9 @@ void ControlledDhcpv6Srv::shutdown() {
ControlledDhcpv6Srv::~ControlledDhcpv6Srv() {
cleanup();
// Stop worker thread running timers, if it is running.
timer_mgr_->stopThread();
// Close the command socket (if it exists).
CommandMgr::instance().closeCommandSocket();
......
......@@ -18,6 +18,7 @@
#include <asiolink/asiolink.h>
#include <cc/data.h>
#include <cc/command_interpreter.h>
#include <dhcpsrv/timer_mgr.h>
#include <dhcp6/dhcp6_srv.h>
namespace isc {
......@@ -101,12 +102,7 @@ public:
return (server_);
}
protected:
/// @brief Static pointer to the sole instance of the DHCP server.
///
/// This is required for config and command handlers to gain access to
/// the server. Some of them need to be static methods.
static ControlledDhcpv6Srv* server_;
private:
/// @brief Callback that will be called from iface_mgr when data
/// is received over control socket.
......@@ -116,9 +112,6 @@ protected:
/// (that was sent from some yet unspecified sender).
static void sessionReader(void);
/// @brief IOService object, used for all ASIO operations.
isc::asiolink::IOService io_service_;
/// @brief handler for processing 'shutdown' command
///
/// This handler processes shutdown command, which initializes shutdown
......@@ -156,6 +149,22 @@ protected:
isc::data::ConstElementPtr
commandConfigReloadHandler(const std::string& command,
isc::data::ConstElementPtr args);
/// @brief Static pointer to the sole instance of the DHCP server.
///
/// This is required for config and command handlers to gain access to
/// the server. Some of them need to be static methods.
static ControlledDhcpv6Srv* server_;
/// @brief IOService object, used for all ASIO operations.
isc::asiolink::IOService io_service_;
/// @brief Instance of the @c TimerMgr.
///
/// Shared pointer to the instance of timer @c TimerMgr is held here to
/// make sure that the @c TimerMgr outlives instance of this class.
TimerMgrPtr timer_mgr_;
};
}; // namespace isc::dhcp
......
......@@ -16,6 +16,8 @@
CFG_FILE=@abs_top_builddir@/src/bin/dhcp6/tests/test_config.json
# Path to the Kea log file.
LOG_FILE=@abs_top_builddir@/src/bin/dhcp6/tests/test.log
# Path to the Kea lease file.
LEASE_FILE=@abs_top_builddir@/src/bin/dhcp6/tests/test_leases.csv
# Expected version
EXPECTED_VERSION="@PACKAGE_VERSION@"
# Kea configuration to be stored in the configuration file.
......@@ -31,7 +33,9 @@ CONFIG="{
\"lease-database\":
{
\"type\": \"memfile\",
\"persist\": false
\"name\": \"$LEASE_FILE\",
\"persist\": false,
\"lfc-interval\": 0
},
\"subnet6\": [
{
......@@ -277,9 +281,110 @@ returned %d."
test_finish 0
}
# This test verifies that DHCPv6 can be configured to run lease file cleanup
# periodially.
lfc_timer_test() {
# Log the start of the test and print test name.
test_start "dhcpv6_srv.lfc_timer_test"
# Remove dangling Kea instances and remove log files.
cleanup
# Create a configuration with the LFC enabled, by replacing the section
# with the lfc-interval and persist parameters.
LFC_CONFIG=$(printf "${CONFIG}" | sed -e 's/\"lfc-interval\": 0/\"lfc-interval\": 1/g' \
| sed -e 's/\"persist\": false/\"persist\": true/g')
# Create new configuration file.
create_config "${LFC_CONFIG}"
# Instruct Kea to log to the specific file.
set_logger
# Start Kea.
start_kea ${bin_path}/${bin}
# Wait up to 20s for Kea to start.
wait_for_kea 20
if [ ${_WAIT_FOR_KEA} -eq 0 ]; then
printf "ERROR: timeout waiting for Kea to start.\n"
clean_exit 1
fi
# Check if it is still running. It could have terminated (e.g. as a result
# of configuration failure).
get_pids ${bin}
if [ ${_GET_PIDS_NUM} -ne 1 ]; then
printf "ERROR: expected one Kea process to be started. Found %d processes\
started.\n" ${_GET_PIDS_NUM}
clean_exit 1
fi
# Check if Kea emits the log message indicating that LFC is started.
wait_for_message 10 "DHCPSRV_MEMFILE_LFC_EXECUTE" 1
if [ ${_WAIT_FOR_MESSAGE} -eq 0 ]; then
printf "ERROR: Server did not execute LFC.\n"
clean_exit 1
fi
# Give it a short time to run.
sleep 1
# Modify the interval.
LFC_CONFIG=$(printf "${CONFIG}" | sed -e 's/\"lfc-interval\": 1/\"lfc-interval\": 2/g')
# Create new configuration file.
create_config "${LFC_CONFIG}"
# Reconfigure the server with SIGHUP.
send_signal 1 ${bin}
# There should be two occurrences of the DHCP4_CONFIG_COMPLETE messages.
# Wait for it up to 10s.
wait_for_message 10 "DHCP6_CONFIG_COMPLETE" 2
# After receiving SIGHUP the server should get reconfigured and the
# reconfiguration should be noted in the log file. We should now
# have two configurations logged in the log file.
if [ ${_WAIT_FOR_MESSAGE} -eq 0 ]; then
printf "ERROR: server hasn't been reconfigured.\n"
clean_exit 1
else
printf "Server successfully reconfigured.\n"
fi
# Make sure the server is still operational.
get_pids ${bin}
if [ ${_GET_PIDS_NUM} -ne 1 ]; then
printf "ERROR: Kea process was killed when attempting reconfiguration.\n"
clean_exit 1
fi
# Wait for the LFC to run the second time.
wait_for_message 10 "DHCPSRV_MEMFILE_LFC_EXECUTE" 2
if [ ${_WAIT_FOR_MESSAGE} -eq 0 ]; then
printf "ERROR: Server did not execute LFC.\n"
clean_exit 1
fi
# Send signal to Kea SIGTERM
send_signal 15 ${bin}
# Wait up to 10s for the server's graceful shutdown. The graceful shut down
# should be recorded in the log file with the appropriate message.
wait_for_message 10 "DHCP6_SHUTDOWN" 1
if [ ${_WAIT_FOR_MESSAGE} -eq 0 ]; then
printf "ERROR: Server did not record shutdown in the log.\n"
clean_exit 1
fi
# Make sure the server is down.
wait_for_server_down 5 ${bin}
assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
"Expected wait_for_server_down return %d, returned %d"
# All ok. Shut down Kea and exit.
test_finish 0
}
server_pid_file_test "${CONFIG}" DHCP6_ALREADY_RUNNING
dynamic_reconfiguration_test
shutdown_test "dhcpv6.sigterm_test" 15
shutdown_test "dhcpv6.sigint_test" 2
version_test "dhcpv6.version"
logger_vars_test "dhcpv6.variables"
lfc_timer_test
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