Parcourir la source

[3422] Address review comments.

- Renamed kea4 and kea6 parameters to dhcp4 and dhcp6
- Location of the kea binaries is specified in the keactrl.conf
- Swap pools and subnets in kea.conf.
- Renamed keactrl commit command to reload
- Added -s and -c command line options.
Marcin Siodelski il y a 11 ans
Parent
commit
cb0e4c426a

+ 14 - 14
src/bin/keactrl/kea.conf.in

@@ -7,7 +7,7 @@
 
 # DHCPv4 configuration starts here.
 "Dhcp4":
-{ 
+{
 # Add names of interfaces to listen on.
   "interfaces": [ ],
 
@@ -21,15 +21,15 @@
 
 # Below an example of the simple subnet declaration. Uncomment to
 # enable it.
-  "subnet4": [ 
-#  {    "pool": [ "192.0.2.1 - 192.0.2.200" ],
-#       "subnet": "192.0.2.0/24"  }
+  "subnet4": [
+#  {    "subnet": "192.0.2.0/24",
+#       "pool": [ "192.0.2.1 - 192.0.2.200" ] }
   ]
 },
 
 # DHCPv6 configuration starts here.
 "Dhcp6":
-{ 
+{
 # Add names of interfaces to listen on.
   "interfaces": [ ],
 
@@ -45,15 +45,15 @@
   "rebind-timer": 2000,
 
 # The following list defines subnets. Uncomment to enable them.
-  "subnet6": [ 
-#  {    "pool": [ "2001:db8:1::/80" ],
-#       "subnet": "2001:db8:1::/64"  },
-#  {    "pool": [ "2001:db8:2::/80" ],
-#       "subnet": "2001:db8:2::/64"  }, 
-#  {    "pool": [ "2001:db8:3::/80" ],
-#       "subnet": "2001:db8:3::/64"  },
-#  {    "pool": [ "2001:db8:4::/80" ],
-#       "subnet": "2001:db8:4::/64"  }
+  "subnet6": [
+#  {    "subnet": "2001:db8:1::/64",
+#       "pool": [ "2001:db8:1::/80" ] },
+#  {    "subnet": "2001:db8:2::/64",
+#       "pool": [ "2001:db8:2::/80" ] },
+#  {    "subnet": "2001:db8:3::/64",
+#       "pool": [ "2001:db8:3::/80" ] },
+#  {    "subnet": "2001:db8:4::/64",
+#       "pool": [ "2001:db8:4::/80" ] }
    ]
 }
 

+ 8 - 2
src/bin/keactrl/keactrl.conf.in

@@ -8,11 +8,17 @@ prefix=@prefix@
 # Location of Kea configuration file.
 kea_config_file=@sysconfdir@/@PACKAGE@/kea.conf
 
+# Location of Kea binaries.
+exec_prefix=@exec_prefix@
+dhcp4_srv=@libexecdir@/@PACKAGE@/b10-dhcp4
+dhcp6_srv=@libexecdir@/@PACKAGE@/b10-dhcp6
+dhcp_ddns=@libexecdir@/@PACKAGE@/b10-dhcp-ddns
+
 # Start DHCPv4 server?
-kea4=yes
+dhcp4=yes
 
 # Start DHCPv6 server?
-kea6=yes
+dhcp6=yes
 
 # Be verbose?
 kea_verbose=no

+ 132 - 58
src/bin/keactrl/keactrl.in

@@ -35,6 +35,29 @@ log_info() {
     printf "INFO/keactrl: ${1}\n"
 }
 
+### Convenience functions ###
+
+# Checks if the value is in the list. An example usage of this function
+# is to determine whether the keactrl command belongs to the list of
+# supported commands.
+is_in_list() {
+    local member=${1}  # Value to be checked
+    local list=${2}    # Comma separated list of items
+    _inlist=0          # Return value: 0 if not in list, 1 otherwise.
+    if [ -z ${member} ]; then
+        log_error "missing ${class}"
+    fi
+    # Iterate over all items on the list and compare with the member.
+    # If they match, return, otherwise log error and exit.
+    for item in ${list}
+    do
+        if [ ${item} = ${member} ]; then
+            _inlist=1
+            return
+        fi
+    done
+}
+
 ### Functions managing Kea processes ###
 
 # Returns a list of existing PIDs and a number of PIDs for the process
@@ -101,6 +124,40 @@ as another instance is already running."
     fi
 }
 
+# Run the specified command if the server has been enabled.
+# In order for the command to run, the following conditions have to be met:
+# - server must be on the list of servers (e.g. specified from command line)
+#   or servers must contain all
+# - if check_file_cfg is non zero, the server must be enabled in the
+#   configuration file, so the variable named after server name should exist
+#   and be set to yes, e.g. ${dhcp4} should be equal to yes if server name
+#   is dhcp4
+run_conditional() {
+    local server=${1}         # Server name: dhcp4, dhcp6, dhcp_ddns
+    local command=${2}        # Command to execute
+    local check_file_cfg=${3} # Check if server enabled in the configuration file
+
+    # If keyword "all" is not on the list of servers we will have to check
+    # if our specific server is on the list. If, not return.
+    is_in_list "all" ${servers}
+    if [ ${_inlist} -eq 0 ]; then
+        is_in_list ${server} ${servers}
+        if [ ${_inlist} -eq 0 ]; then
+            return
+        fi
+    fi
+
+    # Get the configuration value of the keactrl which indicates whether
+    # the server should be enabled or not. Variables that hold these values
+    # are: ${dhcp4}, ${dhcp6}, ${dhcp_ddns}.
+    local file_config=$( eval printf "%s" \${$server} )
+    # Run the command if we ignore the configuration setting or if the
+    # setting is "yes".
+    if [ ${check_file_cfg} -eq 0 ] || [ "${file_config}" = "yes" ]; then
+        ${command}
+    fi
+}
+
 ### Script starts here ###
 
 # Configure logger to log messages into the file.
@@ -112,48 +169,50 @@ if [ -z ${B10_LOGGER_DESTINATION} ]; then
     export B10_LOGGER_DESTINATION=@localstatedir@/@PACKAGE@/kea.log
 fi
 
-command=
-if [ $# -ne 1 ]; then
-    log_error "No command specified. Use: start, stop, commit or status."
-    exit 1
-
-elif [ "${1}" != "start" -a "${1}" != "stop" -a\
- "${1}" != "commit" -a "${1}" != "status" ]; then
-    log_error "Illegal command: ${1}"
+command=${1}
+is_in_list "${command}" "start stop reload status"
+if [ ${_inlist} -eq 0 ]; then
+    log_error "invalid command: ${command}"
     exit 1
-
-else
-    command=${1}
 fi
 
-# Set locations of the Kea binaries. The location depends on whether we
-# are running unit tests or we're running the installed binaries.
-dhcpv4_srv=
-dhcpv6_srv=
-dhcp_ddns=
-keactrl_conf=
-
-# The environment variable is set when the script is ran from the
-# tests. If not set, the Kea installation directory is used.
-if test -n "${KEACTRL_BUILD_DIR}"; then
-    dhcpv4_srv=${KEACTRL_BUILD_DIR}/src/bin/dhcp4/b10-dhcp4
-    dhcpv6_srv=${KEACTRL_BUILD_DIR}/src/bin/dhcp6/b10-dhcp6
-    dhcp_ddns=${KEACTRL_BUILD_DIR}/src/bin/d2/b10-dhcp-ddns
-else
-    prefix=@prefix@
-    exec_prefix=@exec_prefix@
-    dhcpv4_srv=@libexecdir@/@PACKAGE@/b10-dhcp4
-    dhcpv6_srv=@libexecdir@/@PACKAGE@/b10-dhcp6
-    dhcp_ddns=@libexecdir@/@PACKAGE@/b10-dhcp-ddns
-    keactrl_conf=@sysconfdir@/@PACKAGE@/keactrl.conf
-fi
-
-# KEACTRL_CONF environment variable may hold a location of the keactrl
-# configuration file. If this is the case, it overrides the default
-# location.
-if test -n "${KEACTRL_CONF}"; then
-    keactrl_conf=${KEACTRL_CONF}
-fi
+# Get the location of the keactrl configuration file.
+prefix=@prefix@
+keactrl_conf=@sysconfdir@/@PACKAGE@/keactrl.conf
+
+servers="all"
+
+shift
+while [ ! -z "${1}" ]
+do
+    option=${1}
+    case ${option} in
+        # Override keactrl configuration file.
+        -c|--ctrl-config)
+            shift
+            keactrl_conf=${1}
+            ;;
+        # Get the specific servers for which the command will be
+        # executed.
+        -s|--server)
+            shift
+            servers=$( printf "%s" ${1} | tr "," "\n" )
+            # Validate that the specifief server names are correct.
+            for s in ${servers}
+            do
+                is_in_list "${s}" "all dhcp4 dhcp6 dhcp_ddns"
+                if [ ${_inlist} -eq 0 ]; then
+                    log_error "invalid server name: ${s}"
+                    exit 1
+                fi
+            done
+            ;;
+        *)
+            log_error "invalid option: ${option}"
+            exit 1
+    esac
+    shift
+done
 
 # Check if the file exists. If it doesn't, it is a fatal error.
 if [ ! -f ${keactrl_conf} ]; then
@@ -164,6 +223,24 @@ fi
 # Include the configuration file.
 . ${keactrl_conf}
 
+# Get location of the DHCPv4 server binary.
+if [ -z ${dhcp4_srv} ]; then
+    log_error "dhcp4_srv parameter not specified"
+    exit 1
+fi
+
+# Get location of the DHCPv6 server binary.
+if [ -z ${dhcp6_srv} ]; then
+    log_error "dhcp6_srv parameter not specified"
+    exit 1
+fi
+
+# Get location of the DHCP DDNS server binary.
+if [ -z ${dhcp_ddns} ]; then
+    log_error "dhcp_ddns parameter not specified"
+    exit 1
+fi
+
 # Check if the Kea configuration file location has been specified in the
 # keactrl configuration file. If not, it is a fatal error.
 if [ -z ${kea_config_file} ]; then
@@ -174,10 +251,10 @@ elif [ ! -f ${kea_config_file} ]; then
     exit 1
 fi
 
-# kea4 and kea6 (=yes) indicate if we should start DHCPv4 and DHCPv6 server
+# dhcp4 and dhcp6 (=yes) indicate if we should start DHCPv4 and DHCPv6 server
 # respectively.
-kea4=$( printf "%s" ${kea4} | tr [:upper:] [:lower:] )
-kea6=$( printf "%s" ${kea6} | tr [:upper:] [:lower:] )
+dhcp4=$( printf "%s" ${dhcp4} | tr [:upper:] [:lower:] )
+dhcp6=$( printf "%s" ${dhcp6} | tr [:upper:] [:lower:] )
 
 case ${command} in
     # Start the servers.
@@ -188,47 +265,44 @@ case ${command} in
             args="${args} -v"
         fi
 
-        if [ "${kea4}" = "yes" ]; then
-            start_server ${dhcpv4_srv} "${args}"
-        fi
-
-        if [ "${kea6}" = "yes" ]; then
-            start_server ${dhcpv6_srv} "${args}"
-        fi
+        # Run servers if they are on the list of servers from the command line
+        # and if they are enabled in the keactrl configuration file.
+        run_conditional "dhcp4" "start_server ${dhcp4_srv} \"${args}\"" 1
+        run_conditional "dhcp6" "start_server ${dhcp6_srv} \"${args}\"" 1
 
         exit 0 ;;
 
     # Stop running servers.
     stop)
