diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | ChangeLog.vserver | 14 | ||||
-rw-r--r-- | etc/conf.d/rc | 14 | ||||
-rwxr-xr-x | net-scripts/init.d/net.lo | 2 | ||||
-rw-r--r-- | net-scripts/net.modules.d/bonding | 16 | ||||
-rwxr-xr-x | sbin/rc-daemon.sh | 9 | ||||
-rwxr-xr-x | sbin/rc-services.sh | 6 | ||||
-rwxr-xr-x | sbin/runscript.sh | 133 |
8 files changed, 151 insertions, 53 deletions
@@ -1,6 +1,16 @@ # ChangeLog for Gentoo System Intialization ("rc") scripts # Copyright 1999-2006 Gentoo Foundation; Distributed under the GPLv2 + 11 Jan 2006; Roy Marples <uberlord@gentoo.org>: + + runscript.sh now traps interrupt signals and rolls back its status to what + it was when before it started. + + bonding module now supports space seperated and array variables, #118590. + + start-stop-daemon now waits for upto 1 second if it returns 0 and we + don't have a valid process. + 10 Jan 2006; Roy Marples <uberlord@gentoo.org>: Removed runlevel dependancies from runscript.sh as they're now in rc. diff --git a/ChangeLog.vserver b/ChangeLog.vserver index 24ab7e6..24e03b1 100644 --- a/ChangeLog.vserver +++ b/ChangeLog.vserver @@ -1,6 +1,20 @@ # ChangeLog for Gentoo System Intialization ("rc") scripts # Copyright 1999-2005 Gentoo Foundation; Distributed under the GPLv2 + 11 Jan 2005; Christian Heim <phreak@gentoo.org>: + Importing latest baselayout/trunk changes. This merge is based upon + revision 1802. + + ChangeLog | 10 + + ChangeLog.vserver | 14 + + etc/conf.d/rc | 14 - + net-scripts/init.d/net.lo | 2 + net-scripts/net.modules.d/bonding | 16 +- + sbin/rc-daemon.sh | 9 + + sbin/rc-services.sh | 6 + sbin/runscript.sh | 133 ++++++++++++------ + 8 files changed, 151 insertions(+), 53 deletions(-) + 10 Jan 2005; Christian Heim <phreak@gentoo.org>: Importing latest baselayout/trunk changes. This merge is based upon revision 1799. diff --git a/etc/conf.d/rc b/etc/conf.d/rc index 7f48996..12cba6d 100644 --- a/etc/conf.d/rc +++ b/etc/conf.d/rc @@ -55,31 +55,31 @@ RC_INITSTYLE_HACK="no" # # Controlling start-stop-daemon behavior -# Set to "yes" if stop_daemon() should always retry killing the +# Set to "yes" if start-stop-daemon should always retry killing the # service with sig KILL if it fails the first time. RC_RETRY_KILL="yes" -# Set the amount of seconds stop_daemon() should wait between +# Set the amount of seconds start-stop-daemon should wait between # retries. RC_RETRY_TIMEOUT=1 -# Set the amount of times stop_daemon() should try to kill +# Set the amount of times start-stop-daemon should try to kill # a service before giving up. RC_RETRY_COUNT=5 -# Set to "yes" if stop_daemon() should fail if the service +# Set to "yes" if start-stop-daemon should fail if the service # is marked as started, but not actually running on stop. RC_FAIL_ON_ZOMBIE="no" -# Set to "yes" if stop_daemon() should attempt to kill +# Set to "yes" if start-stop-daemon should attempt to kill # any children left in the system. # Be careful with this as it really does what it was on the tin. # fex, if you're in an ssh process and you restart a service on which ssh @@ -88,13 +88,13 @@ RC_FAIL_ON_ZOMBIE="no" RC_KILL_CHILDREN="no" -# Set the amount of seconds start_daemon() waits after starting +# Set the amount of seconds start-stop-daemon waits after starting # the daemon to check it is still running. If it's not then we # try and stop any children if possible. RC_WAIT_ON_START="0.1" -# Some daemons are started and stopped via start_stop_daemon. +# Some daemons are started and stopped via start-stop-daemon. # We can change launch them through other daemons here, for example valgrind. # This is only useful for serious debugging of the daemon # Note non alphanumeric chars in the script name need to be changed to _ diff --git a/net-scripts/init.d/net.lo b/net-scripts/init.d/net.lo index 47752cb..2a8ac84 100755 --- a/net-scripts/init.d/net.lo +++ b/net-scripts/init.d/net.lo @@ -12,7 +12,7 @@ # runlevel as the net.* script that needs it. depend() { need localmount - use coldplug pcmcia usb isdn wlan + use pcmcia usb isdn wlan # Load any custom depend functions for the given interface # For example, br0 may need eth0 and eth1 diff --git a/net-scripts/net.modules.d/bonding b/net-scripts/net.modules.d/bonding index a717ccb..3e629c8 100644 --- a/net-scripts/net.modules.d/bonding +++ b/net-scripts/net.modules.d/bonding @@ -40,6 +40,10 @@ bonding_pre_start() { slaves="slaves_${ifvar}[@]" [[ -z ${!slaves} ]] && return 0 + slaves=( "${!slaves}" ) + + # Support space seperated slaves + [[ ${#slaves[@]} == 1 ]] && slaves=( ${slaves} ) interface_exists "${iface}" true || return 1 @@ -50,17 +54,17 @@ bonding_pre_start() { ebegin "Adding slaves to ${iface}" eindent - einfo "${!slaves}" + einfo "${slaves[@]}" # Check that our slaves exist - for s in ${!slaves} ; do + for s in "${slaves[@]}" ; do interface_exists "${s}" && continue ewarn "interface ${s} does not exist" return 1 done # Must force the slaves to a particular state before adding them - for s in ${!slaves} ; do + for s in "${slaves[@]}" ; do interface_del_addresses "${s}" interface_up "${s}" done @@ -70,7 +74,7 @@ bonding_pre_start() { # finally add in slaves eoutdent - eval /sbin/ifenslave "${iface}" "${!slaves}" >/dev/null + eval /sbin/ifenslave "${iface}" "${slaves[@]}" >/dev/null eend $? return 0 #important @@ -87,7 +91,9 @@ bonding_stop() { ! bonding_exists "${iface}" && return 0 # don't trust the config, get the active list instead - slaves=$( sed -n -e 's/^Slave Interface: //p' "/proc/net/bonding/${iface}" ) + slaves="$( \ + sed -n -e 's/^Slave Interface: //p' /proc/net/bonding/${iface} | xargs \ + )" [[ -z ${slaves} ]] && return 0 # remove all slaves diff --git a/sbin/rc-daemon.sh b/sbin/rc-daemon.sh index 51fc834..c600803 100755 --- a/sbin/rc-daemon.sh +++ b/sbin/rc-daemon.sh @@ -240,6 +240,15 @@ rc_start_daemon() { [[ ${retval} != "0" ]] && return "${retval}" [[ ${RC_WAIT_ON_START} == "0" ]] && return "${retval}" + # Give the daemon upto 1 second to fork after s-s-d returns + # Some daemons like acpid and vsftpd need this when system is under load + # Seems to be only daemons that do not create pid files though ... + local i=0 + for ((i=0; i<10; i++)); do + is_daemon_running ${cmd} "${pidfile}" && break + LC_ALL=C /bin/sleep "0.1" + done + # We pause for RC_WAIT_ON_START seconds and then # check if the daemon is still running - this is mainly # to handle daemons who launch and then fail due to invalid diff --git a/sbin/rc-services.sh b/sbin/rc-services.sh index d47482a..9cfc606 100755 --- a/sbin/rc-services.sh +++ b/sbin/rc-services.sh @@ -287,7 +287,7 @@ begin_service() { local service="$1" [[ -z ${service} ]] && return 1 - [[ ${START_CRITICAL} == "yes" ]] && return 0 + [[ ${START_CRITICAL} == "yes" || ${STOP_CRITICAL} == "yes" ]] && return 0 mkfifo "${svcdir}/exclusive/${service}" 2> /dev/null } @@ -302,7 +302,7 @@ end_service() { [[ -z ${service} ]] && return # if we are doing critical services, there is no fifo - [[ ${START_CRITICAL} == "yes" ]] && return + [[ ${START_CRITICAL} == "yes" || ${STOP_CRITICAL} == "yes" ]] && return if [[ -n ${exitstatus} ]] ; then echo "${exitstatus}" > "${svcdir}/exitcodes/${service}" @@ -336,7 +336,7 @@ wait_service() { # This will block until the service fifo is touched # Otheriwse we don't block - local tmp=$( < "${fifo}" &>/dev/null ) + $( < "${fifo}" &>/dev/null ) local exitstatus=$( < "${svcdir}/exitcodes/${service}" ) return "${exitstatus}" diff --git a/sbin/runscript.sh b/sbin/runscript.sh index 0a5deb8..005d7bb 100755 --- a/sbin/runscript.sh +++ b/sbin/runscript.sh @@ -4,10 +4,6 @@ # Common functions [[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh -# Functions to handle dependencies and services -[[ ${RC_GOT_SERVICES} != "yes" ]] && source "${svclib}/sh/rc-services.sh" -# Functions to control daemons -[[ ${RC_GOT_DAEMON} != "yes" ]] && source "${svclib}/sh/rc-daemon.sh" # User must be root to run most script stuff (except status) if [[ ${EUID} != 0 ]] && ! [[ $2 == "status" && $# -eq 2 ]] ; then @@ -20,7 +16,7 @@ svcpause="no" svcrestart="no" myscript="$1" -if [[ -L $1 && ! -L /etc/init.d/${1##*/} ]] ; then +if [[ -L $1 && ! -L "/etc/init.d/${1##*/}" ]] ; then myservice="$(readlink $1)" else myservice="$1" @@ -30,6 +26,19 @@ myservice="${myservice##*/}" export SVCNAME="${myservice}" mylevel="$(<${svcdir}/softlevel)" +svc_trap() { + trap 'eerror "ERROR: \"${myservice}\" caught an interrupt"; exit 1' \ + INT QUIT TSTP +} + +# Setup a default trap +svc_trap + +# Functions to handle dependencies and services +[[ ${RC_GOT_SERVICES} != "yes" ]] && source "${svclib}/sh/rc-services.sh" +# Functions to control daemons +[[ ${RC_GOT_DAEMON} != "yes" ]] && source "${svclib}/sh/rc-daemon.sh" + # Set $IFACE to the name of the network interface if it is a 'net.*' script if [[ ${myservice%%.*} == "net" && ${myservice##*.} != "${myservice}" ]] ; then IFACE="${myservice##*.}" @@ -51,7 +60,7 @@ search_lang="${LC_ALL:-${LC_MESSAGES:-${LANG}}}" # (3) Source /etc/rc.conf to pick up potentially overriding # configuration, if the system administrator chose to put it # there (if it exists). -if [[ ${NETSERVICE} == "yes" ]]; then +if [[ ${NETSERVICE} == "yes" ]] ; then conf="$(add_suffix /etc/conf.d/net)" [[ -e ${conf} ]] && source "${conf}" fi @@ -60,6 +69,24 @@ conf="$(add_suffix /etc/conf.d/${myservice})" 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=$? +svc_quit() { + eerror "ERROR: \"${myservice}\" caught an interrupt" + if [[ ${svcbegun} == 0 ]] ; then + end_service "${myservice}" + svcbegun=1 + fi + if [[ ${svcstarted} == 0 ]] ; then + mark_service_started "${myservice}" + else + mark_service_stopped "${myservice}" + fi + exit 1 +} + usage() { local IFS="|" myline="Usage: ${myservice} { $* " @@ -87,7 +114,7 @@ status() { # Dummy function return 0 } - + svc_stop() { local x= mydep= mydeps= retval=0 was_inactive=false local -a servicelist=() @@ -109,8 +136,12 @@ svc_stop() { fi # Lock service starting too ... mark_service_starting "${myservice}" + + # Ensure that we clean up if we abort for any reason + trap "svc_quit" INT QUIT TSTP + begin_service "${myservice}" - local begun=$? + svcbegun=$? service_message "Stopping service ${myservice}" @@ -152,7 +183,6 @@ svc_stop() { done for x in "${service_list[@]}" ; do - service_stopped "${x}" && continue wait_service "${x}" if ! service_stopped "${x}" ; then retval=1 @@ -176,7 +206,7 @@ svc_stop() { # If a service has been marked inactive, exit now as something # may attempt to start it again later if service_inactive "${myservice}" ; then - [[ ${begun} == 0 ]] && end_service "${myservice}" 0 + [[ ${svcbegun} == 0 ]] && end_service "${myservice}" 0 return 0 fi fi @@ -199,6 +229,7 @@ svc_stop() { else # 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}" else @@ -207,7 +238,14 @@ svc_stop() { service_message "Stopped service ${myservice}" fi - [[ ${begun} == 0 ]] && end_service "${myservice}" "${retval}" + if [[ ${svcbegun} == 0 ]] ; then + end_service "${myservice}" "${retval}" + svcbegun=1 + fi + + # Reset the trap + svc_trap + return "${retval}" } @@ -220,37 +258,42 @@ 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 + + # Ensure that we clean up if we abort for any reason + trap "svc_quit" INT QUIT TSTP + begin_service "${myservice}" - local begun=$? + svcbegun=$? service_message "Starting service ${myservice}" local startupservices="$(trace_dependencies $(ineed "${myservice}") \ $(valid_iuse ${myservice}))" + local netservices="$(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \ + $(dolisting "/etc/runlevels/${mylevel}/net.*")" + local mynetservice= - # Start dependencies, if any + # 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 - local netservices="$(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \ - $(dolisting "/etc/runlevels/${mylevel}/net.*")" - for y in ${netservices} ; do mynetservice="${y##*/}" if service_stopped "${mynetservice}" ; then @@ -264,9 +307,15 @@ svc_start() { fi done - # wait for dependencies to finish + # 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})" + fi + + # Wait for dependencies to finish. for x in ${startupservices} ; do - if [ "${x}" = "net" -a "${NETSERVICE}" != "yes" ] ; then + if [[ ${x} == "net" && ${NETSERVICE} != "yes" ]] ; then for y in ${netservices} ; do mynetservice="${y##*/}" @@ -284,7 +333,7 @@ svc_start() { fi fi done - elif [ "${x}" != "net" ] ; then + elif [[ ${x} != "net" ]] ; then wait_service "${x}" if ! service_started "${x}" ; then # A 'need' dependacy is critical for startup @@ -322,7 +371,7 @@ svc_start() { # If a service has been marked inactive, exit now as something # may attempt to start it again later if service_inactive "${myservice}" ; then - [[ ${begun} == 0 ]] && end_service "${myservice}" 1 + [[ ${svcbegun} == 0 ]] && end_service "${myservice}" 1 return 1 fi fi @@ -333,7 +382,7 @@ svc_start() { # 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 [[ ${SOFTLEVEL} != "${BOOTLEVEL}" ]] ; then if ${was_inactive} ; then mark_service_inactive "${myservice}" else @@ -343,12 +392,20 @@ svc_start() { service_message "eerror" "FAILED to start service ${myservice}!" else + svcstarted=0 mark_service_started "${myservice}" service_message "Service ${myservice} started OK" fi - [[ ${begun} == 0 ]] && end_service "${myservice}" "${retval}" + if [[ ${svcbegun} == 0 ]] ; then + end_service "${myservice}" "${retval}" + svcbegun=1 + fi + + # Reset the trap + svc_trap + return "${retval}" } @@ -394,7 +451,7 @@ svc_status() { [[ ${efunc} != "eerror" ]] } -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 ..." exit 1 @@ -411,7 +468,7 @@ if [[ -z ${opts} ]] ; then fi svc_homegrown() { - local x arg=$1 + local x arg="$1" shift # Walk through the list of available options, looking for the @@ -459,13 +516,13 @@ done for arg in $* ; do case "${arg}" in stop) - if [[ -e "${svcdir}/restart/${myservice}" ]]; then + if [[ -e "${svcdir}/restart/${myservice}" ]] ; then rm -f "${svcdir}/restart/${myservice}" fi # Stoped from the background - treat this as a restart so that # stopped services come back up again when started. - if [[ ${IN_BACKGROUND} == "true" ]]; then + if [[ ${IN_BACKGROUND} == "true" ]] ; then rm -rf "${svcdir}/snapshot/$$" mkdir -p "${svcdir}/snapshot/$$" cp -a "${svcdir}"/started/* "${svcdir}/snapshot/$$/" @@ -473,23 +530,25 @@ for arg in $* ; do svc_stop - if [[ ${IN_BACKGROUND} == "true" ]]; then + if [[ ${IN_BACKGROUND} == "true" ]] ; then res= for x in $(dolisting "${svcdir}/snapshot/$$/") ; do if service_stopped "${x##*/}" ; then res="${res}${x##*/} " fi done - echo "${res}" > "${svcdir}/restart/${myservice}" + [[ -n ${res} ]] && echo "${res}" > "${svcdir}/restart/${myservice}" fi ;; start) svc_start retval=$? - if [[ -e "${svcdir}/restart/${myservice}" ]]; then + 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} @@ -501,14 +560,14 @@ for arg in $* ; do svc_status ;; zap) - if [[ -e "${svcdir}/restart/${myservice}" ]]; then + if [[ -e "${svcdir}/restart/${myservice}" ]] ; then rm -f "${svcdir}/restart/${myservice}" fi if ! service_stopped "${myservice}" ; then einfo "Manually resetting ${myservice} to stopped state." mark_service_stopped "${myservice}" - end_service "${myservice}" fi + end_service "${myservice}" ;; restart) svcrestart="yes" @@ -530,7 +589,7 @@ for arg in $* ; do echo ewarn "Please use 'svc_stop; svc_start' and not 'stop; start' to" ewarn "restart the service in its custom 'restart()' function." -/var/lib/init.d/exclusive/net.lan ewarn "Run ${myservice} without arguments for more info." + ewarn "Run ${myservice} without arguments for more info." echo svc_restart else @@ -555,7 +614,7 @@ for arg in $* ; do res="${res}${x##*/} " fi done - echo "${res}" > "${svcdir}/restart/${myservice}" + [[ -n ${res} ]] && echo "${res}" > "${svcdir}/restart/${myservice}" fi # Wait for any services that may still be running ... |