Browse Source

[3406] Handle reconfiguration errors gracefully.

Marcin Siodelski 11 years ago
parent
commit
fd4b2ac4ad

+ 8 - 0
src/bin/dhcp6/dhcp6_messages.mes

@@ -115,6 +115,14 @@ This message is printed when DHCPv6 server disables an interface from being
 used to receive DHCPv6 traffic. Sockets on this interface will not be opened
 by the Interface Manager until interface is enabled.
 
+% DHCP6_DYNAMIC_RECONFIGURATION initate server reconfiguration after receiving SIGHUP signal
+This is the info message logged when the DHCPv6 server starts reconfiguration
+as a result of receiving SIGHUP signal.
+
+% DHCP6_DYNAMIC_RECONFIGURATION_FAIL dynamic server reconfiguration failed
+This is an error message logged when the dynamic reconfiguration of the
+DHCP server failed.
+
 % DHCP6_EXTEND_LEASE_SUBNET_SELECTED the %1 subnet was selected for client extending its lease
 This is a debug message informing that a given subnet was selected. It will
 be used for extending lifetime of the lease. This is one of the early steps

+ 10 - 1
src/bin/dhcp6/kea_controller.cc

@@ -133,8 +133,17 @@ void configure(const std::string& file_name) {
 ///
 /// @param signo Signal number received.
 void signalHandler(int signo) {
+    // SIGHUP signals a request to reconfigure the server.
     if (signo == SIGHUP) {
-        configure(ControlledDhcpv6Srv::getInstance()->getConfigFile());
+        try {
+            LOG_INFO(dhcp6_logger, DHCP6_DYNAMIC_RECONFIGURATION);
+            configure(ControlledDhcpv6Srv::getInstance()->getConfigFile());
+        } catch (const std::exception& ex) {
+            // Log the unsuccessful reconfiguration. The reason for failure
+            // should be already logged. Don't rethrow an exception so as
+            // the server keeps working.
+            LOG_ERROR(dhcp6_logger, DHCP6_DYNAMIC_RECONFIGURATION_FAIL);
+        }
     }
 }
 

+ 65 - 3
src/bin/dhcp6/tests/dhcp6_reconfigure_test.sh

@@ -41,6 +41,28 @@ CONFIG="{
         } ]
     }
 }"
+# Invalid configuration (negative preferred-lifetime) to check that Kea
+# gracefully handles reconfiguration errors.
+CONFIG_INVALID="{
+    \"Dhcp6\":
+    {
+        \"interfaces\": [ ],
+        \"preferred-lifetime\": -3,
+        \"valid-lifetime\": 4000,
+        \"renew-timer\": 1000,
+        \"rebind-timer\": 2000,
+        \"lease-database\":
+        {
+            \"type\": \"memfile\",
+            \"persist\": false
+        },
+        \"subnet6\": [
+        {
+            \"subnet\": \"2001:db8:1::/64\",
+            \"pool\": [ \"2001:db8:1::10-2001:db8:1::100\" ]
+        } ]
+    }
+}"
 
 _GETPIDS1=
 _GETPIDS2=
@@ -57,6 +79,7 @@ cleanup() {
         kill -9 ${pid}
     done
     rm -rf ${LOG_FILE}
+    rm -rf ${CONFIG_FILE}
 }
 
 cleanexit() {
@@ -73,12 +96,17 @@ cleanexit() {
 }
 
 _GETRECONFIGS=
+_GETRECONFIGERRORS=
 getreconfigs() {
     # Grep log file for DHCP6_CONFIG_COMPLETE occurences. There should
     # be one occurence per (re)configuration.
     _GETRECONFIGS=`grep -o DHCP6_CONFIG_COMPLETE ${LOG_FILE} | wc -w`
-    # Remove whitespace
+    # Grep log file for DHCP6_CONFIG_LOAD_FAIL to check for configuration
+    # failures.
+    _GETRECONFIGERRORS=`grep -o DHCP6_CONFIG_LOAD_FAIL ${LOG_FILE} | wc -w`
+    # Remove whitespaces
     ${_GETRECONFIGS##*[! ]}
+    ${_GETRECONFIGERRORS##*[! ]}
 }
 
 printf "\nSTART TEST ${TEST_NAME}\n"
@@ -114,9 +142,12 @@ if [ ${_GETRECONFIGS} -ne 1 ]; then
     printf "ERROR: server hasn't been configured.\n"
     cleanexit 1
 else
-    printf "Server successfully configured\n"
+    printf "Server successfully configured.\n"
 fi
 
+printf "Creating configuration file with invalid configuration: %s.\n" ${CFG_FILE}
+printf "%b" ${CONFIG_INVALID} > ${CFG_FILE}
+
 # Reconfigure the server with SIGHUP.
 printf "Sending SIGHUP to Kea process (pid=%s) to reconfigure the server.\n" \
     ${_GETPIDS1}
@@ -126,6 +157,37 @@ kill -1 ${_GETPIDS1}
 # if reconfiguration didn't work.
 sleep 1
 
+# After receiving SIGHUP the server should try to reconfigure itself.
+# The configuration provided is invalid so it should result in
+# reconfiguration failure but the server should still be running.
+getreconfigs
+if [ ${_GETRECONFIGS} -ne 1 ]; then
+    printf "ERROR: server has been reconfigured despite bogus configuration.\n"
+    cleanexit 1
+elif [ ${_GETRECONFIGERRORS} -ne 1 ]; then
+    printf "ERROR: server did not report reconfiguration error despite attempt" \
+        " to configure it with invalid configuration.\n"
+    cleanexit 1
+fi
+
+# Be patient. Kea may terminate and we need to give it a time to do so.
+sleep 1
+
+# Make sure the server is still operational.
+getpids
+if [ ${_GETPIDS2} -ne 1 ]; then
+    printf "ERROR: Kea process was killed when attempting reconfiguration.\n"
+    cleanexit 1
+fi
+
+# Restore the good configuration.
+printf "%b" ${CONFIG} > ${CFG_FILE}
+
+# Reconfigure the server with SIGHUP.
+printf "Sending SIGHUP to Kea process (pid=%s) to reconfigure the server.\n" \
+    ${_GETPIDS1}
+kill -1 ${_GETPIDS1}
+
 # 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.
@@ -134,7 +196,7 @@ if [ ${_GETRECONFIGS} -ne 2 ]; then
     printf "ERROR: server hasn't been reconfigured.\n"
     cleanexit 1
 else
-    printf "Server successfully reconfigured\n"
+    printf "Server successfully reconfigured.\n"
 fi
 
 # Make sure the server is still operational.