Commit 93a720ed authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[master] keactrl now uses server PID files

Merge branch 'trac3939'
parents caed0f6d 3d701e67
......@@ -48,14 +48,6 @@ make check
The following environment variable can affect unit-tests:
- KEA_SOCKET_TEST_DIR - if set, it specifies the directory where Unix
sockets are created. There's OS limitation on how long a Unix socket
path can be. It is typcially slightly over 100 characters. If you
happen to build and run unit-tests in deeply nested directories, this
may become a problem. KEA_SOCKET_TEST_DIR can be specified to instruct
unit-test to use a different directory. Must not end with slash (e.g.
/tmp).
- KEA_LOCKFILE_DIR - Specifies a directory where the logging system should
create its lock file. If not specified, it is prefix/var/run/kea, where prefix
defaults to /usr/local. This variable must not end with a slash. There is one
......@@ -68,4 +60,17 @@ The following environment variable can affect unit-tests:
stdout, stderr and syslog. Any other value is interpreted as a filename.
Also see Kea User's Guide, section 15.3.
- KEA_PIDFILE_DIR - Specifies the directory which should be used for PID files
as used by dhcp::Daemon or its derivatives. If not specified, the default is
prefix/var/run/kea, where prefix defaults to /usr/local. This variable must
not end with a slash.
- KEA_SOCKET_TEST_DIR - if set, it specifies the directory where Unix
sockets are created. There's OS limitation on how long a Unix socket
path can be. It is typcially slightly over 100 characters. If you
happen to build and run unit-tests in deeply nested directories, this
may become a problem. KEA_SOCKET_TEST_DIR can be specified to instruct
unit-test to use a different directory. Must not end with slash (e.g.
/tmp).
*/
......@@ -157,21 +157,48 @@ kea_verbose=no
the servers looks similar to the following:
<screen>
<userinput>$ keactrl start</userinput>
INFO/keactrl: Starting kea-dhcp4 -c /usr/local/etc/kea/kea.conf
INFO/keactrl: Starting kea-dhcp6 -c /usr/local/etc/kea/kea.conf
INFO/keactrl: Starting kea-dhcp-ddns -c /usr/local/etc/kea/kea.conf
INFO/keactrl: Starting kea-dhcp4 -c /usr/local/etc/kea/kea.conf -d
INFO/keactrl: Starting kea-dhcp6 -c /usr/local/etc/kea/kea.conf -d
INFO/keactrl: Starting kea-dhcp-ddns -c /usr/local/etc/kea/kea.conf -d
</screen>
</para>
<para>Kea's servers create PID files upon startup. These files are used
by keactrl to deteremine whether or not a given server is running. If
one or more servers are running when the start command is issued, the
output will look similiar to the following:
<screen>
<userinput>$ keactrl start</userinput>
INFO/keactrl: kea-dhcp4 appears to be running, see: PID 10918, PID file: /usr/local/var/kea/kea.kea-dhcp4.pid.
INFO/keactrl: kea-dhcp6 appears to be running, see: PID 10924, PID file: /usr/local/var/kea/kea.kea-dhcp6.pid.
INFO/keactrl: kea-dhcp-ddns appears to be running, see: PID 10930, PID file: /usr/local/var/kea/kea.kea-dhcp-ddns.pid.
</screen>
During normal shutdowns these PID files are deleted. They may, however,
be left over as remnants following a system crash. It is possible,
though highly unlikely, that upon system restart the PIDs they contain
actually refer to processes unrelated to Kea. This condition will cause
keactrl to decide that the servers are running, when in fact they are
not. In such a case the PID files as listed in the keactrl output
must be manually deleted.
</para>
<para>The following command stops all servers:
<screen>
<userinput>$ keactrl stop</userinput>
INFO/keactrl: Skip sending signal 15 to process kea-dhcp6: process is not running
INFO/keactrl: Stopping kea-dhcp4...
INFO/keactrl: Stopping kea-dhcp6...
INFO/keactrl: Stopping kea-dhcp-ddns...
</screen>
Note that the <command>stop</command> will attempt to stop all servers
regardless of whether they are "enabled" in the <filename>keactrl.conf</filename>.
If any of the servers is not running, an informational message
is displayed as in the <command>stop</command> command output above.
If any of the servers are not running, an informational message
is displayed as in the <command>stop</command> command output below.
<screen>
<userinput>$ keactrl stop</userinput>
INFO/keactrl: kea-dhcp4 isn't running.
INFO/keactrl: kea-dhcp6 isn't running.
INFO/keactrl: kea-dhcp-ddns isn't running.
</screen>
</para>
<para>
......@@ -184,6 +211,17 @@ INFO/keactrl: Skip sending signal 15 to process kea-dhcp6: process is not runnin
valid, uses the new configuration. A reload is executed as follows:
<screen>
<userinput>$ keactrl reload</userinput>
INFO/keactrl: Reloading kea-dhcp4...
INFO/keactrl: Reloading kea-dhcp6...
INFO/keactrl: Reloading kea-dhcp-ddns...
</screen>
If any of the servers are not running, an informational message
is displayed as in the <command>reload</command> command output below.
<screen>
<userinput>$ keactrl stop</userinput>
INFO/keactrl: kea-dhcp4 isn't running.
INFO/keactrl: kea-dhcp6 isn't running.
INFO/keactrl: kea-dhcp-ddns isn't running.
</screen>
</para>
......
#!/bin/sh
# 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
......@@ -65,48 +65,75 @@ usage() {
}
### Functions managing Kea processes ###
# Contructs a server's PID file based on its binary name, the config file,
# and the --localstatedir and returns the contents as $_pid. If the file
# does not exist, the value of $_pid is 0. If the file exists but cannot
# be read the function exists with a error message. Note the PID file name
# is always returned in $_pid_file.
get_pid_from_file() {
local proc_name=${1} # Process name.
# Extract the name portion of the config file
local conf_name=$(basename ${kea_config_file} | cut -f1 -d'.')
# Default the directory to --localstatedir
local pid_file_dir=@localstatedir@/@PACKAGE@
# Use directory override if set (primarily for testing only)
if [ ! -z $KEA_PIDFILE_DIR ]; then
pid_file_dir=${KEA_PIDFILE_DIR}
fi
# Returns a list of existing PIDs and a number of PIDs for the process
# having a name specified as an argument to the function.
get_pids() {
local proc_name=${1} # Process name.
# Return the list of PIDs.
_get_pids=$(ps axwwo pid,command | grep ${proc_name} | grep -v grep \
| awk '{print $1}')
# Return the number of PIDs.
_get_pids_num=$(printf "%s" "${_get_pids}" | wc -w | awk '{print $1}')
# construct the PID file name
_pid_file="${pid_file_dir}/${conf_name}.${proc_name}.pid"
# Grab the PID if the file exists
if [ -e ${_pid_file} ]; then
_pid=`cat ${_pid_file}`
if [ $? -ne 0 ]; then
log_error "Error reading PID file: ${_pid_file}"
fi
else
# No file, means no pid
_pid=0;
fi
}
# Checks if the specified process is running. Internally it calls get_pids
# to get the number of processes.
# Checks if the specified process is running by reading its
# PID file and checking the PID it contains. If the file does
# not exist, the process is assumed to not be running.
check_running() {
local proc_name=${1} # Process name.
# Initially mark the process as not running.
_running=0
get_pids ${proc_name}
# If the number of pids is non-zero, the process is running.
if [ ${_get_pids_num} -gt 0 ]; then
_running=1
# Get the PID from the PID file (if it exists)
get_pid_from_file ${proc_name}
if [ ${_pid} -gt 0 ]; then
# Use kill -0 to check if PID is alive
kill -0 ${_pid}
if [ $? -eq 0 ]; then
# No error, so PID IS ALIVE
_running=1
fi
fi
}
# Sends a signal to a group of processes having a specified name.
# Sends a signal to a process based on its PID file
send_signal() {
local sig=${1} # Signal number
local proc_name=${2} # Process name.
# Get all PIDs for the specified process name.
get_pids ${proc_name}
# If no processes running, there is no process we can send the signal
# to. This is not neccessarily an error.
if [ -z ${_get_pids} ]; then
get_pid_from_file ${proc_name}
if [ ${_pid} -eq 0 ]; then
log_info "Skip sending signal ${sig} to process ${proc_name}: \
process is not running\n"
return
fi
# Send a signal to all processes.
kill -${sig} ${_get_pids} >/dev/null 2>&1
if [ $? -ne 0 ]; then
log_error "Failed to send signal ${sig} to process ${proc_name}.\n"
else
kill -${sig} ${_pid}
if [ $? -ne 0 ]; then
log_error "Failed to send signal ${sig} to process ${proc_name}, PID {$_pid}.\n"
fi
fi
}
......@@ -121,8 +148,8 @@ start_server() {
check_running ${binary_name}
# If process is running, don't start another one. Just log a message.
if [ ${_running} -ne 0 ]; then
log_info "Skip starting ${binary_name} \
as another instance is already running."
log_info "${binary_name} appears to be running, see: \
PID ${_pid}, PID file: ${_pid_file}."
else
log_info "Starting ${binary_name} ${args}"
# Start the process.
......@@ -130,6 +157,50 @@ as another instance is already running."
fi
}
# Instruct Kea process to shutdown by sending it signal 15
stop_server() {
binary_path=${1} # Full path to the binary.
local sig=15
# Extract the name of the binary from the path.
local binary_name=$(basename ${binary_path})
# Use the binary name to check if the process is already running.
check_running ${binary_name}
# If process isn't running, don't start another one. Just log a message.
if [ ${_running} -eq 0 ]; then
log_info "${binary_name} isn't running."
else
log_info "Stopping ${binary_name}..."
kill -${sig} ${_pid}
if [ $? -ne 0 ]; then
log_error "Stop failed, could not send signal ${sig} \
to process ${proc_name}, PID ${_pid}.\n"
fi
fi
}
# Instruct Kea process to reload config by sending it signal 1
reload_server() {
binary_path=${1} # Full path to the binary.
local sig=1
# Extract the name of the binary from the path.
local binary_name=$(basename ${binary_path})
# Use the binary name to check if the process is already running.
check_running ${binary_name}
# If process isn't running, don't start another one. Just log a message.
if [ ${_running} -eq 0 ]; then
log_info "${binary_name} isn't running."
else
log_info "Reloading ${binary_name}..."
kill -${sig} ${_pid}
if [ $? -ne 0 ]; then
log_error "Reload failed, could not send signal ${sig} \
to process ${proc_name}, PID ${_pid}.\n"
fi
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)
......@@ -301,18 +372,18 @@ case ${command} in
# Stop running servers.
stop)
# 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
run_conditional "dhcp_ddns" "send_signal 15 $(basename ${dhcp_ddns_srv})" 0
run_conditional "dhcp4" "stop_server ${dhcp4_srv}" 0
run_conditional "dhcp6" "stop_server ${dhcp6_srv}" 0
run_conditional "dhcp_ddns" "stop_server ${dhcp_ddns_srv}" 0
exit 0 ;;
# Reconfigure the servers.
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
run_conditional "dhcp_ddns" "send_signal 1 $(basename ${dhcp_ddns_srv})" 0
run_conditional "dhcp4" "reload_server ${dhcp4_srv}" 0
run_conditional "dhcp6" "reload_server ${dhcp6_srv}" 0
run_conditional "dhcp_ddns" "reload_server ${dhcp_ddns_srv}" 0
exit 0 ;;
......
Supports Markdown
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