By Jonathan Corbet
October 9, 2007
The venerable
printk() function is one of the primary
communication channels from the kernel to user space.
printk()
looks much like the standard C
printf(), but with a few
differences, including support for log levels. This function has not seen
much change in recent times, but there are now a couple of people looking
at enhancing it in various ways.
The most ambitious changes are being pushed by Vegard Nossum. This work
came initially from the discussion of the revived Linux-tiny patch set.
One of the quickest ways to reduce the size of a binary kernel image is to
remove all of the printk() calls and their associated format
strings. The downside of doing that, of course, is that it results in a
kernel which can no longer communicate. If something starts to go wrong on
a printk()-less system, there is often no way to determine what
the problem is. Usually only one experience like that is required before
one decides that, perhaps, storing a few thousand format strings is not the
worst possible use for a bit of memory.
Vegard's original patch
addressed this problem by reworking the definition of printk()
such that calls below a given log level could be dropped at compile time.
With this change in place, debugging messages could be removed from the
kernel while the more important messaged would be retained. This change is
made at the cost of creating a whole new kprint() infrastructure
and breaking occasional printk() callers, though.
This patch also made a number of other changes aimed at different
objectives. In particular, Vegard is trying to help developers who are
looking to translate kernel messages into other languages on the fly.
Supporting translation directly inside the kernel has never been a popular
option, so that part of the task must be done in user space. But people
working on translation still think it would be nice if the messages coming
out of the kernel were formatted in a way which made translation easier.
One of the things which complicates translation, it seems, is the encoding
of arguments into kernel messages. What the translation developers would
like to see is a format where arguments are kept separate from the format
string itself, making it easy to write expressions which match the strings
and, perhaps, do something intelligent with the arguments separately. So
Vegard's patch changed the output format (as seen in the kernel log buffer)
entirely. Arguments were encoded, but kept separate with the idea that the
user-space log daemon would put things together. So, while a current
kernel might print something like:
usb-storage: cheesy flash drive detected at 12
the new format would be more like:
"usb-storage: cheesy flash drive detected at %d", "12"
In fact, there was more to it than that - the new format also included
fields for the log level, current time, file name, line number, and current
function.
This patch raised a few eyebrows. A patch which was intended to help
shrink the kernel, but which, in the end, added a new log buffer format and
about 1600 lines to the kernel tree seemed a bit inconsistent. Nobody
really wants to have to put together a more complicated user-space log
daemon just to make sense of kernel messages. Overall, it seemed like the
addition of a fair amount of complexity for not much gain. So this patch did not get
very far.
Acting on a suggestion from Alan Cox, Vegard came back with a much simpler solution aimed at the
translation problem. Rather than create an entirely new log format, the
new patch simply puts marker characters (0x1f) around each encoded
argument. This character does not display on serial consoles (though it
does result in "funny symbols" on VGA consoles, currently), but it can be
picked out by translation code. This more focused solution has not yet
gotten a lot of feedback, but it might point the way toward the creation of
more translation-friendly messages without forcing big changes to the
kernel - or to the habits of kernel developers.
Meanwhile, Jan Engelhardt decided to stir things up and improve the
"cuteness" of Linux by adding a color output option for kernel
messages. The initial version of the patch set a single color for all
messages; later updates added per-loglevel coloring as well. Some
developers like this feature, while others see it as useless bloat. One remarked that "Coloring isn't useful. If
it was, it would be implemented ~16 years ago." In the end, the
patch is small and the default output does not change, so there probably is
no real reason for it not to go in. One can only hope the distributors can
resist the temptation to set up message colors which are as garishly
unreadable as those they seem to prefer for tools like ls.
(
Log in to post comments)