-        send_signal 15 $(basename ${dhcpv4_srv})
-        send_signal 15 $(basename ${dhcpv6_srv})
+        # Stop all servers or servers specified from the command line.
+        run_conditional "dhcp4" "send_signal 15 $(basename ${dhcp4_srv})" 0
+        run_conditional "dhcp6" "send_signal 15 $(basename ${dhcp6_srv})" 0
 
         exit 0 ;;
 
     # Reconfigure the servers.
-    commit)
-        send_signal 1 $(basename ${dhcpv4_srv})
-        send_signal 1 $(basename ${dhcpv6_srv})
+    reload)
+        # Reconfigure all servers or servers specified from the command line.
+        run_conditional "dhcp4" "send_signal 1 $(basename ${dhcp4_srv})" 0
+        run_conditional "dhcp6" "send_signal 1 $(basename ${dhcp6_srv})" 0
 
         exit 0 ;;
 
     status)
         kea4_status="inactive"
-        check_running $(basename ${dhcpv4_srv})
+        check_running $(basename ${dhcp4_srv})
         if [ ${_running} -eq 1 ]; then
             kea4_status="active"
         fi
         printf "DHCPv4 server: %s\n" ${kea4_status}
 
         kea6_status="inactive"
-        check_running $(basename ${dhcpv6_srv})
+        check_running $(basename ${dhcp6_srv})
         if [ ${_running} -eq 1 ]; then
             kea6_status="active"
         fi
         printf "DHCPv6 server: %s\n" ${kea6_status}
