Bug#298689: Another solution
The apache command 'apache -k stop' simply sends a signal to the server
process,
The code is a simple as:
kill ($PID, SIGTERM);
I verified that in the apache 2.2.4 sources.
NOTE: it does not wait until the server really stops
So the init.d restart code has a race condition:
apache2 -k stop # sends a kill, but server is still running
sleep XXX # server is still running when under high load
apache2 start # start fails because previous server is still
running
# stop succeeds - all apache servers are now stopped!
Although the sleep 10 avoids the bug in most cases, it is not 100% save,
especially
when running on slow machines (vmware) or when the server is on high load.
On fast
Machines it adds an unnecessary delay.
It is quite easy to reproduce that race condition with the following script:
---------------------------------------------
#!/bin/sh
`pidof apache2` || /etc/init.d/apache2 start
while PID=`pidof apache2`; do
/etc/init.d/apache2 restart
sleep 1
done
----------------------------------------------
If you remove the sleep 10 (or put the server under high load) the restart
fails
Quite often.
The correct fix is to wait until the server really stops:
----------------------------------------------
apache_sync_stop() {
# running ?
PIDTMP=$(pidof_apache)
if $(kill -0 "${PIDTMP:-}" 2> /dev/null); then
PID=$PIDTMP
fi
apache_stop
# wait until really stopped
if [ -n "${PID:-}" ]; then
i=0
while $(kill -0 "${PID:-}" 2> /dev/null); do
if [[ $i == '6' ]]; then
break;
else
if [[ $i == '0' ]]; then
echo -n " waiting "
else
echo -n "."
fi
i=$(($i+1))
sleep $(($i*$i)); # 1,4,9,16,25
fi
done
fi
}
----------------------------------------------
Is that reasonable?
- Dietmar
Reply to: