On Tue, 2005-08-23 at 16:09 +0200, Paul de Vrieze wrote:
> What I would really like to see in the init system is a way that
> initscripts can check whether the services they are responsible for are
> still running and then adjust their status accordingly, along with some
> nice output. This would then allow the execution of rc-status to give
> proper information of actually running daemons, and the "rc" command the
> possibility to actually bring online all daemons that should be running.
>
> Paul
>
Attached is a patch to baselayout-1.12.0_pre6-r3 that allows this.
Basically when an init script calls start-stop-daemon --start then we
log what it started (and hopefully a pidfile) in
${svcdir}/daemons/${myservice}
When it's status is asked for (either init.d/foo status or rc-status)
then we load this daemon file and check to see if the given daemons are
still running. If not then we call init.d/foo stop. We do this instead
of just marking the daemon as stopped in-case there is any clean-up code
that's needed to be run by the init script.
For this to work well, start-stop-daemon needs to be used correctly, not
just to stop it (like most init scripts seem to). sshd is a popular init
script and on most Gentoo'ers systems, so I've attached a patch so show
how init script should use start-stop-daemon so this works correctly.
What do people think about this? Is this worthfile and fixing all the
init scripts in the tree to use start-stop-daemon correctly AND for
starting up?
Thanks
Roy
--- rc-status 2005-08-01 21:26:00.000000000 +0100
+++ /bin/rc-status 2005-08-31 07:57:15.000000000 +0100
@@ -31,6 +31,7 @@
# grab settings from conf.d/rc
source /etc/conf.d/rc
+source "${svclib}/sh/rc-daemon.sh"
################################################################################
# Parse command line options #
@@ -157,10 +158,19 @@
# Now collect information about the status of the various services; whether #
# they're started, broken, or failed. Put all of this into arrays. #
################################################################################
-# Read services from ${svcdir}/{started,failed,broken}
+if [[ -x ${svcdir}/started ]]; then
+ started=$(ls ${svcdir}/started)
+ # If we're root then update service statuses incase any naughty daemons
+ # stopped running without our say so
+ if [[ ${EUID} == 0 ]]; then
+ for service in ${started}; do
+ update_service_status "${service}"
+ done
+ started=$(ls ${svcdir}/started)
+ fi
+fi
[[ -x ${svcdir}/starting ]] && starting=$(ls ${svcdir}/starting)
[[ -x ${svcdir}/inactive ]] && inactive=$(ls ${svcdir}/inactive)
-[[ -x ${svcdir}/started ]] && started=$(ls ${svcdir}/started)
[[ -x ${svcdir}/stopping ]] && stopping=$(ls ${svcdir}/stopping)
################################################################################
--- runscript.sh 2005-08-21 18:08:24.000000000 +0100
+++ /sbin/runscript.sh 2005-08-31 07:59:30.000000000 +0100
@@ -413,6 +413,10 @@
# to work with the printed " * status: foo".
local efunc="" state=""
+ # If we are effectively root, check to see if required daemons are running
+ # and update our status accordingly
+ [[ ${EUID} == 0 ]] && update_service_status "${myservice}"
+
if service_starting "${myservice}" ; then
efunc="einfo"
state="starting"
--- rc-daemon.sh 2005-08-30 07:22:39.000000000 +0100
+++ /lib/rcscripts/sh/rc-daemon.sh 2005-08-31 07:53:14.000000000 +0100
@@ -19,6 +19,7 @@
RC_GOT_DAEMON="yes"
[[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh
+[[ ${RC_GOT_SERVICES} != "yes" ]] && source "${svclib}/sh/rc-services.sh"
RC_RETRY_KILL="no"
RC_RETRY_TIMEOUT=1
@@ -285,14 +286,45 @@
return "${retval}"
}
+# void update_service_status(char *service)
+#
+# Loads the service state file and ensures that all listed daemons are still
+# running - hopefully on their correct pids too
+# If not, we stop the service
+update_service_status() {
+ local service="$1" daemonfile="${svcdir}/daemons/$1" i
+ local -a RC_DAEMONS=() RC_PIDFILES=()
+
+ # We only care about marking started services as stopped if the daemon(s)
+ # for it are no longer running
+ ! service_started "${service}" && return
+ [[ ! -f ${daemonfile} ]] && return
+
+ # OK, now check that every daemon launched is active
+ # If the --start command was any good a pidfile was specified too
+ source "${daemonfile}"
+ for (( i=0; i<[EMAIL PROTECTED]; i++ )); do
+ if ! is_daemon_running ${RC_DAEMONS[i]} "${RC_PIDFILES[i]}" ; then
+ if [[ -e "/etc/init.d/${service}" ]]; then
+ /etc/init.d/"${service}" stop &>/dev/null
+ break
+ fi
+ fi
+ done
+}
+
# int start-stop-daemon(...)
#
# Provide a wrapper to start-stop-daemon
# Return the result of start_daemon or stop_daemon depending on
# how we are called
start-stop-daemon() {
- local args=$( requote "$@" )
- local cmd pidfile pid stopping signal nothing=false
+ local args=$( requote "$@" ) result i
+ local cmd pidfile pid stopping signal nothing=false
+ local daemonfile="${svcdir}/daemons/${myservice}"
+ local -a RC_DAEMONS=() RC_PIDFILES=()
+
+ [[ -e ${daemonfile} ]] && source "${daemonfile}"
rc_setup_daemon_vars
@@ -303,10 +335,49 @@
fi
if ${stopping}; then
- rc_stop_daemon
+ rc_stop_daemon
+ result="$?"
+ if [[ ${result} == "0" ]]; then
+ # We stopped the daemon successfully
+ # so we remove it from our state
+ for (( i=0; i<[EMAIL PROTECTED]; i++ )); do
+ # We should really check for valid cmd AND pidfile
+ # But most called to --stop only set the pidfile
+ if [[ ${RC_DAEMONS[i]} == "{cmd}" \
+ || ${RC_PIDFILES[i]}="${pidfile}" ]]; then
+ unset RC_DAEMONS[i] RC_PIDFILES[i]
+ RC_DAEMONS=( "[EMAIL PROTECTED]" )
+ RC_PIDFILES=( "[EMAIL PROTECTED]" )
+ break
+ fi
+ done
+ fi
else
rc_start_daemon
+ result="$?"
+ if [[ ${result} == "0" ]]; then
+ # We started the daemon sucessfully
+ # so we add it to our state
+ local max="[EMAIL PROTECTED]"
+ RC_DAEMONS[max]="${cmd}"
+ RC_PIDFILES[max]="${pidfile}"
+ fi
+ fi
+
+ # Write the new list of daemon states for this service
+ if [[ [EMAIL PROTECTED] == "0" ]]; then
+ [[ -f ${daemonfile} ]] && rm -f "${daemonfile}"
+ else
+ echo "RC_DAEMONS[0]=\"${RC_DAEMONS[0]}\"" > "${daemonfile}"
+ echo "RC_PIDFILES[0]=\"${RC_PIDFILES[0]}\"" >> "${daemonfile}"
+
+ for (( i=1; i<[EMAIL PROTECTED]; i++ )); do
+ echo "RC_DAEMONS[${i}]=\"${RC_DAEMONS[i]}\"" >> "${daemonfile}"
+ echo "RC_PIDFILES[${i}]=\"${RC_PIDFILES[i]}\"" >> "${daemonfile}"
+ done
fi
+
+ return "${result}"
}
# vim:ts=4
--- sshd.orig 2005-08-31 08:07:05.000000000 +0100
+++ sshd 2005-08-31 08:08:05.000000000 +0100
@@ -40,12 +40,14 @@
start() {
checkconfig || return 1
ebegin "Starting sshd"
- /usr/sbin/sshd
+ start-stop-daemon --start --exec /usr/sbin/sshd \
+ --pidfile /var/run/sshd.pid
eend $?
}
stop() {
ebegin "Stopping sshd"
- start-stop-daemon --stop --quiet --pidfile /var/run/sshd.pid
+ start-stop-daemon --stop --exec /usr/bin/sshd \
+ --pidfile /var/run/sshd.pid
eend $?
}