]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[3769] DHPCv4 now uses PID file, made pid test common
authorThomas Markwalder <tmark@isc.org>
Thu, 2 Jul 2015 20:49:53 +0000 (16:49 -0400)
committerThomas Markwalder <tmark@isc.org>
Thu, 2 Jul 2015 20:49:53 +0000 (16:49 -0400)
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

12 files changed:
src/bin/d2/d2_messages.mes
src/bin/d2/tests/d2_process_tests.sh.in
src/bin/dhcp4/dhcp4_messages.mes
src/bin/dhcp4/kea_controller.cc
src/bin/dhcp4/main.cc
src/bin/dhcp4/tests/Makefile.am
src/bin/dhcp4/tests/dhcp4_process_tests.sh.in
src/bin/dhcp4/tests/dhcp4_unittests.cc
src/lib/dhcpsrv/daemon.cc
src/lib/dhcpsrv/daemon.h
src/lib/dhcpsrv/tests/daemon_unittest.cc
src/lib/testutils/dhcp_test_lib.sh.in

index a0193a768314c4bd114790b79b9944ccbce669e5..383c64f13c76842d8ea5c7854ba4c495897509cd 100644 (file)
@@ -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.
index 1233b307017d1a3065d8b946d08af18009ba2b71..3a6aa83d3b0805c2136fa02c556c186c4abfd34d 100755 (executable)
@@ -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
index d820896b6d48f107de03a662ade7f84782e6c47a..9c358abbf495f6a1708f574ca2af58e83c5ab3a1 100644 (file)
@@ -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
index ea43d88935f70e0e9c5ad883d5355dc4e55b5f0b..92503d5cf0b09ec71773c698fd26e84e93d55bd4 100644 (file)
@@ -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);
 
index 0635086950f4017610d417c09dc084368e80e92c..ca49d30eee1aa3af3253dfd9cb6161d7035e8351 100644 (file)
@@ -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;
index 2752ecdef9fe43d1ef5611e4bcce0545cfff8451..65098c98f5a9cedfa97c32797d79a3bee109738f 100644 (file)
@@ -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
 
index 4bf8fb67b1abe69f0b34ee230e11d731f199324c..91bca885389b73541a2728b0e24c852b7b77d036 100755 (executable)
@@ -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
index f57cfa429f72478fd5b5b9abd872520a43f9eaf7..2beea84252659b536d5060e065ceaa89b4b534ad 100644 (file)
@@ -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);
index 6fe017205728675fb388fc41fa8c962da2067e43..49868c3ee1c4e635eb997ba8144ffb4aad3fba21 100644 (file)
@@ -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_);
 };
 
index 7d8ffe76731fe6367d296a253bbff30407d17407..77035dbb69a4811ed88d931d22c45ea564fac959 100644 (file)
@@ -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
index f28819a371fd26f1c304379da6b9a68f869ebf36..b6618e539b2bc1fb7e4a6bfa7d197139fb0ad286 100644 (file)
@@ -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("");
     }
 };
 
index f81a3a63edeaaf929c69fb57ccd597f4b03e8194..a07cc473398c375d774d423a550cae1efc56505b 100644 (file)
@@ -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
+}