public inbox for gentoo-dev@lists.gentoo.org
 help / color / mirror / Atom feed
From: Roy Marples <uberlord@gentoo.org>
To: gentoo-dev@lists.gentoo.org
Subject: Re: [gentoo-dev] init script guidelines
Date: Wed, 31 Aug 2005 08:13:28 +0100	[thread overview]
Message-ID: <1125472408.11354.7.camel@uberpc.ubernet> (raw)
In-Reply-To: <200508231609.52681.pauldv@gentoo.org>

[-- Attachment #1: Type: text/plain, Size: 1515 bytes --]

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

[-- Attachment #2: rc-init-status.patch --]
[-- Type: text/x-patch, Size: 5126 bytes --]

--- 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<${#RC_DAEMONS[@]}; 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<${#RC_DAEMONS[@]}; 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=( "${RC_DAEMONS[@]}" )
+					RC_PIDFILES=( "${RC_PIDFILES[@]}" )
+					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="${#RC_DAEMONS[@]}"
+			RC_DAEMONS[max]="${cmd}"
+			RC_PIDFILES[max]="${pidfile}"
+		fi
+	fi
+
+	# Write the new list of daemon states for this service
+	if [[ ${#RC_DAEMONS[@]} == "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<${#RC_DAEMONS[@]}; 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

[-- Attachment #3: sshd-ssd.patch --]
[-- Type: text/x-patch, Size: 490 bytes --]

--- 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 $?
 }

  reply	other threads:[~2005-08-31  7:15 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-07-19 16:42 [gentoo-dev] init script guidelines Eric Brown
2005-07-19 17:22 ` Chris Gianelloni
2005-07-19 17:45 ` Mike Frysinger
2005-07-19 18:00 ` Roy Marples
2005-07-19 22:16   ` Francesco R
2005-08-23 14:09   ` Paul de Vrieze
2005-08-31  7:13     ` Roy Marples [this message]
2005-08-31  8:05       ` Roy Marples
2005-08-31  8:24         ` Georgi Georgiev
2005-08-31  8:32           ` [gentoo-dev] OT: cvs $Header not substituted Georgi Georgiev
2005-08-31  8:42             ` Brian Harring
2005-08-31  8:54               ` Roy Marples
2005-08-31 10:05                 ` Paul de Vrieze
2005-08-31 10:19                   ` Roy Marples
2005-08-31 13:07                   ` Mike Frysinger
2005-08-31 17:38       ` [gentoo-dev] init script guidelines Roy Marples
2005-07-19 18:14 ` Francesco R
  -- strict thread matches above, loose matches on Subject: below --
2005-07-19 18:08 Eric Brown
2005-07-19 18:40 ` Chris Gianelloni
2005-07-19 20:43   ` Michael Cummings
2005-07-19 21:07     ` Chris Gianelloni
2005-07-19 21:53   ` Martin Schlemmer
2005-07-20  6:30     ` Roy Marples
2005-07-19 20:03 ` Mike Frysinger
2005-07-19 19:39 Eric Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1125472408.11354.7.camel@uberpc.ubernet \
    --to=uberlord@gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox