From 5ad71a399280f9210b1076099b7ee64ed36ff0b8 Mon Sep 17 00:00:00 2001 From: Christian Heim Date: Sun, 15 Jan 2006 10:42:17 +0000 Subject: Merging r1822 from trunk svn path=/baselayout-vserver/trunk/; revision=208 --- ChangeLog | 29 +++ ChangeLog.vserver | 21 +++ bin/rc-status | 3 +- net-scripts/init.d/net.lo | 9 + net-scripts/net.modules.d/bonding | 4 +- net-scripts/net.modules.d/bridge | 4 +- net-scripts/net.modules.d/helpers.d/functions | 6 +- net-scripts/net.modules.d/ifconfig | 7 +- net-scripts/net.modules.d/iproute2 | 5 +- sbin/functions.sh | 2 +- sbin/init.linux.sh | 2 - sbin/rc | 47 +++-- sbin/rc-daemon.sh | 26 +-- sbin/rc-services.sh | 27 +-- sbin/runscript.sh | 258 +++++++++++++++----------- 15 files changed, 269 insertions(+), 181 deletions(-) diff --git a/ChangeLog b/ChangeLog index e4514a7..38c6294 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,33 @@ # ChangeLog for Gentoo System Intialization ("rc") scripts # Copyright 1999-2006 Gentoo Foundation; Distributed under the GPLv2 + 14 Jan 2006; Roy Marples : + + Changed runscript.sh to store it's services to restart like rc. + +* baselayout-1.12.0_pre14 (13 Jan 2006) + + 13 Jan 2006; Mike Frysinger : + + Filter all of fuse as network based since there's no way for us to know + if the thing is local or not #118552 by Pete Ezzo.' + + 13 Jan 2006; Roy Marples : + + Added warning to modules.autoload.d files stating that it's a bad idea + to put modules there that trigger hotplug events which in turn start + services, #118419. + + Services that need a service which is inactive at boot are now scheduled + to start when the inactive service starts, #118801. + + 12 Jan 2006; Roy Marples : + + Interactive start is now controllable by RC_INTERACTIVE="yes" and will + probe to see if we can go interactive. + + Interactive start should now work on Sparc, #104067. + 11 Jan 2006; Roy Marples : runscript.sh now traps interrupt signals and rolls back its status to what @@ -11,6 +38,8 @@ start-stop-daemon now waits for upto 1 second if it returns 0 and we don't have a valid process. + A more user friendly message is reported when an interface does not exist. + 10 Jan 2006; Roy Marples : Removed runlevel dependancies from runscript.sh as they're now in rc. diff --git a/ChangeLog.vserver b/ChangeLog.vserver index 24e03b1..0311046 100644 --- a/ChangeLog.vserver +++ b/ChangeLog.vserver @@ -1,6 +1,27 @@ # ChangeLog for Gentoo System Intialization ("rc") scripts # Copyright 1999-2005 Gentoo Foundation; Distributed under the GPLv2 + 15 Jan 2005; Christian Heim : + Importing latest baselayout/trunk changes. This merge is based upon + revision 1822. + + ChangeLog | 29 ++ + ChangeLog.vserver | 21 + + bin/rc-status | 3 + net-scripts/init.d/net.lo | 9 + net-scripts/net.modules.d/bonding | 4 + net-scripts/net.modules.d/bridge | 4 + net-scripts/net.modules.d/helpers.d/functions | 6 + net-scripts/net.modules.d/ifconfig | 7 + net-scripts/net.modules.d/iproute2 | 5 + sbin/functions.sh | 2 + sbin/init.linux.sh | 2 + sbin/rc | 47 +-- + sbin/rc-daemon.sh | 26 - + sbin/rc-services.sh | 27 - + sbin/runscript.sh | 258 ++++++++++-------- + 15 files changed, 269 insertions(+), 181 deletions(-) + 11 Jan 2005; Christian Heim : Importing latest baselayout/trunk changes. This merge is based upon revision 1802. diff --git a/bin/rc-status b/bin/rc-status index 05254fc..1cc8572 100755 --- a/bin/rc-status +++ b/bin/rc-status @@ -30,8 +30,9 @@ source /sbin/functions.sh runleveldir=/etc/runlevels # grab settings from conf.d/rc -source /etc/conf.d/rc source "${svclib}/sh/rc-daemon.sh" +conf="$(add_suffix /etc/conf.d/rc)" +[[ -e ${conf} ]] && source "${conf}" ################################################################################ # Parse command line options # diff --git a/net-scripts/init.d/net.lo b/net-scripts/init.d/net.lo index 2a8ac84..04f030d 100755 --- a/net-scripts/init.d/net.lo +++ b/net-scripts/init.d/net.lo @@ -787,6 +787,9 @@ run_start() { # Call user-defined postup function if it exists if is_function postup ; then + # We need to mark the service as started incase a + # postdown function wants to restart services that depend on us + mark_service_started "net.${iface}" einfo "Running postup function" eindent ( postup "${iface}" ) @@ -823,8 +826,14 @@ run_stop() { iface_stop "${iface}" || return 1 # always succeeds, btw + # Mark us as inactive if called from the background + [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}" + # Call user-defined postdown function if it exists if is_function postdown ; then + # We need to mark the service as stopped incase a + # postdown function wants to restart services that depend on us + [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}" einfo "Running postdown function" eindent ( postdown "${iface}" ) diff --git a/net-scripts/net.modules.d/bonding b/net-scripts/net.modules.d/bonding index 3e629c8..62431aa 100644 --- a/net-scripts/net.modules.d/bonding +++ b/net-scripts/net.modules.d/bonding @@ -58,9 +58,7 @@ bonding_pre_start() { # Check that our slaves exist for s in "${slaves[@]}" ; do - interface_exists "${s}" && continue - ewarn "interface ${s} does not exist" - return 1 + interface_exists "${s}" true || return 1 done # Must force the slaves to a particular state before adding them diff --git a/net-scripts/net.modules.d/bridge b/net-scripts/net.modules.d/bridge index 6c77067..23a0be1 100644 --- a/net-scripts/net.modules.d/bridge +++ b/net-scripts/net.modules.d/bridge @@ -143,9 +143,7 @@ bridge_pre_start() { eindent for i in ${ports}; do - interface_exists "${i}" && continue - eerror "interface ${i} does not exist" - return 1 + interface_exists "${i}" true || return 1 done for i in ${ports}; do diff --git a/net-scripts/net.modules.d/helpers.d/functions b/net-scripts/net.modules.d/helpers.d/functions index eebb55d..dd325a3 100644 --- a/net-scripts/net.modules.d/helpers.d/functions +++ b/net-scripts/net.modules.d/helpers.d/functions @@ -38,7 +38,7 @@ save_state() { local d="${statedir}/${iface}" [[ ! -d ${d} ]] && mkdir -m 0755 -p "${d}" - cp -a /etc/resolv.conf /etc/ntp.conf /etc/yp.conf "${d}" 2>/dev/null + cp -p /etc/resolv.conf /etc/ntp.conf /etc/yp.conf "${d}" 2>/dev/null } # void remove_state(char *interface) @@ -70,7 +70,7 @@ apply_state() { local files=$( ls "${d}" ) if [[ -n ${files} ]] ; then if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then - cp -aR "${d}"/* "${netdir}" + cp -pPR "${d}"/* "${netdir}" local file for file in ${files} ; do # Skip .sv files @@ -82,7 +82,7 @@ apply_state() { fi done else - cp -ar "${d}"/* /etc + cp -pPR "${d}"/* /etc fi fi fi diff --git a/net-scripts/net.modules.d/ifconfig b/net-scripts/net.modules.d/ifconfig index b769215..05ef95a 100644 --- a/net-scripts/net.modules.d/ifconfig +++ b/net-scripts/net.modules.d/ifconfig @@ -42,7 +42,12 @@ ifconfig_check_installed() { ifconfig_exists() { local e=$( ifconfig -a | grep -o "^$1" ) report="${2:-false}" [[ -n ${e} ]] && return 0 - ${report} && eerror "$1 does not exist" + + if ${report} ; then + eerror "network interface $1 does not exist" + eerror "Please verify hardware or kernel module (driver)" + fi + return 1 } diff --git a/net-scripts/net.modules.d/iproute2 b/net-scripts/net.modules.d/iproute2 index cff83e2..8b6a9a7 100644 --- a/net-scripts/net.modules.d/iproute2 +++ b/net-scripts/net.modules.d/iproute2 @@ -46,7 +46,10 @@ iproute2_exists() { local e=$( ip addr show label "$1" ) report="${2:-false}" [[ -n ${e} ]] && return 0 - ${report} && eerror "$1 does not exist" + if ${report} ; then + eerror "network interface $1 does not exist" + eerror "Please verify hardware or kernel module (driver)" + fi return 1 } diff --git a/sbin/functions.sh b/sbin/functions.sh index ea09893..e371382 100755 --- a/sbin/functions.sh +++ b/sbin/functions.sh @@ -519,7 +519,7 @@ get_base_ver() { # Network filesystems list for common use in rc-scripts. # This variable is used in is_net_fs and other places such as # localmount. -NET_FS_LIST="afs cifs coda davfs gfs ncpfs nfs nfs4 ocfs2 shfs smbfs" +NET_FS_LIST="afs cifs coda davfs fuse gfs ncpfs nfs nfs4 ocfs2 shfs smbfs" # bool is_net_fs(path) # diff --git a/sbin/init.linux.sh b/sbin/init.linux.sh index 6c37cd6..6ed91aa 100755 --- a/sbin/init.linux.sh +++ b/sbin/init.linux.sh @@ -17,8 +17,6 @@ echo echo -e "${GOOD}Gentoo Linux${GENTOO_VERS}; ${BRACKET}http://www.gentoo.org/${NORMAL}" echo -e " Copyright 1999-2006 Gentoo Foundation; Distributed under the GPLv2" echo -echo -e "Press ${GOOD}I${NORMAL} to enter interactive boot mode" -echo check_statedir /proc check_statedir /dev diff --git a/sbin/rc b/sbin/rc index 000fabe..6527d16 100755 --- a/sbin/rc +++ b/sbin/rc @@ -14,7 +14,7 @@ get_critical_services() { local x= CRITICAL_SERVICES= - if [[ -f /etc/runlevels/${BOOTLEVEL}/.critical ]] ; then + if [[ -f "/etc/runlevels/${BOOTLEVEL}/.critical" ]] ; then for x in $(< "/etc/runlevels/${BOOTLEVEL}/.critical") ; do CRITICAL_SERVICES="${CRITICAL_SERVICES} ${x##*/}" done @@ -53,34 +53,34 @@ then # We reset argv1 to the bootlevel given on the kernel command line # if there is one - argv1=${BOOTLEVEL} + argv1="${BOOTLEVEL}" fi source "${svclib}/sh/rc-services.sh" -if [[ -f ${svcdir}/softlevel ]] ; then +if [[ -f "${svcdir}/softlevel" ]] ; then # Set OLDSOFTLEVEL if we had a valid SOFTLEVEL - export OLDSOFTLEVEL=$(< ${svcdir}/softlevel) + export OLDSOFTLEVEL="$(< "${svcdir}/softlevel")" else export OLDSOFTLEVEL= fi if [[ -z ${argv1} ]] ; then - if [[ -f ${svcdir}/softlevel ]] ; then - export SOFTLEVEL=$(< ${svcdir}/softlevel) + if [[ -f "${svcdir}/softlevel" ]] ; then + export SOFTLEVEL="$(< "${svcdir}/softlevel")" else - export SOFTLEVEL=${BOOTLEVEL} + export SOFTLEVEL="${BOOTLEVEL}" fi else - export SOFTLEVEL=${argv1} + export SOFTLEVEL="${argv1}" fi -if [[ ! -f ${svcdir}/softlevel ]] ; then +if [[ ! -f "${svcdir}/softlevel" ]] ; then echo "${SOFTLEVEL}" > "${svcdir}/softlevel" fi # For keeping a list of services that fails during boot/halt -if [[ ! -d ${svcdir}/failed ]] ; then +if [[ ! -d "${svcdir}/failed" ]] ; then mkdir -p -m 0755 "${svcdir}/failed" else rm -rf "${svcdir}"/failed/* @@ -89,18 +89,18 @@ fi if [[ ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] ; then myscripts= -elif [[ ! -d /etc/runlevels/${SOFTLEVEL} ]] ; then +elif [[ ! -d "/etc/runlevels/${SOFTLEVEL}" ]] ; then eerror "ERROR: runlevel ${SOFTLEVEL} does not exist; exiting ..." exit 1 else myscripts= if [[ ${SOFTLEVEL} != "${BOOTLEVEL}" ]] ; then # Normal runlevels *include* boot scripts - mylevels=$(dolisting "/etc/runlevels/${SOFTLEVEL}/") - mylevels="${mylevels} $(dolisting /etc/runlevels/${BOOTLEVEL}/)" + mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")" + mylevels="${mylevels} $(dolisting "/etc/runlevels/${BOOTLEVEL}/")" else # Non-normal runlevels don't include boot scripts as default - mylevels=$(dolisting "/etc/runlevels/${SOFTLEVEL}/") + mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")" fi for x in ${mylevels} ; do @@ -116,7 +116,7 @@ fi mkdir -p -m 0755 "${svcdir}/softscripts.new" for x in ${myscripts} ; do - if [[ ! -e /etc/init.d/${x} ]] ; then + if [[ ! -e "/etc/init.d/${x}" ]] ; then ewarn "WARNING: /etc/init.d/${x} missing; skipping ..." continue fi @@ -139,12 +139,12 @@ get_stop_services() { dep_stop() { local x dep needsme depservice - local myservice=${1##*/} + local myservice="${1##*/}" service_stopped "${myservice}" && return 0 # Candidate for zapping ? - [[ ! -L ${svcdir}/softscripts.new/${myservice} ]] || \ + [[ ! -L "${svcdir}/softscripts.new/${myservice}" ]] || \ return 0 # If this is a 'net' service, we do not want to stop it if it was @@ -171,11 +171,8 @@ dep_stop() { needsme=0 for dep in $(needsme "${myservice}") ; do - #if service_started "${dep}" && \ - if [[ -L ${svcdir}/softscripts.new/${dep} ]] ; then - # This dep is valid + if [[ -L "${svcdir}/softscripts.new/${dep}" ]] ; then needsme=1 - break fi done @@ -192,13 +189,13 @@ if [[ ${SOFTLEVEL} != "reboot" && \ done # Wait for any services that may still be stopping ... - [ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait + [[ ${RC_PARALLEL_STARTUP} = "yes" ]] && wait else get_critical_services is_critical_service() { local x - local myservice=${1##*/} + local myservice="${1##*/}" for x in ${CRITICAL_SERVICES} ${LOGGER_SERVICE} ; do [[ ${myservice} == "${x}" ]] && return 0 @@ -261,10 +258,10 @@ get_start_services() { local x list get_critical_services - list=${CRITICAL_SERVICES} + list="${CRITICAL_SERVICES}" [[ -n ${LOGGER_SERVICE} && \ - -L ${svcdir}/softscripts/${LOGGER_SERVICE} ]] && \ + -L "${svcdir}/softscripts/${LOGGER_SERVICE}" ]] && \ list="${list} ${LOGGER_SERVICE}" for x in $(dolisting "${svcdir}/softscripts/") ; do diff --git a/sbin/rc-daemon.sh b/sbin/rc-daemon.sh index c600803..c8cccb5 100755 --- a/sbin/rc-daemon.sh +++ b/sbin/rc-daemon.sh @@ -27,9 +27,6 @@ RC_FAIL_ON_ZOMBIE="no" RC_KILL_CHILDREN="no" RC_WAIT_ON_START="0.1" -# Override default settings with user settings ... -[[ -f /etc/conf.d/rc ]] && source /etc/conf.d/rc - # void rc_shift_args(void) # # Proccess vars - makes things easier by using the shift command @@ -103,7 +100,7 @@ rc_setup_daemon_vars() { # We may want to launch the daemon with a custom command # This is mainly useful for debugging with apps like valgrind, strace - local bash_service=$( bash_variable "${myservice}" ) + local bash_service="$( bash_variable "${myservice}" )" eval x=\"\$\{RC_DAEMON_${bash_service}\}\" if [[ -n ${x} ]]; then local -a d=( ${x} ) @@ -120,7 +117,7 @@ rc_setup_daemon_vars() { args="${args} ${d[i]}" unset d[i] done - d=$( "${d[@]}" ) + d=( "${d[@]}" ) eval args=\"${args} --exec '${d[0]}' -- ${d[@]:1} '${cmd}' ${eargs[@]}\" ! ${stopping} && cmd="${d[0]}" @@ -148,7 +145,7 @@ rc_try_kill_pid() { pkill "-${signal}" -s "${pid}" pgrep -s "${pid}" >/dev/null || return 0 else - local pids=$(ps -eo pid,sid | sed -n 's/'${pid}'$//p') + local pids="$(ps -eo pid,sid | sed -n 's/'${pid}'$//p')" [[ -z ${pids} ]] && return 0 kill -s "${signal}" ${pids} 2>/dev/null e=false @@ -219,7 +216,7 @@ is_daemon_running() { pidfile="$1" fi - pids=$( pidof ${cmd} ) + pids="$( pidof ${cmd} )" [[ -z ${pids} ]] && return 1 [[ -s ${pidfile} ]] || return 0 @@ -259,11 +256,8 @@ rc_start_daemon() { [[ ${retval} == "0" ]] && return 0 # Stop if we can to clean things up - if [[ $( type -t stop ) == "function" ]]; then - stop >/dev/null # We don't want to echo ebegin/eend - elif [[ -n ${pidfile} ]]; then - rc_stop_daemon - fi + [[ -n ${pidfile} ]] && rc_stop_daemon + return "${retval}" } @@ -279,7 +273,7 @@ rc_stop_daemon() { if ! is_daemon_running ${cmd} "${pidfile}" ; then [[ ${RC_FAIL_ON_ZOMBIE} == "yes" ]] && return 1 fi - pids=$( pidof ${cmd} ) + pids="$( pidof ${cmd} )" fi if [[ -s ${pidfile} ]]; then @@ -299,11 +293,11 @@ rc_stop_daemon() { # two methods if [[ ${RC_KILL_CHILDREN} == "yes" ]]; then if [[ -x /usr/bin/pgrep ]]; then - pids="${pids} $(pgrep -P ${pids// /,})" + pids="${pids} $(pgrep -P "${pids// /,}")" else local npids for pid in ${pids} ; do - npids="${npids} $(ps -eo pid,ppid | sed -n 's/'${pid}'$//p')" + npids="${npids} $(ps -eo pid,ppid | sed -n 's/'"${pid}"'$//p')" done pids="${pids} ${npids}" fi @@ -362,7 +356,7 @@ update_service_status() { # Return the result of start_daemon or stop_daemon depending on # how we are called start-stop-daemon() { - local args=$( requote "$@" ) result i + local args="$( requote "$@" )" result i local cmd pidfile pid stopping signal nothing=false local daemonfile="${svcdir}/daemons/${myservice}" local -a RC_DAEMONS=() RC_PIDFILES=() diff --git a/sbin/rc-services.sh b/sbin/rc-services.sh index 9cfc606..40dd877 100755 --- a/sbin/rc-services.sh +++ b/sbin/rc-services.sh @@ -68,7 +68,7 @@ get_service_index() { fi for (( x=1; x<=${RC_DEPEND_TREE[0]}; x++ )); do - index=$(( ${x} * ${rc_index_scale} )) + index="$(( ${x} * ${rc_index_scale} ))" if [[ ${myservice} == "${RC_DEPEND_TREE[${index}]}" ]] ; then echo "${index}" return 0 @@ -91,7 +91,7 @@ get_dep_info() { # We already have the right stuff ... [[ ${myservice} == "${rc_name}" && -n ${rc_mtime} ]] && return 0 - rc_index="`get_service_index "${myservice}" "${rc_index}"`" + rc_index="$(get_service_index "${myservice}" "${rc_index}")" rc_mtime="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_mtime}))]}" # Verify that we have the correct index (rc_index) ... @@ -133,7 +133,7 @@ check_dependency() { fi if ! get_dep_info "${myservice}" >/dev/null ; then - eerror "Could not get dependency info for \"${myservice}\"!" > /dev/stderr + eerror "Could not get dependency info for ${myservice}!" > /dev/stderr eerror "Please run:" > /dev/stderr eerror " # /sbin/depscan.sh" > /dev/stderr eerror "to try and fix this." > /dev/stderr @@ -214,10 +214,10 @@ is_fake_service() { [[ -z $1 || -z $2 ]] && return 1 [[ $2 != "${BOOTLEVEL}" && -e /etc/runlevels/"${BOOTLEVEL}"/.fake ]] && \ - fake_services=$( < /etc/runlevels/"${BOOTLEVEL}"/.fake ) + fake_services="$( < /etc/runlevels/"${BOOTLEVEL}"/.fake )" [[ -e /etc/runlevels/"$2"/.fake ]] && \ - fake_services="${fake_services} $( < /etc/runlevels/$2/.fake )" + fake_services="${fake_services} $( < /etc/runlevels/"$2"/.fake )" for x in ${fake_services} ; do [[ $1 == "${x##*/}" ]] && return 0 @@ -271,7 +271,7 @@ service_message() { local r="${RC_QUIET_STDOUT}" RC_QUIET_STDOUT="no" ${cmd} "$@" - RC_QUIET_STDOUT=${r} + RC_QUIET_STDOUT="${r}" } # bool begin_service( service ) @@ -336,8 +336,9 @@ wait_service() { # This will block until the service fifo is touched # Otheriwse we don't block - $( < "${fifo}" &>/dev/null ) - local exitstatus=$( < "${svcdir}/exitcodes/${service}" ) + # We need to use cat instead of the bash inbuilt < so we don't see errors + local tmp="$( cat "${fifo}" 2>/dev/null )" + local exitstatus="$( < "${svcdir}/exitcodes/${service}" )" return "${exitstatus}" } @@ -637,7 +638,7 @@ is_net_up() { # Only worry about net.* services if this is the last one running, # or if RC_NET_STRICT_CHECKING is set ... - if [[ "${netcount}" -lt 1 || ${RC_NET_STRICT_CHECKING} == "yes" ]] ; then + if [[ ${netcount} -lt 1 || ${RC_NET_STRICT_CHECKING} == "yes" ]] ; then return 1 fi @@ -711,7 +712,7 @@ trace_dependencies() { fi fi - net_services=$( cd "${svcdir}"/started; ls net.* 2>/dev/null ) + net_services="$( cd "${svcdir}"/started; ls net.* 2>/dev/null )" # If no net services are running or we only have net.lo up, then # assume we are in boot runlevel or starting a new runlevel if [[ -z ${net_services} || ${net_services} == "net.lo" ]]; then @@ -725,9 +726,9 @@ trace_dependencies() { } local mylevel="${BOOTLEVEL}" - local x=$( get_net_services "${mylevel}" ) + local x="$( get_net_services "${mylevel}" )" - [[ -f "${svcdir}/softlevel" ]] && mylevel=$( < "${svcdir}/softlevel" ) + [[ -f "${svcdir}/softlevel" ]] && mylevel="$( < "${svcdir}/softlevel" )" [[ ${BOOTLEVEL} != "${mylevel}" ]] && \ local x="${x} $( get_net_services "${mylevel}" )" [[ -n ${x} ]] && net_services="${x}" @@ -805,7 +806,7 @@ query_before() { [[ -z $1 || -z $2 ]] && return 1 - list=$( trace_dependencies "$1" ) + list="$( trace_dependencies "$1" )" net_service "$2" && netservice="yes" 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" ;; -- cgit v1.2.3-65-gdbad