[Pkg-sysvinit-devel] Bug#594253: init.d/rc concurrent shutdown tries to run the stop action twice

Ron ron at debian.org
Tue Aug 24 21:05:14 UTC 2010


Package: sysv-rc
Version: 2.86.ds1-65
Severity: normal

Hi Petter :)

Thanks for the tips, it turns out this is nothing particularly tricky
at all, it's just a plain vanilla bug in /etc/init.d/rc ;

Around line 184 we have this code:

        case "$runlevel" in
                0|6)
                        ACTION=stop
        ...


Followed by this at line 220:

	if [ makefile = "$CONCURRENCY" ]
	then
		[ "$previous" != N ] && startup stop
        ...


which calls 'startup stop' the first time, and is followed at line 268 by:

	if [ makefile = "$CONCURRENCY" ]
	then
		if [ S = "$runlevel" ]
		then
			startup boot
		else
			startup $ACTION
		fi
	else
        ...

Which then calls 'startup stop' again :(

So it's only on arches where the first stop actually powers down the machine
before this script completes that you might not notice we are losing here,
but clearly this bug is present on all arches and racing the poweroff.

Adding an elif $ACTION != stop to the second case might be enough to fix it,
but I haven't looked any deeper for other bugs that might shake out of this.
(and very much ought to get some sleep right now :)

Attached below is a set -x trace of init.d/rc that demonstrates this really
happening in more excruciating detail if you still need it...

Workaround in the meantime is to set CONCURRENCY=none.  This doesn't affect
the script when running in that mode.

Cheers!
Ron



# halt; logout;

Broadcast message from root at squeezebox (ttyS0) (Tue Jan  4 12:00:57 2000):

The system is going down for system halt NOW!
INIT: Sending processes the TERM signal
+ PATH=/sbin:/usr/sbin:/bin:/usr/bin
+ export PATH
+ date +%s
+ starttime=946949457
+ CONCURRENCY=makefile
+ scriptname=/etc/init.d/rc
+ umask 022
+ trap on_exit EXIT
+ trap : INT QUIT TSTP
+ stty onlcr
+ [ -e /lib/init/splash-functions-base ]
+ . /lib/init/splash-functions-base
+ [ -e /lib/init/splash-functions ]
+ runlevel=0
+ [ 0 !=  ]
+ runlevel=0
+ [ 0 =  ]
+ previous=2
+ [ 2 =  ]
+ export runlevel previous
+ [ -f /etc/default/rcS ]
+ . /etc/default/rcS
+ TMPTIME=0
+ SULOGIN=no
+ DELAYLOGIN=no
+ UTC=yes
+ VERBOSE=no
+ FSCKFIX=no
+ RAMRUN=no
+ RAMLOCK=no
+ export VERBOSE
+ [ -f /lib/lsb/init-functions ]
+ . /lib/lsb/init-functions
+ FANCYTTY=
+ [ -e /etc/lsb-base-logging.sh ]
+ true
+ [ none != makefile ]
+ test -s /etc/init.d/.depend.boot
+ test -s /etc/init.d/.depend.start
+ test -s /etc/init.d/.depend.stop
+ test -e /etc/init.d/.legacy-bootordering
+ startpar -v
+ CONCURRENCY=makefile
+ log_action_msg Using makefile-style concurrent boot in runlevel 0
+ echo Using makefile-style concurrent boot in runlevel 0.
Using makefile-style concurrent boot in runlevel 0.
+ [ -d /etc/rc0.d ]
+ PROGRESS_STATE=0
+ [ -f /dev/.initramfs/progress_state ]
+ progress_size=33
+ ACTION=stop
+ first_step=0
+ progress_size=100
+ step_change=-1
+ num_steps=0
+ is_splash_stop_scripts /etc/rc0.d/K01sendsigs
+ scriptname=/etc/rc0.d/K01sendsigs
+ return 1
+ num_steps=1
+ is_splash_stop_scripts /etc/rc0.d/K01urandom
+ scriptname=/etc/rc0.d/K01urandom
+ return 1
+ num_steps=2
+ is_splash_stop_scripts /etc/rc0.d/K02rsyslog
+ scriptname=/etc/rc0.d/K02rsyslog
+ return 1
+ num_steps=3
+ is_splash_stop_scripts /etc/rc0.d/K03hwclock.sh
+ scriptname=/etc/rc0.d/K03hwclock.sh
+ return 1
+ num_steps=4
+ is_splash_stop_scripts /etc/rc0.d/K03umountnfs.sh
+ scriptname=/etc/rc0.d/K03umountnfs.sh
+ return 1
+ num_steps=5
+ is_splash_stop_scripts /etc/rc0.d/K04networking
+ scriptname=/etc/rc0.d/K04networking
+ return 1
+ num_steps=6
+ is_splash_stop_scripts /etc/rc0.d/K05ifupdown
+ scriptname=/etc/rc0.d/K05ifupdown
+ return 1
+ num_steps=7
+ is_splash_stop_scripts /etc/rc0.d/K06umountfs
+ scriptname=/etc/rc0.d/K06umountfs
+ return 1
+ num_steps=8
+ is_splash_stop_scripts /etc/rc0.d/K07umountroot
+ scriptname=/etc/rc0.d/K07umountroot
+ return 1
+ num_steps=9
+ is_splash_stop_scripts /etc/rc0.d/K08halt
+ scriptname=/etc/rc0.d/K08halt
+ return 1
+ num_steps=10
+ step=0
+ [ makefile = makefile ]
+ [ 2 != N ]
+ startup stop
+ [ start = stop ]
+ [ boot = stop ]
+ startpar -p 4 -t 20 -T 3 -M stop -P 2 -R 0
Asking all remaining processes to terminate...done.
All processes ended within 1 seconds....done.
Stopping enhanced syslogd: rsyslogd.
Saving the system clock.
Deconfiguring network interfaces...done.
Cleaning up ifupdown....
Deactivating swap...done.
Will now halt.
[   79.330196] System halted.
+ eval failed_service=""
skipped_service=""
+ failed_service=
+ skipped_service=
+ [ -n  ]
+ [ -n  ]
+ unset failed_service skipped_service
+ [ makefile = makefile ]
+ [ S = 0 ]
+ startup stop
+ [ start = stop ]
+ [ boot = stop ]
+ startpar -p 4 -t 20 -T 3 -M stop -P 2 -R 0
Asking all remaining processes to terminate...done.
All processes ended within 1 seconds....done.
Stopping enhanced syslogd: rsyslogd already stopped.
Deconfiguring network interfaces...ifdown: failed to open statefile /etc/network/run/ifstate: Read-only file system
failed.
Cleaning up ifupdown....
Saving the system clock.
hwclock: Could not open file with the clock adjustment parameters in it (/etc/adjtime) for writing, errno=30: Read-only file system.
Drift adjustment parameters not updated.
Deactivating swap...done.
Will now halt.
[   83.302343] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[   83.310517] pgd = dded4000
[   83.313259] [00000000] *pgd=1defc031, *pte=00000000, *ppte=00000000
[   83.319579] Internal error: Oops: 17 [#1]

  <snip oops>

[   83.631246] ---[ end trace eb06a24eadc042a7 ]---
Segmentation fault
+ eval failed_service=""
skipped_service=""
+ failed_service=
+ skipped_service=
+ [ -n  ]
+ [ -n  ]
+ unset failed_service skipped_service
+ trap - EXIT
+ date +%s
+ endtime=946949466
+ duration=9
+ log_action_msg Running scripts in rc0.d/ took 9 seconds
+ echo Running scripts in rc0.d/ took 9 seconds.
Running scripts in rc0.d/ took 9 seconds.
+ exit 0





More information about the Pkg-sysvinit-devel mailing list