summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/runscript.sh')
-rwxr-xr-xsbin/runscript.sh258
1 files changed, 146 insertions, 112 deletions
diff --git a/sbin/runscript.sh b/sbin/runscript.sh
index 005d7bb..d1960a7 100755
--- a/sbin/runscript.sh
+++ b/sbin/runscript.sh
@@ -17,14 +17,14 @@ svcrestart="no"
myscript="$1"
if [[ -L $1 && ! -L "/etc/init.d/${1##*/}" ]] ; then
- myservice="$(readlink $1)"
+ myservice="$(readlink "$1")"
else
myservice="$1"
fi
myservice="${myservice##*/}"
export SVCNAME="${myservice}"
-mylevel="$(<${svcdir}/softlevel)"
+mylevel="$(< "${svcdir}/softlevel")"
svc_trap() {
trap 'eerror "ERROR: \"${myservice}\" caught an interrupt"; exit 1' \
@@ -64,22 +64,22 @@ if [[ ${NETSERVICE} == "yes" ]] ; then
conf="$(add_suffix /etc/conf.d/net)"
[[ -e ${conf} ]] && source "${conf}"
fi
-conf="$(add_suffix /etc/conf.d/${myservice})"
+conf="$(add_suffix "/etc/conf.d/${myservice}")"
[[ -e ${conf} ]] && source "${conf}"
conf="$(add_suffix /etc/rc.conf)"
[[ -e ${conf} ]] && source "${conf}"
# Call svc_quit if we abort AND we have obtained a lock
-svcbegun=1
service_started "${myservice}"
-svcstarted=$?
+svcstarted="$?"
+service_inactive "${myservice}"
+svcinactive="$?"
svc_quit() {
- eerror "ERROR: \"${myservice}\" caught an interrupt"
- if [[ ${svcbegun} == 0 ]] ; then
- end_service "${myservice}"
- svcbegun=1
- fi
- if [[ ${svcstarted} == 0 ]] ; then
+ eerror "ERROR: ${myservice} caught an interrupt"
+ end_service "${myservice}"
+ if service_inactive "${myservice}" || [[ ${svcinactive} == 0 ]] ; then
+ mark_service_inactive "${myservice}"
+ elif [[ ${svcstarted} == 0 ]] ; then
mark_service_started "${myservice}"
else
mark_service_stopped "${myservice}"
@@ -101,13 +101,13 @@ stop() {
}
start() {
- eerror "ERROR: \"${myservice}\" does not have a start function."
+ eerror "ERROR: ${myservice} does not have a start function."
# Return failure so the symlink doesn't get created
return 1
}
restart() {
- svc_restart || return $?
+ svc_restart
}
status() {
@@ -115,8 +115,33 @@ status() {
return 0
}
+svc_schedule_restart() {
+ local service="$1" restart="$2"
+ [[ ! -d "${svcdir}/restart/${service}" ]] \
+ && mkdir -p "${svcdir}/restart/${service}"
+ [[ ! -e "${svcdir}/restart/${service}/${restart}" ]] \
+ && ln -snf "/etc/init.d/${service}" \
+ "${svcdir}/restart/${service}/${restart}"
+}
+
+svc_start_restart() {
+ [[ ! -d "${svcdir}/restart/${myservice}" ]] && return
+ local x= services= scripts="$(dolisting "${svcdir}/restart/${myservice}/")"
+
+ for x in ${scripts} ; do
+ services="${services} ${x##*/}"
+ done
+
+ for x in $(trace_dependencies "${services}") ; do
+ service_stopped "${x}" && start_service "${x}"
+ rm -f "${svcdir}/restart/${myservice}/${x}"
+ done
+
+ rmdir "${svcdir}/restart/${myservice}"
+}
+
svc_stop() {
- local x= mydep= mydeps= retval=0 was_inactive=false
+ local x= mydep= mydeps= retval=0
local -a servicelist=()
# Do not try to stop if it had already failed to do so on runlevel change
@@ -125,13 +150,12 @@ svc_stop() {
fi
if service_stopped "${myservice}" ; then
- ewarn "WARNING: \"${myservice}\" has not yet been started."
+ ewarn "WARNING: ${myservice} has not yet been started."
return 0
fi
- service_inactive "${myservice}" && was_inactive=true
if ! mark_service_stopping "${myservice}" ; then
- ewarn "WARNING: \"${myservice}\" is already stopping."
+ ewarn "WARNING: ${myservice} is already stopping."
return 0
fi
# Lock service starting too ...
@@ -141,7 +165,6 @@ svc_stop() {
trap "svc_quit" INT QUIT TSTP
begin_service "${myservice}"
- svcbegun=$?
service_message "Stopping service ${myservice}"
@@ -155,13 +178,10 @@ svc_stop() {
# A net.* service
if in_runlevel "${myservice}" "${BOOTLEVEL}" || \
in_runlevel "${myservice}" "${mylevel}" ; then
- # Only worry about net.* services if this is the last one running,
- # or if RC_NET_STRICT_CHECKING is set ...
- if ! is_net_up ; then
- mydeps="net"
- fi
+ # Only worry about net.* services if this is the last one
+ # running or if RC_NET_STRICT_CHECKING is set ...
+ ! is_net_up && mydeps="net"
fi
-
mydeps="${mydeps} ${myservice}"
else
mydeps="${myservice}"
@@ -182,7 +202,14 @@ svc_stop() {
done
done
+ [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
+
for x in "${service_list[@]}" ; do
+ # We need to test if the service has been marked stopped
+ # as the fifo may still be around if called by custom code
+ # such as postup from a net script.
+ service_stopped "${mynetservice}" && continue
+
wait_service "${x}"
if ! service_stopped "${x}" ; then
retval=1
@@ -194,19 +221,28 @@ svc_stop() {
if [[ ${retval} != 0 ]] ; then
eerror "ERROR: problems stopping dependent services."
- eerror " \"${myservice}\" is still up."
+ eerror " ${myservice} is still up."
else
+ # Now that deps are stopped, stop our service
+ (
+ exit() {
+ RC_QUIET_STDOUT="no"
+ eerror "DO NOT USE EXIT IN INIT.D SCRIPTS"
+ eerror "This IS a bug, please fix your broken init.d"
+ unset -f exit
+ exit "$@"
+ }
# Stop einfo/ebegin/eend from working as parallel messes us up
[[ ${RC_PARALLEL_STARTUP} == "yes" ]] && RC_QUIET_STDOUT="yes"
-
- # Now that deps are stopped, stop our service
- ( stop )
- retval=$?
+ stop
+ )
+ retval="$?"
# If a service has been marked inactive, exit now as something
# may attempt to start it again later
if service_inactive "${myservice}" ; then
- [[ ${svcbegun} == 0 ]] && end_service "${myservice}" 0
+ svcinactive=0
+ end_service "${myservice}" 0
return 0
fi
fi
@@ -218,7 +254,7 @@ svc_stop() {
# If we are halting the system, do it as cleanly as possible
if [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" ]] ; then
- if ${was_inactive} ; then
+ if [[ ${svcinactive} == 0 ]] ; then
mark_service_inactive "${myservice}"
else
mark_service_started "${myservice}"
@@ -230,18 +266,15 @@ svc_stop() {
# If we're stopped from a daemon that sets ${IN_BACKGROUND} such as
# wpa_monitor when we mark as inactive instead of taking the down
svcstarted=1
- if ${IN_BACKGROUND:-false} ; then
- mark_service_inactive "${myservice}"
+ if service_inactive "${myservice}" ; then
+ svcinactive=0
else
mark_service_stopped "${myservice}"
fi
service_message "Stopped service ${myservice}"
fi
- if [[ ${svcbegun} == 0 ]] ; then
- end_service "${myservice}" "${retval}"
- svcbegun=1
- fi
+ end_service "${myservice}" "${retval}"
# Reset the trap
svc_trap
@@ -250,7 +283,7 @@ svc_stop() {
}
svc_start() {
- local x= y= retval=0 was_inactive=false startfail="no"
+ local x= y= retval=0 startfail= startinactive=
# Do not try to start if i have done so already on runlevel change
if is_runlevel_start && service_failed "${myservice}" ; then
@@ -258,21 +291,20 @@ svc_start() {
fi
if service_started "${myservice}" ; then
- ewarn "WARNING: \"${myservice}\" has already been started."
+ ewarn "WARNING: ${myservice} has already been started."
return 0
elif service_stopping "${myservice}" ; then
- eerror "ERROR: please wait for \"${myservice}\" to stop first."
+ eerror "ERROR: please wait for ${myservice} to stop first."
return 1
elif service_inactive "${myservice}" ; then
if [[ ${IN_BACKGROUND} != "true" ]] ; then
- ewarn "WARNING: \"${myservice}\" has already been started."
+ ewarn "WARNING: ${myservice} has already been started."
return 0
fi
fi
- service_inactive "${myservice}" && was_inactive=true
if ! mark_service_starting "${myservice}" ; then
- ewarn "WARNING: \"${myservice}\" is already starting."
+ ewarn "WARNING: ${myservice} is already starting."
return 0
fi
@@ -280,25 +312,25 @@ svc_start() {
trap "svc_quit" INT QUIT TSTP
begin_service "${myservice}"
- svcbegun=$?
-
service_message "Starting service ${myservice}"
+
+ # Save the IN_BACKGROUND var as we need to clear it for starting depends
+ local ib_save="${IN_BACKGROUND}"
+ unset IN_BACKGROUND
local startupservices="$(trace_dependencies $(ineed "${myservice}") \
- $(valid_iuse ${myservice}))"
+ $(valid_iuse "${myservice}"))"
local netservices="$(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \
$(dolisting "/etc/runlevels/${mylevel}/net.*")"
- local mynetservice=
+ local startupnetservices=
# Start dependencies, if any.
# We don't handle "after" deps here as it's the job of rc to start them.
for x in ${startupservices} ; do
if [[ ${x} == "net" && ${NETSERVICE} != "yes" ]] && ! is_net_up ; then
for y in ${netservices} ; do
- mynetservice="${y##*/}"
- if service_stopped "${mynetservice}" ; then
- start_service "${mynetservice}"
- fi
+ y="${y##*/}"
+ service_stopped "${y}" && start_service "${y}"
done
elif [[ ${x} != "net" ]] ; then
if service_stopped "${x}" ; then
@@ -307,102 +339,116 @@ svc_start() {
fi
done
+ [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
+
# We also wait for any services we're after to finish incase they
# have a "before" dep but we don't dep on them.
if is_runlevel_start ; then
- startupservices="${startupservices} $(valid_iafter ${myservice})"
+ startupservices="${startupservices} $(valid_iafter "${myservice}")"
fi
# Wait for dependencies to finish.
for x in ${startupservices} ; do
if [[ ${x} == "net" && ${NETSERVICE} != "yes" ]] ; then
for y in ${netservices} ; do
- mynetservice="${y##*/}"
-
- wait_service "${mynetservice}"
-
- if ! service_started "${mynetservice}" ; then
+ y="${y##*/}"
+ # Don't wait if it's already been started
+ service_started "${y}" && continue
+ wait_service "${y}"
+ if ! service_started "${y}" ; then
# A 'need' dependency is critical for startup
if ineed -t "${myservice}" "${x}" >/dev/null ; then
- # Only worry about a net.* service if we do not have one
- # up and running already, or if RC_NET_STRICT_CHECKING
- # is set ....
if ! is_net_up ; then
- startfail="yes"
+ if service_inactive "${y}" ; then
+ svc_schedule_restart "${y}" "${myservice}"
+ startinactive="${y}"
+ else
+ startfail="${y}"
+ fi
+ break
fi
fi
fi
done
elif [[ ${x} != "net" ]] ; then
+ # Don't wait if it's already been started
+ service_started "${x}" && continue
wait_service "${x}"
if ! service_started "${x}" ; then
# A 'need' dependacy is critical for startup
if ineed -t "${myservice}" "${x}" >/dev/null ; then
- startfail="yes"
+ if service_inactive "${x}" ; then
+ svc_schedule_restart "${x}"
+ startinactive="${x}"
+ else
+ startfail="${x}"
+ fi
+ break
fi
fi
fi
done
if [[ ${startfail} == "yes" ]] ; then
- eerror "ERROR: Problem starting needed services."
- eerror " \"${myservice}\" was not started."
+ eerror "ERROR: Problem starting needed service ${startfail}."
+ eerror " ${myservice} was not started."
+ retval=1
+ elif [[ -n ${startinactive} ]] ; then
+ ewarn "WARNING: ${myservice} is scheduled to start when ${startinactive} has started."
retval=1
elif broken "${myservice}" ; then
eerror "ERROR: Some services needed are missing. Run"
eerror " './${myservice} broken' for a list of those"
- eerror " services. \"${myservice}\" was not started."
+ eerror " services. ${myservice} was not started."
retval=1
else
+ IN_BACKGROUND="${ib_save}"
(
exit() {
RC_QUIET_STDOUT="no"
eerror "DO NOT USE EXIT IN INIT.D SCRIPTS"
eerror "This IS a bug, please fix your broken init.d"
unset -f exit
- exit $@
+ exit "$@"
}
# Stop einfo/ebegin/eend from working as parallel messes us up
[[ ${RC_PARALLEL_STARTUP} == "yes" ]] && RC_QUIET_STDOUT="yes"
start
)
- retval=$?
+ retval="$?"
# If a service has been marked inactive, exit now as something
# may attempt to start it again later
if service_inactive "${myservice}" ; then
- [[ ${svcbegun} == 0 ]] && end_service "${myservice}" 1
+ svcinactive=0
+ end_service "${myservice}" 1
return 1
fi
fi
if [[ ${retval} != 0 ]] ; then
- is_runlevel_start && mark_service_failed "${myservice}"
-
# Remove link if service didn't start; but only if we're not booting
# If we're booting, we need to continue and do our best to get the
# system up.
if [[ ${SOFTLEVEL} != "${BOOTLEVEL}" ]] ; then
- if ${was_inactive} ; then
+ if [[ ${svcinactive} == 0 ]] ; then
mark_service_inactive "${myservice}"
else
mark_service_stopped "${myservice}"
fi
fi
- service_message "eerror" "FAILED to start service ${myservice}!"
+ if [[ -z ${startinactive} ]] ; then
+ is_runlevel_start && mark_service_failed "${myservice}"
+ service_message "eerror" "FAILED to start service ${myservice}!"
+ fi
else
svcstarted=0
mark_service_started "${myservice}"
-
service_message "Service ${myservice} started OK"
fi
- if [[ ${svcbegun} == 0 ]] ; then
- end_service "${myservice}" "${retval}"
- svcbegun=1
- fi
-
+ end_service "${myservice}" "${retval}"
# Reset the trap
svc_trap
@@ -413,7 +459,7 @@ svc_restart() {
if ! service_stopped "${myservice}" ; then
svc_stop || return "$?"
fi
- svc_start || return "$?"
+ svc_start
}
svc_status() {
@@ -448,12 +494,13 @@ svc_status() {
&& ${efunc} "status: ${state}"
status
- [[ ${efunc} != "eerror" ]]
+ # Return 0 if started, otherwise 1
+ [[ ${state} == "started" ]]
}
-rcscript_errors="$(bash -n ${myscript} 2>&1)" || {
+rcscript_errors="$(bash -n "${myscript}" 2>&1)" || {
[[ -n ${rcscript_errors} ]] && echo "${rcscript_errors}" >&2
- eerror "ERROR: \"${myscript}\" has syntax errors in it; aborting ..."
+ eerror "ERROR: ${myscript} has syntax errors in it; aborting ..."
exit 1
}
@@ -517,7 +564,7 @@ for arg in $* ; do
case "${arg}" in
stop)
if [[ -e "${svcdir}/restart/${myservice}" ]] ; then
- rm -f "${svcdir}/restart/${myservice}"
+ rm -Rf "${svcdir}/restart/${myservice}"
fi
# Stoped from the background - treat this as a restart so that
@@ -525,33 +572,27 @@ for arg in $* ; do
if [[ ${IN_BACKGROUND} == "true" ]] ; then
rm -rf "${svcdir}/snapshot/$$"
mkdir -p "${svcdir}/snapshot/$$"
- cp -a "${svcdir}"/started/* "${svcdir}/snapshot/$$/"
+ cp -pP "${svcdir}"/started/* "${svcdir}/snapshot/$$/"
fi
svc_stop
-
+ retval="$?"
+
if [[ ${IN_BACKGROUND} == "true" ]] ; then
- res=
for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
if service_stopped "${x##*/}" ; then
- res="${res}${x##*/} "
+ svc_schedule_restart "${myservice}" "${x##*/}"
fi
done
- [[ -n ${res} ]] && echo "${res}" > "${svcdir}/restart/${myservice}"
fi
+
+ exit "${retval}"
;;
start)
svc_start
retval=$?
- if ! is_runlevel_start && [[ -s "${svcdir}/restart/${myservice}" ]] ; then
- for x in $(trace_dependencies $(< "${svcdir}/restart/${myservice}")) ; do
- service_stopped "${x}" && start_service "${x}"
- done
- fi
- if [[ -e "${svcdir}/restart/${myservice}" ]] ; then
- rm -f "${svcdir}/restart/${myservice}"
- fi
- exit ${retval}
+ service_started "${myservice}" && svc_start_restart
+ exit "${retval}"
;;
needsme|ineed|usesme|iuse|broken)
trace_dependencies "-${arg}"
@@ -579,7 +620,7 @@ for arg in $* ; do
# Create a snapshot of started services
rm -rf "${svcdir}/snapshot/$$"
mkdir -p "${svcdir}/snapshot/$$"
- cp -a "${svcdir}"/started/* "${svcdir}/snapshot/$$/"
+ cp -pP "${svcdir}"/started/* "${svcdir}/snapshot/$$/"
# Simple way to try and detect if the service use svc_{start,stop}
# to restart if it have a custom restart() funtion.
@@ -599,27 +640,20 @@ for arg in $* ; do
restart
fi
+ [[ -e "${svcdir}/restart/${myservice}" ]] \
+ && rm -f "${svcdir}/restart/${myservice}"
+
# Restart dependencies as well
- if service_started "${myservice}" ; then
- for x in $(trace_dependencies \
- $(dolisting "${svcdir}/snapshot/$$/") ) ; do
- if service_stopped "${x##*/}" ; then
- start_service "${x##*/}"
- fi
- done
- elif service_inactive "${myservice}" ; then
- res=
+ if service_inactive "${myservice}" ; then
for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
if service_stopped "${x##*/}" ; then
- res="${res}${x##*/} "
+ svc_schedule_restart "${myservice}" "${x##*/}"
fi
done
- [[ -n ${res} ]] && echo "${res}" > "${svcdir}/restart/${myservice}"
+ elif service_started "${myservice}" ; then
+ svc_start_restart
fi
- # Wait for any services that may still be running ...
- [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
-
rm -rf "${svcdir}/snapshot/$$"
svcrestart="no"
;;