Re: [PATCH] Console: fall back to /dev/null when no console is availlable

From: Valdis . Kletnieks
Date: Thu Oct 07 2004 - 08:42:37 EST


On Wed, 06 Oct 2004 21:29:44 BST, Alan Cox said:
> On Mer, 2004-10-06 at 21:54, Greg KH wrote:
> > Ok, then anyone with some serious bash-foo care to send me a patch for
> > the existing /sbin/hotplug file that causes it to handle this properly?

Greg - Unless you're willing to trust that /dev/ is in something of a sane
state (basically, you're willing to take a leap of faith that /dev/console
and/or /dev/null exist and are references to character devices with the
correct major,minor pair, it's a somewhat doomed quest.

> Something like
>
> #!/bin/sh
> (
> Everything you had before
> ) <>/dev/console 2>&1

That should be '< /dev/console > /dev/console 2>&1' - what you have will open
fd0 on /dev/console for read/write, then point fd2 at wherever fd1 happened to
be pointing. And even that version isn't totally correct - the man page for sh
specifically says: "A failure to open or create a file causes the redirection
to fail." So if /dev/console is borked due to a bad console= kernel
boot parameter, we'll *still* be flying along with a borked stderr.

A *slightly* better version would be:

#!/bin/sh
# First, check if it's even there - we could mknod it but it's
# not safe if /dev is totally scrogged or on a R/O filesystem.
if [ ! -c /dev/console ]; then
exit 999
# not-really-safe mknod magic
if [ -e /dev/console ]; then
/bin/rm -f /dev/console
fi
/sbin/mknod /dev/console c 5 1
# end not-really-safe code
fi
# Next, try redirecting each of 0,1,2 to /dev/console - if
# we redirect and fail, try to use /dev/null instead.
exec < /dev/console
if [ ! /dev/fd/0 -ef /dev/console ]; then
exec < /dev/null
if [ ! /dev/fd/0 -ef /dev/null ]; then
exit 998;
fi
fi
exec > /dev/console
if [ ! /dev/fd/1 -ef /dev/console ]; then
exec > /dev/null
if [ ! /dev/fd/1 -ef /dev/null ]; then
exit 998;
fi
fi
exec 2> /dev/console
if [ ! /dev/fd/2 -ef /dev/console ]; then
exec 2> /dev/null
if [ ! /dev/fd/2 -ef /dev/null ]; then
exit 998
fi
fi
# Everything you had before

This would be a lot shorter as:

for filedesc in 0 1 2; do
exec $filedesc<> /dev/console
if [ ! /dev/fd/$filedesc -ef /dev/console ]; then
exec $filedesc> /dev/null
if [ ! /dev/fd/$filedesc -ef /dev/null ]; then
exit 998
fi
fi
done

But that leaves fd 0-2 in read/write rather than unidirectional.

The reason the rm/mknod isn't really safe is because if either of them
generate an error message, they'll go wherever fd2 is pointing (which is
the problem we're trying to solve, and a major bootstrap problem).

Note that this *still* assumes that at least one of /dev/console or /dev/null
is sane enough to use - if /dev/console won't open (due to a borked 'console='
on the boot line, or whatever), and /dev/null is on a R/O filesystem and has
gotten mangled and is now a regular file, you're still screwed....

Attachment: pgp00000.pgp
Description: PGP signature