-
         printf "Kea configuration file: %s\n" ${kea_config_file}
-
         printf "keactrl configuration file: %s\n" ${keactrl_conf}
 
         exit 0 ;;

+ 163 - 48
src/bin/keactrl/tests/keactrl_tests.sh.in

@@ -68,12 +68,18 @@ config="{
     }
 }"
 
+# Fixed part of the keactrl configuration file.
+keactrl_fixed_config="dhcp4_srv=${KEACTRL_BUILD_DIR}/src/bin/dhcp4/b10-dhcp4\n\
+dhcp6_srv=${KEACTRL_BUILD_DIR}/src/bin/dhcp6/b10-dhcp6\n\
+dhcp_ddns=${KEACTRL_BUILD_DIR}/src/bin/d2/b10-dhcp-ddns\n"
+
 # This test checks that both DHCPv4 and DHCPv6 server can be started and
 # shut down.
 start_both_servers_no_verbose_test() {
     # Create configuration file for keactrl. This configuration enables
     # both DHCPv4 and DHCPv6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\nkea4=yes\nkea6=yes\nkea_verbose=no\n"
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\nkea_verbose=no\n\
+${keactrl_fixed_config}"
 
     test_start "keactrl.start_both_servers_no_verbose_test"
 
@@ -85,8 +91,11 @@ start_both_servers_no_verbose_test() {
     set_logger
 
     # Start servers using keactrl script.
-    printf "Starting Kea: ${keactrl} start\n"
-    ${keactrl} start
+    printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE} -s all\n"
+    # Append the -s option to specify all servers. This is not necessary
+    # because all should be a default but let's see if it is accepted
+    # by the command line parser.
+    ${keactrl} start -c ${KEACTRL_CFG_FILE} -s all
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d"
 
@@ -126,8 +135,8 @@ Expected wait_for_message return %d, returned %d."
         "Expected %d ${kea6_name} process running, found %d processes running"
 
     # Use keactrl stop to shutdown the servers.
-    printf "Stopping Kea: ${keactrl} stop\n"
-    ${keactrl} stop
+    printf "Stopping Kea: ${keactrl} stop  -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} stop -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d."
 
@@ -160,7 +169,8 @@ Expected wait_for_message return %d, returned %d."
 start_both_servers_verbose_test() {
     # Create configuration file for keactrl. This configuration enables
     # both DHCPv4 and DHCPv6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\nkea4=yes\nkea6=yes\nkea_verbose=yes\n"
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\nkea_verbose=yes\n\
+${keactrl_fixed_config}"
 
     test_start "keactrl.start_both_servers_verbose_test"
 
@@ -172,8 +182,8 @@ start_both_servers_verbose_test() {
     set_logger
 
     # Start servers using keactrl script.
-    printf "Starting Kea: ${keactrl} start\n"
-    ${keactrl} start
+    printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} start -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d"
 
@@ -215,8 +225,8 @@ Expected wait_for_message return %d, returned %d."
         "Expected %d ${kea6_name} process running, found %d processes running"
 
     # Use keactrl stop to shutdown the servers.
-    printf "Stopping Kea: ${keactrl} stop\n"
-    ${keactrl} stop
+    printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} stop -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d."
 
@@ -251,7 +261,8 @@ Expected wait_for_message return %d, returned %d."
 start_v4_server_test() {
     # Create configuration file for keactrl. This configuration enables
     # DHCPv4 server but disables DHCPv6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\nkea4=yes\nkea6=no\nkea_verbose=no\n"
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=no\nkea_verbose=no\n\
+${keactrl_fixed_config}"
 
     test_start "keactrl.start_v4_server_test"
 
@@ -263,8 +274,8 @@ start_v4_server_test() {
     set_logger
 
     # Start DHCPv4 server using keactrl script.
-    printf "Starting Kea: ${keactrl} start\n"
-    ${keactrl} start
+    printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} start -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to retrun 0, returned value was ${ret}"
 
@@ -289,8 +300,9 @@ Expected wait_for_message return %d, returned %d."
         "Expected %d ${kea6_name} process running, found %d processes running"
 
     # Make sure that the status command returns appropriate status.
-    printf "Getting status of Kea modules: %s\n" "${keactrl} status"
-    output=$( ${keactrl} status )
+    printf "Getting status of Kea modules: %s\n" "${keactrl} status \
+-c ${KEACTRL_CFG_FILE}"
+    output=$( ${keactrl} status -c ${KEACTRL_CFG_FILE} )
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned %d"
     assert_string_contains "DHCPv4 server: active" "${output}" \
@@ -299,8 +311,8 @@ Expected wait_for_message return %d, returned %d."
         "Expected keactrl status command return %s"
 
     # Use keactrl stop to shutdown the servers.
-    printf "Stopping Kea: ${keactrl} stop\n"
-    ${keactrl} stop
+    printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} stop -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d."
 
@@ -327,7 +339,8 @@ Expected wait_for_message return %d, returned %d."
 start_v6_server_test() {
     # Create configuration file for keactrl. This configuration enables
     # DHCPv6 server but disables DHCPv4 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\nkea4=no\nkea6=yes\nkea_verbose=no\n"
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=no\ndhcp6=yes\nkea_verbose=no\n\
+${keactrl_fixed_config}"
 
     test_start "keactrl.start_v6_server_test"
 
@@ -339,8 +352,8 @@ start_v6_server_test() {
     set_logger
 
     # Start DHCPv6 server using keactrl script.
-    printf "Starting Kea: ${keactrl} start\n"
-    ${keactrl} start
+    printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} start -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d"
 
@@ -365,8 +378,8 @@ Expected wait_for_message return %d, returned %d."
         "Expected %d ${kea4_name} process running, found %d processes running"
 
     # Make sure that the status command returns appropriate status.
-    printf "Getting status of Kea modules: %s\n" "${keactrl} status"
-    output=$( ${keactrl} status )
+    printf "Getting status of Kea modules: %s\n" "${keactrl} status -c ${KEACTRL_CFG_FILE}"
+    output=$( ${keactrl} status -c ${KEACTRL_CFG_FILE} )
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned %d"
     assert_string_contains "DHCPv4 server: inactive" "${output}" \
@@ -375,8 +388,8 @@ Expected wait_for_message return %d, returned %d."
         "Expected keactrl status command return %s"
 
     # Use keactrl stop to shutdown the servers.
-    printf "Stopping Kea: ${keactrl} stop\n"
-    ${keactrl} stop
+    printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} stop -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d."
 
@@ -404,7 +417,8 @@ Expected wait_for_message return %d, returned %d."
 late_start_v4_server_test() {
     # Create configuration file for keactrl. This configuration enables
     # DHCPv6 server but disables DHCPv4 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\nkea4=no\nkea6=yes\nkea_verbose=no\n"
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=no\ndhcp6=yes\nkea_verbose=no\n\
+${keactrl_fixed_config}"
 
     test_start "keactrl.late_start_v4_server_test"
 
@@ -416,8 +430,8 @@ late_start_v4_server_test() {
     set_logger
 
     # Start DHCPv6 server using keactrl script.
-    printf "Starting Kea: ${keactrl} start\n"
-    ${keactrl} start
+    printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} start -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to retrun 0, returned value was ${ret}"
 
@@ -442,8 +456,8 @@ Expected wait_for_message return %d, returned %d."
         "Expected %d ${kea4_name} process running, found %d processes running"
 
     # Trigger reconfiguration, make sure that the DHCPv6 server reconfigured.
-    printf "Reconfiguring the DHCPv6 server\n"
-    ${keactrl} commit
+    printf "Reconfiguring the DHCPv6 server: ${keactrl} reload -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} reload -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d"
 
@@ -453,12 +467,13 @@ Expected wait_for_message return %d, returned %d."
 Expected wait_for_message to return %d, returned %d."
 
     # Update keactrl config to enable v4 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\nkea4=yes\nkea6=yes\nkea_verbose=yes\n"
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\nkea_verbose=yes\n\
+${keactrl_fixed_config}"
     create_keactrl_config "${keactrl_config}"
 
     # Start DHCPv4 server using keactrl script.
-    printf "Starting Kea: ${keactrl} start\n"
-    ${keactrl} start
+    printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} start -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d"
 
@@ -479,8 +494,9 @@ Expected wait_for_message return %d, returned %d."
         "Expected %d ${kea4_name} process running, found %d processes running"
 
     # Trigger reconfiguration, make sure that servers are reconfigured.
-    printf "Reconfiguring DHCPv6 and DHCPv4 servers\n"
-    ${keactrl} commit
+    printf "Reconfiguring DHCPv6 and DHCPv4 servers: ${keactrl} reload \
+-c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} reload -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d"
 
@@ -495,8 +511,8 @@ Expected wait_for_message to return %d, returned %d."
 Expected wait_for_message to return %d, returned %d."
 
     # Use keactrl stop to shutdown the servers.
-    printf "Stopping Kea: ${keactrl} stop\n"
-    ${keactrl} stop
+    printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} stop -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d."
 
