Description of Problem, followed by technophilosophical discussion on why
the damn thing just isn't a good idea:
In /etc/rc, the code that execs the various S??* scripts tries to
ascertain whether it is safe to exec a script or whether it should run it
in a subshell. To do this, it looks for calls to the shell functions
"action" and "daemon".
Whether this is even an advisable method, *if* implemented correctly, is
not clear to me.
But ... it is clear that the way it is implemented is less than desirable
and can lead to exceedingly bizarre behavior.
Scripts name halt or reboot are the last guys in the chain. /etc/rc wants
to exec them, after clearing out locale references. If it doesn't do
this, they will hold open files on /usr.
The problem is that the logic checks for the words "action" or "daemon"
in a script *first*, then checks to see if it's halt or reboot.
I have a UPS. I switched to NUT. NUT requires adding code to
/etc/rc.d/init.d/halt to tell the UPS daemon to kill the power.
I put a comment in that file, saying, "tell the UPS daemon to kill the
power". You can see where this is going, can't you?
My comment tripped the "daemon" checker, which executed halt in a
subshell. It had references to locale files on /usr. Halt loops over
filesystems, killing all processes with open files that prevent
unmounting. Halt kills all process with open files on /usr. Halt has an
open file on /usr. Therefore, .... Aiiiieeeeee! Halt commits suicide
before it is ready to commit suicide.
Please, before this is dismissed as minor, think about trying to debug
this mess. Not pretty, is it?
I am willing to argue that the text of a comment in any script, but
especially not a critical system script, should not cause changes in the
script's behavior at all. This isn't just a change in behavior, it is ...
So, first, please reverse the order of the tests. Check for halt or
Second, think about whether this whole idea is really sound. It's
tempting to say, "ok, we'll strip comments." So I add an echo command:
echo "Telling UPS daemon to kill power"
and we're right back where we started. "OK, strip strings, too."
Well, how about:
$(echo "action") "Fsck me" /sbin/fsck --me --really_hard
You'll miss that one. I don't think there's any way to make this do what
There has to be a better way. Unfortunately between mucking with KDE-2.2
CVS, and tracking down a kernel 2.4.5 page_launder() bug, I can't think
of it at the moment.
It's orthangonal to this problem, but why isn't the nut initscript suitable
for your needs? If, even with that, code needs added to the halt script, something
is wrong with the nut package.
No, there's nothing wrong with the nut package. The code (that runs only when
the UPS is on low battery, and we're going down for that reason) needs to be
added at the end of "halt" because IT SHUTS THE POWER OFF!
Do you think that "service nut stop" should kill the power? I hope not ...
Here are the choices:
1. Run it in /etc/rc.d/init.d/nut. So we'll just kill the power with all the
2. Add it to the end of halt. We'll kill the UPS power rather than the "normal"
way of shutting the power off.
3. Do it after halt completes ... umm, wait, we're halted...
Fixed in CVS, will be in 6.00-1 or so. (I added the special case check for
halt/reboot/etc in the 'action|daemon' case.)
The grep is an ugly hack, but the only other way is a magic comment, which
is equally as ugly. (And since the grep has been in the release since 6.0
(or 6.1, I forget), people may be *expecting* this behavior.