Also, improved some LFC unit tests.
-// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
#include <hooks/hooks_manager.h>
#include <dhcp4/json_config_parser.h>
#include <dhcpsrv/cfgmgr.h>
-#include <dhcpsrv/timer_mgr.h>
#include <config/command_mgr.h>
#include <stats/stats_mgr.h>
return (isc::config::createAnswer(1, err.str()));
}
- TimerMgr::instance()->stopThread();
+ // 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) {
+ err << "Unable to stop worker thread running timers: "
+ << ex.what() << ".";
+ return (isc::config::createAnswer(1, err.str()));
+ }
+
ConstElementPtr answer = configureDhcp4Server(*srv, config);
- TimerMgr::instance()->startThread();
+
+ // 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) {
+ 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.
}
ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t port /*= DHCP4_SERVER_PORT*/)
- :Dhcpv4Srv(port) {
+ : Dhcpv4Srv(port), io_service_(), timer_mgr_(TimerMgr::instance()) {
if (getInstance()) {
isc_throw(InvalidOperation,
"There is another Dhcpv4Srv instance already.");
ControlledDhcpv4Srv::~ControlledDhcpv4Srv() {
cleanup();
+ // Stop worker thread running timers, if it is running.
+ timer_mgr_->stopThread();
+
// Close the command socket (if it exists).
CommandMgr::instance().closeCommandSocket();
#include <asiolink/asiolink.h>
#include <cc/data.h>
#include <cc/command_interpreter.h>
+#include <dhcpsrv/timer_mgr.h>
#include <dhcp4/dhcp4_srv.h>
namespace isc {
}
-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
- static ControlledDhcpv4Srv* server_;
-
+private:
/// @brief Callback that will be called from iface_mgr when data
/// is received over control socket.
///
/// (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
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
+ static ControlledDhcpv4Srv* 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
#include <dhcpsrv/parsers/host_reservation_parser.h>
#include <dhcpsrv/parsers/host_reservations_list_parser.h>
#include <dhcpsrv/parsers/ifaces_config_parser.h>
+#include <dhcpsrv/timer_mgr.h>
#include <config/command_mgr.h>
#include <util/encode/hex.h>
#include <util/strutil.h>
// so newly recreated configuration starts with first subnet-id equal 1.
Subnet::resetSubnetID();
+ // Remove any existing timers.
+ TimerMgr::instance()->unregisterTimers();
+
// Some of the values specified in the configuration depend on
// other values. Typically, the values in the subnet4 structure
// depend on the global values. Also, option values configuration
test_finish 0
}
-# This test verifies that DHCPv4 can be reconfigured with a SIGHUP signal.
+# This test verifies that DHCPv4 can be configured to run lease file cleanup
+# periodially.
lfc_timer_test() {
# Log the start of the test and print test name.
test_start "dhcpv4_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 parameter.
+ # 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')
- echo ${LFC_CONFIG}
# Create new configuration file.
create_config "${LFC_CONFIG}"
# Instruct Kea to log to the specific file.
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
- sleep 3
+ # 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 "DHCP4_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}