@@ -530,7 +546,8 @@ Expected wait_for_message return %d, returned %d."
 late_start_v6_server_test() {
     # Create configuration file for keactrl. This configuration enables
     # DHCPv4 server but disables DHCPv6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\nkea4=yes\nkea6=no\nkea_verbose=yes\n"
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=no\nkea_verbose=yes\n\
+${keactrl_fixed_config}"
 
     test_start "keactrl.late_start_v6_server_test"
 
@@ -542,8 +559,8 @@ late_start_v6_server_test() {
     set_logger
 
     # Start DHCPv4 server using keactrl script.
-    printf "Starting Kea: ${keactrl} start\n"
-    ${keactrl} start
+    printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} start -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to retrun 0, returned value was ${ret}"
 
@@ -568,8 +585,8 @@ Expected wait_for_message return %d, returned %d."
         "Expected %d ${kea6_name} process running, found %d processes running"
 
     # Trigger reconfiguration, make sure that the DHCPv4 server is reconfigured.
-    printf "Reconfiguring the DHCPv4 server\n"
-    ${keactrl} commit
+    printf "Reconfiguring the DHCPv4 server: ${keactrl} reload -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} reload -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d"
 
@@ -579,12 +596,13 @@ Expected wait_for_message return %d, returned %d."
 Expected wait_for_message to return %d, returned %d."
 
     # Update keactrl config to enable v6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\nkea4=yes\nkea6=yes\nkea_verbose=no\n"
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\nkea_verbose=no\n\
+${keactrl_fixed_config}"
     create_keactrl_config "${keactrl_config}"
 
     # Start DHCPv6 server using keactrl script.
-    printf "Starting Kea: ${keactrl} start\n"
-    ${keactrl} start
+    printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} start -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to retrun 0, returned value was ${ret}"
 
