Commit 24267d20 authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[3769] DHPCv4 now uses PID file, made pid test common

src/lib/testutils/dhcp_test_lib.sh.in
    - server_pid_file_test() - common test for any server
    to verify PID file management

src/bin/d2/tests/d2_process_tests.sh.in
    remmoved duplicate_server_start_test
    now calls server_pid_file_test

Added PID file creation to DHCP4
    src/bin/dhcp4/dhcp4_messages.mes
    -  added log DHCP4_ALREADY_RUNNING

    src/bin/dhcp4/main.cc
    - added logic to create the PID and catch
    exception specific to PID conflict

    src/bin/dhcp4/tests/Makefile.am
    - exports KEA_PIDFILE_DIR

    src/bin/dhcp4/tests/dhcp4_process_tests.sh.in
    - added call to server_pid_file_test

    src/bin/dhcp4/tests/dhcp4_unittests.cc
    - main(int argc, char* argv[])
    sets env var KEA_PIDFILE_DIR
parent d743c5f2
......@@ -100,6 +100,15 @@ documented in preceding log entries.
This is an informational message issued after DHCP_DDNS has submitted DNS
mapping additions which were received and accepted by an appropriate DNS server.
% DHCP_DDNS_ALREADY_RUNNING %1 already running? %2
This is an error message that occurs when DHCP_DDNS encounters a pre-existing
PID file which contains the PID of a running process. This most likely
indicates an attempt to start a second instance of DHCP_DDNS using the
same configuration file. It is possible, though unlikely, that the PID file
is a remnant left behind by a server crash or power failure and the PID
it contains refers to a process other than DHCP_DDNS. In such an event,
it would be necessary to manually remove the PID file.
% DHCP_DDNS_AT_MAX_TRANSACTIONS application has %1 queued requests but has reached maximum number of %2 concurrent transactions
This is a debug message that indicates that the application has DHCP_DDNS
requests in the queue but is working as many concurrent requests as allowed.
......@@ -277,6 +286,14 @@ no configured DDNS domains in the DHCP_DDNS configuration. Either the DHCP_DDNS
configuration needs to be updated or the source of the FQDN itself should be
investigated.
% DHCP_DDNS_PID_FILE_ERROR %1 could not create a PID file: %2
This is an error message that occurs when DHCP_DDNS is unable to create
its PID file. The log message should contain details sufficient to
determine the underlying cause. The most likely culprits are that
some portion of the pathname does not exist or a permissions issue. The
default path is determined by --localstatedir configure paramter but
may be overridden by setting environment variable, KEA_PIDFILE_DIR.
% DHCP_DDNS_PROCESS_INIT application init invoked
This is a debug message issued when the DHCP-DDNS application enters
its initialization method.
......@@ -492,20 +509,3 @@ server.
% DHCP_DDNS_UPDATE_RESPONSE_RECEIVED Request ID %1: to server: %2 status: %3
This is a debug message issued when DHCP_DDNS receives sends a DNS update
response from a DNS server.
% DHCP_DDNS_ALREADY_RUNNING %1 already running? %2
This is an error message that occurs when DHCP_DDNS encounters a pre-existing
PID file which contains the PID of a running process. This most likely
indicates an attempt to start a second instance of DHCP_DDNS using the
same configuration file. It is possible, the unlikely that the PID file
is a remnant left behind by a server crash or power failure and the PID
it contains refers to a process other than DHCP_DDNS. In such an event,
it would be necessary to manually remove the PID file.
% DHCP_DDNS_PID_FILE_ERROR %1 could not create a PID file: %2
This is an error message that occurs when DHCP_DDNS is unable to create
its PID file. The log message should contain details sufficient to
determine the underlying cause. The most likely culprits are that
some portion of the pathname does not exist or a permissions issue. The
default path is determined by --localstatedir configure paramter but
may be overridden by setting environment variable, KEA_PIDFILE_DIR.
......@@ -235,50 +235,9 @@ shutdown_test() {
test_finish 0
}
# This test verifies if only one D2 per config can be started.
dupcliate_server_start_test() {
# Log the start of the test and print test name.
test_start "dhcp_ddns.duplicate_server_start_test"
# Remove dangling D2 instances and remove log files.
cleanup
# Create new configuration file.
create_config "${CONFIG}"
# Instruct D2 to log to the specific file.
set_logger
# Start D2.
start_kea ${bin_path}/${bin}
# Wait up to 20s for D2 to start.
wait_for_kea 20
if [ ${_WAIT_FOR_KEA} -eq 0 ]; then
printf "ERROR: timeout waiting for D2 to start.\n"
clean_exit 1
fi
# Verify server is still running
verify_server_pid ${bin} ${CFG_FILE}
printf "PID file is [%s], PID is [%d]" ${_SERVER_PID_FILE} ${_SERVER_PID}
# Now try to start a second one
start_kea ${bin_path}/${bin}
wait_for_message 10 "DHCP_DDNS_ALREADY_RUNNING" 1
if [ ${_WAIT_FOR_MESSAGE} -eq 0 ]; then
printf "ERROR: Second D2 instance started? PID conflict not reported.\n"
clean_exit 1
fi
# Verify server is still running
verify_server_pid ${bin} ${CFG_FILE}
# All ok. Shut down D2 and exit.
test_finish 0
}
server_pid_file_test "${CONFIG}" DHCP_DDNS_ALREADY_RUNNING
dynamic_reconfiguration_test
shutdown_test "dhcp-ddns.sigterm_test" 15
shutdown_test "dhcp-ddns.sigint_test" 2
version_test "dhcp-ddns.version"
logger_vars_test "dhcp-ddns.variables"
dupcliate_server_start_test
......@@ -19,6 +19,16 @@ This message is printed when DHCPv4 server enabled an interface to be used
to receive DHCPv4 traffic. IPv4 socket on this interface will be opened once
Interface Manager starts up procedure of opening sockets.
% DHCP4_ALREADY_RUNNING %1 already running? %2
This is an error message that occurs when the DHCPv4 server encounters
a pre-existing PID file which contains the PID of a running process.
This most likely indicates an attempt to start a second instance of
the server using the same configuration file. It is possible, though
unlikely that the PID file is a remnant left behind by a server crash or
power failure and the PID it contains refers to a process other than
the server. In such an event, it would be necessary to manually remove
the PID file.
% DHCP4_BUFFER_RECEIVED received buffer from %1:%2 to %3:%4 over interface %5
This debug message is logged when the server has received a packet
over the socket. When the message is logged the contents of the received
......
......@@ -168,9 +168,6 @@ namespace dhcp {
void
ControlledDhcpv4Srv::init(const std::string& file_name) {
// Call parent class's init to initialize file name.
Daemon::init(file_name);
// Configure the server using JSON file.
configure(file_name);
......
......@@ -118,6 +118,7 @@ main(int argc, char* argv[]) {
usage();
}
// Configuration file is required.
if (config_file.empty()) {
cerr << "Configuration file not specified." << endl;
......@@ -125,7 +126,6 @@ main(int argc, char* argv[]) {
}
int ret = EXIT_SUCCESS;
try {
// It is important that we set a default logger name because this name
// will be used when the user doesn't provide the logging configuration
......@@ -145,6 +145,10 @@ main(int argc, char* argv[]) {
// Remember verbose-mode
server.setVerbose(verbose_mode);
Daemon::setProcName(DHCP4_NAME);
Daemon::setConfigFile(config_file);
server.createPIDFile();
try {
// Initialize the server.
server.init(config_file);
......@@ -173,8 +177,18 @@ main(int argc, char* argv[]) {
LOG_INFO(dhcp4_logger, DHCP4_SHUTDOWN);
} catch (const std::exception& ex) {
} catch (const isc::dhcp::DaemonPIDExists& ex) {
// First, we print the error on stderr (that should always work)
cerr << DHCP4_NAME << " already running? " << ex.what()
<< endl;
// Let's also try to log it using logging system, but we're not
// sure if it's usable (the exception may have been thrown from
// the logger subsystem)
LOG_FATAL(dhcp4_logger, DHCP4_ALREADY_RUNNING)
.arg(DHCP4_NAME).arg(ex.what());
ret = EXIT_FAILURE;
} catch (const std::exception& ex) {
// First, we print the error on stderr (that should always work)
cerr << DHCP4_NAME << ": Fatal error during start up: " << ex.what()
<< endl;
......
......@@ -12,6 +12,7 @@ check-local:
for shtest in $(SHTESTS) ; do \
echo Running test: $$shtest ; \
export KEA_LOCKFILE_DIR=$(abs_top_builddir); \
export KEA_PIDFILE_DIR=$(abs_top_builddir); \
${SHELL} $(abs_builddir)/$$shtest || exit ; \
done
......
......@@ -272,6 +272,7 @@ shutdown_test() {
test_finish 0
}
server_pid_file_test "${CONFIG}" DHCP4_ALREADY_RUNNING
dynamic_reconfiguration_test
shutdown_test "dhcpv4.sigterm_test" 15
shutdown_test "dhcpv4.sigint_test" 2
......
......@@ -25,6 +25,7 @@ main(int argc, char* argv[]) {
// src/lib/log/README for info on how to tweak logging
isc::log::initLogger();
setenv("KEA_PIDFILE_DIR", TEST_DATA_BUILDDIR, 1);
int result = RUN_ALL_TESTS();
return (result);
......
......@@ -37,9 +37,11 @@ namespace dhcp {
// This is an initial config file location.
std::string Daemon::config_file_ = "";
std::string Daemon::proc_name_ = "";
Daemon::Daemon()
: signal_set_(), signal_handler_(), proc_name_(""),
pid_file_dir_(DHCP_DATA_DIR), pid_file_(), am_file_author_(false) {
: signal_set_(), signal_handler_(), pid_file_dir_(DHCP_DATA_DIR),
pid_file_(), am_file_author_(false) {
// The pid_file_dir can be overridden via environment variable
// This is primarily intended to simplify testing
......@@ -117,7 +119,7 @@ Daemon::setConfigFile(const std::string& config_file) {
}
std::string
Daemon::getProcName() const {
Daemon::getProcName() {
return (proc_name_);
};
......
......@@ -177,11 +177,11 @@ public:
/// @brief returns the process name
/// This value is used as when forming the default PID file name
/// @return text string
std::string getProcName() const;
static std::string getProcName();
/// @brief Sets the process name
/// @param proc_name name the process by which the process is recognized
void setProcName(const std::string& proc_name);
static void setProcName(const std::string& proc_name);
/// @brief Returns the directory used when forming default PID file name
/// @return text string
......@@ -255,7 +255,7 @@ private:
static std::string config_file_;
/// @brief Name of this process, used when creating its pid file
std::string proc_name_;
static std::string proc_name_;
/// @brief Pointer to the directory where PID file(s) are written
/// It defaults to --localstatedir
......
......@@ -65,8 +65,9 @@ public:
/// the default after each test completes.
~DaemonTest() {
isc::log::setDefaultLoggingOutput();
// Since it's static we need to clear it between tests
// Since they're static we need to clear them between tests
Daemon::setConfigFile("");
Daemon::setProcName("");
}
};
......
......@@ -590,3 +590,49 @@ logger_vars_test() {
test_finish 0
}
# This test verifies server PID file management
# 1. It verifies that upon startup, the server creates a PID file
# 2. It verifies the an attempt to start a second instance fails
# due to pre-existing PID File/PID detection
server_pid_file_test() {
local server_cfg="${1}"
local log_id="${2}"
# Log the start of the test and print test name.
test_start "${bin}.server_pid_file_test"
# Remove dangling DHCP4 instances and remove log files.
cleanup
# Create new configuration file.
create_config "${CONFIG}"
# Instruct server to log to the specific file.
set_logger
# Start server
start_kea ${bin_path}/${bin}
# Wait up to 20s for server to start.
wait_for_kea 20
if [ ${_WAIT_FOR_KEA} -eq 0 ]; then
printf "ERROR: timeout waiting for %s to start.\n" ${bin}
clean_exit 1
fi
# Verify server is still running
verify_server_pid ${bin} ${CFG_FILE}
printf "PID file is [%s], PID is [%d]" ${_SERVER_PID_FILE} ${_SERVER_PID}
# Now try to start a second one
start_kea ${bin_path}/${bin}
wait_for_message 10 "${log_id}" 1
if [ ${_WAIT_FOR_MESSAGE} -eq 0 ]; then
printf "ERROR: Second %s instance started? PID conflict not reported.\n" ${bin}
clean_exit 1
fi
# Verify server is still running
verify_server_pid ${bin} ${CFG_FILE}
# All ok. Shut down the server and exit.
test_finish 0
}
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