--- sbin/runscript.sh.old 2004-11-08 17:10:09.000000000 -0600 +++ sbin/runscript.sh 2004-11-08 17:20:59.000000000 -0600 @@ -269,38 +269,53 @@ do mynetservice="${y##*/}" - if ! service_started "${mynetservice}" - then - start_service "${mynetservice}" + start_service "${mynetservice}" + done + + elif [ "${x}" != "net" ] + then + start_service "${x}" + fi + done + + # Start dependencies, if any + for x in ${startupservices} + do + if [ "${x}" = "net" -a "${NETSERVICE}" != "yes" ] + then + local netservices="$(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \ + $(dolisting "/etc/runlevels/${mylevel}/net.*")" + + for y in ${netservices} + do + mynetservice="${y##*/}" + + wait_service "${mynetservice}" - # A 'need' dependency is critical for startup - if [ "$?" -ne 0 ] && ineed -t "${myservice}" "${x}" >/dev/null + # A 'need' dependency is critical for startup + if [ "$?" -ne 0 ] && ineed -t "${myservice}" "${x}" >/dev/null + then + local netcount="$(ls -1 ${svcdir}/started/net.* 2> /dev/null | \ + grep -v 'net\.lo' | egrep -c "\/net\.[[:alnum:]]+$")" + + # Only worry about a net.* service if we do not have one + # up and running already, or if RC_NET_SCTRICT_CHECKING + # is set .... + if [ "${netcount}" -lt 1 -o "${RC_NET_STRICT_CHECKING}" = "yes" ] then - local netcount="$(ls -1 ${svcdir}/started/net.* 2> /dev/null | \ - grep -v 'net\.lo' | egrep -c "\/net\.[[:alnum:]]+$")" - - # Only worry about a net.* service if we do not have one - # up and running already, or if RC_NET_SCTRICT_CHECKING - # is set .... - if [ "${netcount}" -lt 1 -o "${RC_NET_STRICT_CHECKING}" = "yes" ] - then - startfail="yes" - fi + startfail="yes" fi fi done elif [ "${x}" != "net" ] then - if ! service_started "${x}" - then - start_service "${x}" + wait_service "${x}" - # A 'need' dependacy is critical for startup - if [ "$?" -ne 0 ] && ineed -t "${myservice}" "${x}" >/dev/null - then - startfail="yes" - fi + # A 'need' dependacy is critical for startup + if [ "$?" -ne 0 ] && ineed -t "${myservice}" "${x}" >/dev/null + then + startfail="yes" fi fi done --- /sbin/rc.old 2004-11-08 15:37:41.612986056 -0600 +++ /sbin/rc 2004-11-08 15:14:11.000000000 -0600 @@ -353,6 +353,8 @@ splash "rc_init" "${argv1}" + export START_CRITICAL="yes" + # We do not want to break compatibility, so we do not fully integrate # these into /sbin/rc, but rather start them by hand ... for x in ${CRITICAL_SERVICES} @@ -376,6 +378,8 @@ splash "svc_started" "${x}" "0" done + unset START_CRITICAL + # Check that $svcdir exists ... check_statedir "${svcdir}" --- /lib/rcscripts/sh.old/rc-services.sh 2004-11-04 12:58:59.000000000 -0600 +++ /lib/rcscripts/sh/rc-services.sh 2004-11-08 15:22:58.000000000 -0600 @@ -397,6 +397,69 @@ return 1 } +# bool begin_exclusive( service ) +# +# atomically marks the service as being executed +# use like this: +# +# if begion_exclusive myexclusive ; then +# whatever is in here can only be executed by one process +# end_exclusive myexclusive +# fi + +begin_service() +{ + [ "$START_CRITICAL" == "yes" ] && return 0 + + mkfifo "${svcdir}/exclusive/$1" &> /dev/null + return $? +} + +# void end_exclusive(service, exitcode) +# +# stops executing a exclusive region and +# wakes up anybody who is waiting for the exclusive region +# +end_service() +{ + local newname + + # if we are doing critical services, there is no fifo + + [ "$START_CRITICAL" == "yes" ] && return + + if [ -n "$2" ] ; then + echo "$2" > "${svcdir}/exitcodes/$1" + fi + + # move the fifo to a unique name so noone is waiting for it after we touch it + newname="$(mktemp "${svcdir}/exclusive/$1.XXXXXXXXXX")" + mv -f "${svcdir}/exclusive/$1" "${newname}" + + # wake up anybody that was waiting for the fifo + touch "${newname}" + + # We dont need the fifo anymore + rm -f "${newname}" +} + +# int wait_exclusive(service) + +wait_service() +{ + + local retval + + [ "$START_CRITICAL" == "yes" ] && return 0 + + # this will block until the fifo is touched. It is touched by calling end_exclusive + # if no begin_eclusive has being called or end_exclusive has already finished + # this will not block + cat "${svcdir}/exclusive/$1" 2> /dev/null + retval="$( cat "${svcdir}/exitcodes/$1")" + return "${retval}" +} + # int start_service(service) # # Start 'service' if it is not already running. @@ -406,24 +469,47 @@ [ -z "$1" ] && return 1 - if ! service_started "$1" - then - splash "svc_start" "$1" - if is_fake_service "$1" "${SOFTLEVEL}" + #critical services can not start in parallel and begin_service fails because + #we don't have write permition to ${svcdir} + # so if we are doing critical services, disable the parallel feature + + # if it is not currently running or we are doing critical services + if begin_service "$1" ; then + + + + if ! service_started "$1" then - mark_service_started "$1" - splash "svc_started" "$1" "0" + splash "svc_start" "$1" + if is_fake_service "$1" "${SOFTLEVEL}" + then + mark_service_started "$1" + splash "svc_started" "$1" "0" + end_service "$1" "0" + else + ( + + (. /sbin/runscript.sh "/etc/init.d/$1" start) + retval="$?" + splash "svc_started" "$1" "${retval}" + end_service "$1" "${retval}" + ) & + + # if startup is not parallel, or we are doing criticall services + if [ "${RC_PARALLEL_STARTUP}" != "yes" -o "$START_CRITICAL" == "yes" ] ; then + wait + fi + + fi else - (. /sbin/runscript.sh "/etc/init.d/$1" start) - retval="$?" - splash "svc_started" "$1" "${retval}" - return "${retval}" + end_service "$1" fi fi - + return 0 } + # int stop_service(service) # # Stop 'service' if it is not already running. @@ -469,6 +555,8 @@ mark_service_started() { [ -z "$1" ] && return 1 + echo "0" > "${svcdir}/exitcodes/$1" + ln -snf "/etc/init.d/$1" "${svcdir}/started/$1" return $? @@ -559,60 +647,12 @@ # Schedule 'service' for startup, in parallel if possible. # schedule_service_startup() { - local count=0 - local current_job= - - if [ "${RC_PARALLEL_STARTUP}" = "yes" ] + if ! iparallel "$1" then - set -m +b - - if [ "$(jobs | grep -c "Running")" -gt 0 ] - then - if [ "$(jobs | grep -c "Running")" -eq 1 ] - then - if [ -n "$(jobs)" ] - then - current_job="$(jobs | awk '/Running/ { print $4}')" - fi - - # Wait if we cannot start this service with the already running - # one (running one might start this one ...). - query_before "$1" "${current_job}" && wait - - elif [ "$(jobs | grep -c "Running")" -ge 2 ] - then - count="$(jobs | grep -c "Running")" - - # Wait until we have only one service running - while [ "${count}" -gt 1 ] - do - count="$(jobs | grep -c "Running")" - done - - if [ -n "$(jobs)" ] - then - current_job="$(jobs | awk '/Running/ { print $4}')" - fi - - # Wait if we cannot start this service with the already running - # one (running one might start this one ...). - query_before "$1" "${current_job}" && wait - fi - fi - - if iparallel "$1" - then - eval start_service "$1" \& - else - # Do not start with any service running if we cannot start - # this service in parallel ... -# wait - - start_service "$1" - fi - else - start_service "$1" + wait fi + + start_service "$1" # We do not need to check the return value here, as svc_{start,stop}() do # their own error handling ... --- /sbin/depscan.sh.old 2004-11-08 16:47:06.000000000 -0600 +++ /sbin/depscan.sh 2004-11-08 17:13:43.000000000 -0600 @@ -15,7 +15,7 @@ fi fi -for x in softscripts snapshot options started +for x in softscripts snapshot options started exclusive exitcodes do if [ ! -d "${svcdir}/${x}" ] then