@@ -605,8 +623,9 @@ Expected wait_for_message return %d, returned %d."
         "Expected %d ${kea4_name} process running, found %d processes running"
 
     # Trigger reconfiguration, make sure that servers are reconfigured.
-    printf "Reconfiguring DHCPv6 and DHCPv4 servers\n"
-    ${keactrl} commit
+    printf "Reconfiguring DHCPv6 and DHCPv4 servers: ${keactrl} reload \
+-c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} reload -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d"
 
@@ -621,8 +640,8 @@ Expected wait_for_message to return %d, returned %d."
 Expected wait_for_message to return %d, returned %d."
 
     # Use keactrl stop to shutdown the servers.
-    printf "Stopping Kea: ${keactrl} stop\n"
-    ${keactrl} stop
+    printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} stop -c ${KEACTRL_CFG_FILE}
     ret=${?}
     assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d."
 
@@ -650,10 +669,106 @@ Expected wait_for_message return %d, returned %d."
     test_finish 0
 }
 
+# This test checks that the servers can be shutdown selectively.
+stop_selected_server_test() {
+    # Create configuration file for keactrl. This configuration enables
+    # both DHCPv4 and DHCPv6 server.
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\nkea_verbose=no\n\
+${keactrl_fixed_config}"
+
+    test_start "keactrl.stop_selected_server_test"
+
+    # Create configuration file for Kea and for keactrl.
+    create_config "${config}"
+    create_keactrl_config "${keactrl_config}"
+
+    # Set logging to a file.
+    set_logger
+
+    # Start servers using keactrl script.
+    printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} start -c ${KEACTRL_CFG_FILE}
+    ret=${?}
+    assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d"
+
+    # Wait up to 20s for the DHCPv6 server to configure.
+    wait_for_message 20 "DHCP6_CONFIG_COMPLETE" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${kea6_name} to start. \
+Expected wait_for_message return %d, returned %d."
+
+    # Wait up to 20s for the DHCPv4 server to configure.
+    wait_for_message 20 "DHCP4_CONFIG_COMPLETE" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${kea4_name} to start. \
+Expected wait_for_message return %d, returned %d."
+
+    # Make sure that debug messages are not logged (non-verbose mode).
+    get_log_messages "DHCP6_START_INFO"
+    assert_eq 0 ${_GET_LOG_MESSAGES} \
+        "Expected get_log_messages return %d, returned %d."
+
+    # Make sure that debug messages are not logged (non-verbose mode).
+    get_log_messages "DHCP4_START_INFO"
+    assert_eq 0 ${_GET_LOG_MESSAGES} \
+        "Expected get_log_messages return %d, returned %d."
+
+    # Server may shut down imediatelly after configuration has competed.
+    # Give it some time to shutdown.
+    sleep 3
+
+    # Make sure that both servers are running.
+    get_pids ${kea4_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${kea4_name} process running, found %d processes running"
+
+    get_pids ${kea6_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${kea6_name} process running, found %d processes running"
+
+    # Use keactrl stop to shutdown DHCPv4 server.
+    printf "Stopping DHCPv4 server: ${keactrl} stop -s dhcp4 -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} stop -s dhcp4 -c ${KEACTRL_CFG_FILE}
+    ret=${?}
+    assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d."
+
+    # Wait up to 10s for the DHCPv4 server to stop.
+    wait_for_message 10 "DHCP4_SHUTDOWN" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${kea4_name} to shutdown. \
+Expected wait_for_message return %d, returned %d."
+
+    # Make sure DHCPv6 server is still running
+    get_pids ${kea6_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${kea6_name} process running, found %d processes running"
+
+    # Use keactrl stop to shutdown DHCPv6 server.
+    printf "Stopping DHCPv6 server: ${keactrl} stop -s dhcp6 -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} stop -s dhcp6 -c ${KEACTRL_CFG_FILE}
+    ret=${?}
+    assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d."
+
+    # Wait up to 10s for the DHCPv6 server to stop.
+    wait_for_message 10 "DHCP6_SHUTDOWN" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${kea6_name} to shutdown. \
+Expected wait_for_message return %d, returned %d."
+
+    # Make sure that the DHCPv6 server is down.
+    get_pids ${kea6_name}
+    assert_eq 0 ${_GET_PIDS_NUM} \
+        "Expected %d ${kea6_name} processes running, found %d processes running"
+
+    test_finish 0
+}
+
+
 start_both_servers_no_verbose_test
 start_both_servers_verbose_test
 start_v4_server_test
 start_v6_server_test
 late_start_v4_server_test
 late_start_v6_server_test
+stop_selected_server_test