LWN.net Logo

Playing with printk()

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)

Playing with printk()

Posted Oct 11, 2007 18:24 UTC (Thu) by flewellyn (subscriber, #5047) [Link]

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.

That, right there, is one of my biggest pet peeves with modern distros. I don't WANT colored ls output! And yet, when I remove the coloring in the system profile, distro upgrades always put it right back. Argh.

Playing with printk()

Posted Oct 11, 2007 22:32 UTC (Thu) by nix (subscriber, #2304) [Link]

YMMV: GNU coreutils is one of the first things I install on non-Linux
Unixes, in large part because I can't live without colour ls
and --group-directories-first. :)

(GNU findutils is next for -print0 and -0.)

Use your .profile.

Posted Oct 12, 2007 12:53 UTC (Fri) by dw (subscriber, #12017) [Link]

I've been building this up for years:

rcEnvReset()
{
unalias -a
complete -r

unset startx spwd remount mc _man_ _cd_ _file_ DIR HISTFILE MAIL COLORTERM
unset CPU GNOMEDIR GNOME_PATH HISTCONTROL HOST HOSTFILE INFODIR INFOPATH
unset INPUTRC JAVA_BINDIR JAVA_HOME JDK_HOME JRE_HOME LC_COLLATE LESSCLOSE
unset LESSKEY LESSOPEN LESS_ADVANCED_PREPROCESSOR LS_COLORS LS_OPTIONS
unset MINICOM NNTPSERVER PRINTER QTDIR SDK_HOME TEXINPUTS WINDOWMANAGER
unset XKEYSYMDB NLSPATH is tty no_proxy http_proxy ftp_proxy TZ
}

It's probably a better idea to have a whitelist instead for all those environment variables.

Playing with printk()

Posted Oct 15, 2007 19:15 UTC (Mon) by sfink (subscriber, #6405) [Link]

I kinda like the colored output, except for the minor little problem that the default of dark blue on black is absolutely unreadable. And even if you fix it in your ~/.*rc file, you'll keep running into it on others' accounts or other machines. My fingers have gotten very good at typing
  export LS_COLORS=di=32

That's enough to at least be able to read directory listings.

Playing with printk()

Posted Oct 16, 2007 20:50 UTC (Tue) by nevyn (subscriber, #33129) [Link]

And yet, when I remove the coloring in the system profile, distro upgrades always put it right back.

Of course it does, if you are altering the programs and not the config. files ... you would expect that for pretty much everything else, no?

For user configuration: touch ~/.dir_colors

System config. is in /etc/DIR_COLORS* (rpm -qcf /bin/ls)

Playing with printk()

Posted Oct 16, 2007 21:39 UTC (Tue) by flewellyn (subscriber, #5047) [Link]

I DO modify the config files.  The problem is, Gentoo seems to like switching the configs back
to defaults.  I have to manually prevent it from doing so.

Playing with printk()

Posted Oct 12, 2007 13:29 UTC (Fri) by liljencrantz (subscriber, #28458) [Link]

"Coloring isn't useful. If it was, it would be implemented ~16 years ago."

The above comment strikes me as exceptionally narrow minded. Among the many useful features that Linux has gained in the last few years are things like sshfs, arbitrary number of arguments to exec and many more. I'm sure there are lots of other such features in the pipeline. Arguing that if it doesn't exist, it is not useful seems to be more or less provably incorrect by checking history.

Playing with printk()

Posted Oct 17, 2007 2:43 UTC (Wed) by roelofs (subscriber, #2599) [Link]

The above comment strikes me as exceptionally narrow minded. Among the many useful features that Linux has gained in the last few years are things like sshfs, arbitrary number of arguments to exec and many more. I'm sure there are lots of other such features in the pipeline. Arguing that if it doesn't exist, it is not useful seems to be more or less provably incorrect by checking history.

I haven't checked, but I understood that comment to be probably tongue-in-cheek. Isn't 16 years ago about when GNU ls --color showed up?

Greg

Copyright © 2007, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds