From mboxrd@z Thu Jan  1 00:00:00 1970
Received: from lists.gentoo.org ([140.105.134.102] helo=robin.gentoo.org)
	by nuthatch.gentoo.org with esmtp (Exim 4.43)
	id 1EAMoz-0007uP-Tw
	for garchives@archives.gentoo.org; Wed, 31 Aug 2005 07:15:46 +0000
Received: from robin.gentoo.org (localhost [127.0.0.1])
	by robin.gentoo.org (8.13.4/8.13.4) with SMTP id j7V7CrEp005834;
	Wed, 31 Aug 2005 07:12:53 GMT
Received: from anchor-post-31.mail.demon.net (anchor-post-31.mail.demon.net [194.217.242.89])
	by robin.gentoo.org (8.13.4/8.13.4) with ESMTP id j7V7BEC0026933
	for <gentoo-dev@lists.gentoo.org>; Wed, 31 Aug 2005 07:11:14 GMT
Received: from rsm.demon.co.uk ([80.177.111.50] helo=mail.ubernet)
	by anchor-post-31.mail.demon.net with esmtp (Exim 4.42)
	id 1EAMhW-000Cu5-4x
	for gentoo-dev@lists.gentoo.org; Wed, 31 Aug 2005 07:08:02 +0000
Received: from uberpc.ubernet (uberpc.ubernet [192.168.2.10])
	(using TLSv1 with cipher RC4-MD5 (128/128 bits))
	(No client certificate requested)
	by mail.ubernet (Postfix) with ESMTP id 521152B4032
	for <gentoo-dev@lists.gentoo.org>; Wed, 31 Aug 2005 08:13:28 +0100 (BST)
Subject: Re: [gentoo-dev] init script guidelines
From: Roy Marples <uberlord@gentoo.org>
To: gentoo-dev@lists.gentoo.org
In-Reply-To: <200508231609.52681.pauldv@gentoo.org>
References: <16CC9569DA3E4D41A1D4BC25D7B5A16A473A7C@hercules.magbank.com>
	 <1121796031.10337.6.camel@uberpc.ubernet>
	 <200508231609.52681.pauldv@gentoo.org>
Content-Type: multipart/mixed; boundary="=-NSGCbOsarGK3bkgvzNQy"
Date: Wed, 31 Aug 2005 08:13:28 +0100
Message-Id: <1125472408.11354.7.camel@uberpc.ubernet>
Precedence: bulk
List-Post: <mailto:gentoo-dev@lists.gentoo.org>
List-Help: <mailto:gentoo-dev+help@gentoo.org>
List-Unsubscribe: <mailto:gentoo-dev+unsubscribe@gentoo.org>
List-Subscribe: <mailto:gentoo-dev+subscribe@gentoo.org>
List-Id: Gentoo Linux mail <gentoo-dev.gentoo.org>
X-BeenThere: gentoo-dev@gentoo.org
Reply-to: gentoo-dev@lists.gentoo.org
Mime-Version: 1.0
X-Mailer: Evolution 2.2.3 
X-Archives-Salt: 2ed97852-0aa6-42e8-9c2b-a5fdeab69200
X-Archives-Hash: 9f652e0bb0529a9b1440531c30b10566


--=-NSGCbOsarGK3bkgvzNQy
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

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

--=-NSGCbOsarGK3bkgvzNQy
Content-Disposition: attachment; filename=rc-init-status.patch
Content-Type: text/x-patch; name=rc-init-status.patch; charset=utf8
Content-Transfer-Encoding: 7bit

--- 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

--=-NSGCbOsarGK3bkgvzNQy
Content-Disposition: attachment; filename=sshd-ssd.patch
Content-Type: text/x-patch; name=sshd-ssd.patch; charset=utf8
Content-Transfer-Encoding: 7bit

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

--=-NSGCbOsarGK3bkgvzNQy--

-- 
gentoo-dev@gentoo.org mailing list