The -q option to initlog does not appear to do anything. When run with -q,
initlog is supposed suppress the stdio of its children. Instead it reads a
single line from its child, logs it, and exits. This leaves children
connected to half-open pipes, which causes them to die as soon as they
produce any output. The -q option is given to initlog by default by the
daemon() function as defined in /etc/rc.d/init.d/functions, so this problem
can affect many programs.
Here is a simple example. Run:
strace -v -f initlog -q -c 'echo hello'
This will run to completion, and the word "hello" will be echoed into the
pipe attached to echo's stdout. It will also be logged to
/var/log/messages. Now try:
strace -v -f initlog -q -c 'sh -c "/bin/echo hello ; sleep 1 ; /bin/echo
world"'
This does not work. The "echo world" is killed with SIGPIPE, and "hello" is
logged to /var/log/messages. I have verified that this has nothing to do
with the shell by using a small compiled C program that prints two lines of
output to stderr with a sleep (1) in the middle. The sleep is necessary for
reliable replication of the problem, as otherwise both lines may be in the
pipe before initlog reads from it.
The -q option isn't documented in the man page, by the way. It is
documented only by "initlog -?".
*** This is a serious problem for slave nameservers, because the named-xfer
program prints out a message for each zone transfer. Only the first
transfer succeeds, because every subsequent time named-xfer runs, it kills
itself by printing to stderr. named is run under initlog by the daemon()
function as defined in /etc/rc.d/init.d/functions.
I am using kernel-2.2.16-3, glibc-2.1.3-22, and initscripts-5.00-1.

Interesting. Perhaps strace is confusing initlog's sense of when children exit. But
here's the thing: if, as root, I run
initlog -q -c 'sh -c "/bin/echo hello ; sleep 1 ; /bin/echo world"'
I see hello and world get logged, so clearly -q is not causing the messages to be
suppressed. On the other hand, if I do the same thing as a non-root user, the log
messages do not appear. If I omit the -q option as a non-root user, the messages
do appear.
So I think there's something screwy in the logic somewhere. Perhaps -q is only
broken when running as root.
Checking the open file descriptors from the proc filesystem of processes running
under initlog -q (as a non-root user) I see 1 and 2 still connected to a pipe, rather
than /dev/null.

That's fine, but what I'm saying is that that is bad design as it means initlog has to stay
around for the entire duration of the child's lifetime. If it connects the child to /dev/null when
invoked with -q it can exit at will without endangering a critical process.
I encountered this when running a slave nameserver, as it was breaking zone transfers.
I didn't start running initlog under strace until I had already established that something
was very wrong. I hope it is clear this is a real problem.

The design is altogether *intentional*. It's extremely hard to
log the output of the command if you connect its output to /dev/null;
if you don't want to log the command's output, don't run it under
initlog.
*** This bug has been marked as a duplicate of 15973 ***

Tell that to the people who wrote the daemon() function in
/etc/rc.d/init.d/functions. I get the feeling you didn't really read
what I wrote at the beginning of this ticket. So I'll recap.
The daemon() function, as shipped by Red Hat, runs all
daemons under initlog with the -q option.
What is the point of connecting stdio to pipes when you
are running it with -q? Presumably, as you just stated:
> it only supresses the output from being *displayed*.
you aren't interested in logging the output in that case.
Meanwhile, you are killing named-xfer every time (except
the first) it runs. Why bother with pipes when you're throwing
it all away anyway? What is the *intent* in this scenario?

You're misunderstanding what it's for; we aren't throwing the output
away, we are logging it all (if it doesn't log, that's a different problem).
We just aren't displaying it.
-q means "don't show me the output if the command runs successfully". In
all cases the output is still logged, though.
How are you starting named? Did you change the initscript at all?

The named startup script is unmodified. /usr/sbin/named
itself has been replaced with a shell script that does:
#!/bin/sh
exec /usr/sbin/named.real -t /path/to/chroot/hierarchy "$@"
I.e., it invokes the real named with an additional -t option.
This strategy has enabled me to keep a chrooted named
updated without having to tweak the init script.
In view of your explanation of the -q option, I'll accept this
as a duplicate of 15973, as you had categorized it. Is there
any solution pending?
My workaround was to redirect stdio in my shell script to
/dev/null, so named-xfer doesn't commit suicide.