diff -ru orig/etc/conf.d/rc change/etc/conf.d/rc --- orig/etc/conf.d/rc 2006-01-06 22:18:53.000000000 +0100 +++ change/etc/conf.d/rc 2006-01-10 22:16:14.000000000 +0100 @@ -179,6 +179,15 @@ svcdir="/var/lib/init.d" +# rc-scripts locking directory +# +# NOTE: Do not remove the next line, as its needed by the baselayout ebuild! +# +# svclock="/var/lib/init.d/locks" + +svclock="/var/lib/init.d/locks" + + # Should we mount $svcdir in a ram disk for some speed increase # for slower machines, or for the more extreme setups ? Only in change/lib/rcscripts/sh: rc-locking.sh diff -ru orig/lib/rcscripts/sh/rc-services.sh change/lib/rcscripts/sh/rc-services.sh --- orig/lib/rcscripts/sh/rc-services.sh 2006-01-06 22:15:42.000000000 +0100 +++ change/lib/rcscripts/sh/rc-services.sh 2006-01-10 23:06:31.000000000 +0100 @@ -6,6 +6,7 @@ RC_GOT_SERVICES="yes" [[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh +[[ ${RC_GOT_LOCKING} != "yes" ]] && source "${svclib}/sh/rc-locking.sh" if [[ ${RC_GOT_DEPTREE_INFO} != "yes" ]] ; then # Only try and update if we are root @@ -357,19 +358,36 @@ mark_service_stopped "${service}" return 1 fi + + lock "status" + + if service_starting "${service}" || + service_started "${service}" + then + unlock "status" + return 0 + fi - service_starting "${service}" && return 0 - service_started "${service}" && return 0 - service_inactive "${service}" && return 1 + if service_inactive "${service}" ; then + unlock "status" + return 1 + fi if is_fake_service "${service}" "${SOFTLEVEL}" ; then mark_service_started "${service}" + unlock "status" splash "svc_start" "${service}" splash "svc_started" "${service}" "0" return 0 fi - begin_service "${service}" || return 0 + if ! begin_service "${service}" ; then + unlock "status" + return 0 + fi + + unlock "status" + splash "svc_start" "${service}" if [[ ${RC_PARALLEL_STARTUP} != "yes" || \ ${START_CRITICAL} == "yes" ]] ; then @@ -405,8 +423,14 @@ return 0 fi - service_stopping "${service}" && return 0 - service_stopped "${service}" && return 0 + lock "status" + + if service_stopping "${service}" || + service_stopped "${service}" + then + unlock "status" + return 0 + fi local level="${SOFTLEVEL}" is_runlevel_stop && level="${OLDSOFTLEVEL}" @@ -414,11 +438,16 @@ if is_fake_service "${service}" "${level}" ; then splash "svc_stop" "${service}" mark_service_stopped "${service}" + unlock "status" splash "svc_stopped" "${service}" "0" return 0 fi - begin_service "${service}" || return 0 + if ! begin_service "${service}" ; then + unlock "status" + return 0 + fi + unlock "status" splash "svc_stop" "${service}" if [[ ${RC_PARALLEL_STARTUP} != "yes" || \ @@ -449,6 +478,8 @@ mark_service_starting() { [[ -z $1 ]] && return 1 + lock "status" + ln -snf "/etc/init.d/$1" "${svcdir}/starting/$1" local retval=$? @@ -456,6 +487,8 @@ [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1" [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1" + unlock "status" + return "${retval}" } @@ -466,6 +499,8 @@ mark_service_started() { [[ -z $1 ]] && return 1 + lock "status" + ln -snf "/etc/init.d/$1" "${svcdir}/started/$1" local retval=$? @@ -473,6 +508,8 @@ [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1" [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1" + unlock "status" + return "${retval}" } @@ -483,12 +520,16 @@ mark_service_inactive() { [[ -z $1 ]] && return 1 + lock "status" + ln -snf "/etc/init.d/$1" "${svcdir}/inactive/$1" local retval=$? [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1" [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1" [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1" + unlock "status" + return "${retval}" } @@ -499,6 +540,8 @@ mark_service_stopping() { [[ -z $1 ]] && return 1 + lock "status" + ln -snf "/etc/init.d/$1" "${svcdir}/stopping/$1" local retval=$? @@ -506,6 +549,8 @@ [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1" [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1" + unlock "status" + return "${retval}" } @@ -516,12 +561,16 @@ mark_service_stopped() { [[ -z $1 ]] && return 1 + lock "status" + [[ -f "${svcdir}/daemons/$1" ]] && rm -f "${svcdir}/daemons/$1" [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1" [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1" [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1" [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1" + unlock "status" + return $? } @@ -580,11 +629,18 @@ service_stopped() { [[ -z $1 ]] && return 1 - service_starting "$1" && return 1 - service_started "$1" && return 1 - service_stopping "$1" && return 1 - service_inactive "$1" && return 1 + lock "status" + + if service_starting "$1" || + service_started "$1" || + service_stopping "$1" || + service_inactive "$1" + then + unlock "status" + return 1 + fi + unlock "status" return 0 } Only in change: rc-execution.sh diff -ru orig/sbin/functions.sh change/sbin/functions.sh --- orig/sbin/functions.sh 2006-01-06 22:15:42.000000000 +0100 +++ change/sbin/functions.sh 2006-01-10 23:06:11.000000000 +0100 @@ -12,6 +12,7 @@ # Check /etc/conf.d/rc for a description of these ... svclib="/lib/rcscripts" svcdir=${svcdir:-/var/lib/init.d} +svclock=${svclock:-/var/lib/init.d/locks} svcmount=${svcmount:-no} svcfstype=${svcfstype:-tmpfs} svcsize=${svcsize:-1024} diff -ru orig/sbin/rc change/sbin/rc --- orig/sbin/rc 2006-01-06 22:15:42.000000000 +0100 +++ change/sbin/rc 2006-01-10 22:24:35.000000000 +0100 @@ -489,7 +489,15 @@ # Update the dependency cache /sbin/depscan.sh -u - + + # Create locking directory + if [[ ! -d "${svclock}" ]] ; then + if ! mkdir -p -m 0755 "${svclock}" 2>/dev/null ; then + eerror "Could not create needed directory '${svclock}'!" + fi + fi + + # Now that the dependency cache are up to date, make sure these # are marked as started ... ( diff -ru orig/sbin/runscript.sh change/sbin/runscript.sh --- orig/sbin/runscript.sh 2006-01-06 22:15:42.000000000 +0100 +++ change/sbin/runscript.sh 2006-01-10 23:14:35.000000000 +0100 @@ -88,16 +88,21 @@ local ordservice= local was_inactive=false + lock "status" + if service_stopping "${myservice}" ; then + unlock "status" eerror "ERROR: \"${myservice}\" is already stopping." return 0 elif service_stopped "${myservice}" ; then + unlock "status" eerror "ERROR: \"${myservice}\" has not yet been started." return 0 fi # Do not try to stop if it had already failed to do so on runlevel change if is_runlevel_stop && service_failed "${myservice}" ; then + unlock "status" return 1 fi @@ -105,6 +110,8 @@ # Remove symlink to prevent recursion mark_service_stopping "${myservice}" + + unlock "status" service_message "Stopping service ${myservice}" @@ -257,28 +265,38 @@ local myserv= local ordservice= + lock "status" + if service_starting "${myservice}" ; then + unlock "status" ewarn "WARNING: \"${myservice}\" is already starting." return 0 elif service_stopping "${myservice}" ; then + unlock "status" ewarn "WARNING: please wait for \"${myservice}\" to stop first." return 0 elif service_inactive "${myservice}" ; then + unlock "status" if [[ ${IN_BACKGROUND} != "true" ]] ; then ewarn "WARNING: \"${myservice}\" has already been started." return 0 fi elif service_started "${myservice}" ; then + unlock "status" ewarn "WARNING: \"${myservice}\" has already been started." return 0 fi # Do not try to start if i have done so already on runlevel change if is_runlevel_start && service_failed "${myservice}" ; then + unlock "status" return 1 fi mark_service_starting "${myservice}" + + unlock "status" + service_message "Starting service ${myservice}" # On rc change, start all services "before $myservice" first @@ -302,7 +320,7 @@ if service_stopped "${mynetservice}" ; then start_service "${mynetservice}" fi - done + done elif [[ ${x} != "net" ]] ; then if service_stopped "${x}" ; then start_service "${x}" @@ -411,7 +430,9 @@ # If we are effectively root, check to see if required daemons are running # and update our status accordingly [[ ${EUID} == 0 ]] && update_service_status "${myservice}" - + + lock "status" + if service_starting "${myservice}" ; then efunc="einfo" state="starting" @@ -428,6 +449,9 @@ efunc="eerror" state="stopped" fi + + unlock "status" + [[ ${RC_QUIET_STDOUT} != "yes" ]] \ && ${efunc} "status: ${state}"