printk() and KERN_CONT
A nearly year-old "fix" to the main logging function used in the kernel, printk(), changed the appearance of some log messages in an unexpected way, at least for some. Messages that had appeared on a single line will now be spread over multiple lines as each call to printk() begins a new line in the output unless the KERN_CONT flag is used. That is how a comment in the kernel code says it should work, but the change was made by Linus Torvalds without any discussion or fanfare, so it took some by surprise.
The printk() function is the workhorse of kernel output, for critical messages, warnings, information, and debugging. It is used in much the same way as printf() but there are some differences. For one thing, "log levels" can be prepended to the format string to specify the severity of the message. These range from KERN_EMERG to KERN_DEBUG and can be used as follows:
printk(KERN_ALERT "CPU on fire: %d\n", cpu_num);The log levels are simply strings that get concatenated with the format string, thus there is no comma between them. Another difference from printf() is in how a format string without a newline is treated, which is what has changed. The KERN_CONT "log level" is meant to indicate a continuation line; a printk() that lacks that flag is supposed to start a new line in the log—though that hasn't always been enforced.
Pavel Machek posted a query about that
behavior on August 28. He noted that "printk("foo"); printk("bar"); seems to produce
foo\nbar
", which was both surprising and unwelcome. That led to a
bit of a rant from Torvalds, who had made
the change:
That has always been true. It hasn't always been enforced, though.
If you do two printk's and the second one doesn't say "I'm a continuation", the printk logic assumes you're just confused and wanted two lines.
But, as several pointed out, that behavior only
changed
relatively recently (for the 4.9 kernel released in December 2016); prior to that Machek's example would produce
"foobar" as he expected. Lots of places in the kernel use
printk() without KERN_CONT and expect to get output on a
single line, Joe Perches pointed out.
Perches also complained that Torvalds had, in fact, changed longstanding
behavior and was not just enforcing something that had "always been
true
". But Torvalds pointed to a commit
from 2007 that added the KERN_CONT flag, along with the
following comment:
/* * Annotation for a "continued" line of log printout (only done after a * line that had no enclosing \n). Only to be used by core/arch code * during early bootup (a continued line is not SMP-safe otherwise). */
While 2007 is not exactly "always", the comment certainly documents the intent of KERN_CONT, so not using it and expecting multiple calls to printk() to end up on the same line has not been right for nearly ten years. Torvalds was unapologetic about this recent change:
In fact, he would like to get rid of the whole idea of continuation lines. They made some amount of sense when the output was just sent to a circular character buffer, he said, but printk() now has a log-based structure so continuation lines do not really work well in that environment. Beyond that, there is always the chance that some asynchronous action (e.g. an interrupt) outputs something that interferes with the single line of output. Instead, users should be marshaling their own output into single-line chunks and passing those to printk(), he said.
He went on to suggest that some helper functions be added to assist in places where that marshaling is needed. Users would provide their own buffer to these routines that would then call printk() when they have a full line.
That set off a discussion on various ways to implement what had been suggested. Various schemes to replace printk() with something "smarter" were batted down quickly by Torvalds. Steven Rostedt recommended using the kernel's seq_buf facility that is used for tracing and implementing /proc files. That idea seemed to gain traction among the other thread participants (including, crucially, Torvalds). So far, no patch set along those lines has been proposed, but it seems like a promising direction.
No matter what happens, there are going to be multiple changes to fix the output in places where KERN_CONT was not used but should have been. If the seq_buf interface is going to be used, it would make sense to do that directly, rather than add a bunch of KERN_CONT flags in various places. Once that is done, perhaps the existing uses of KERN_CONT could be tackled to get rid of as many of those as possible—leaving only those used at boot time as was originally planned.
Clearly Torvalds doesn't think twice about breaking things internal to the kernel in order to enforce something he sees as important. Doing so silently, though, as happened here, might not have been the best approach. Had there been discussion of the patch on the mailing list, it would at least have given folks a chance to realize what was up. That might have eliminated Machek's query and perhaps reduced Torvalds's blood pressure a bit.
Index entries for this article | |
---|---|
Kernel | Kernel messages |
Kernel | printk() |
Posted Aug 31, 2017 7:17 UTC (Thu)
by abelloni (subscriber, #89904)
[Link]
Posted Aug 31, 2017 11:45 UTC (Thu)
by grawity (subscriber, #80596)
[Link]
He's defending it now, but I remember when the new /dev/kmsg system got merged and broke implicit (non-KERN_CONT) continuations for the first time. Linus wasn't amused. (Well, it's fine. As a userspace person, I'd much rather have /dev/kmsg with strict records than the old crusty interface with continuations...)
Posted Sep 4, 2017 15:49 UTC (Mon)
by nettings (subscriber, #429)
[Link] (7 responses)
Posted Sep 4, 2017 16:11 UTC (Mon)
by rvfh (guest, #31018)
[Link] (2 responses)
Posted Sep 8, 2017 8:45 UTC (Fri)
by Wol (subscriber, #4433)
[Link]
And the same almost certainly holds true for other names!
Cheers,
Posted Sep 8, 2017 21:03 UTC (Fri)
by nix (subscriber, #2304)
[Link]
Posted Sep 10, 2017 8:24 UTC (Sun)
by mcortese (guest, #52099)
[Link] (3 responses)
It's not journalistic style, it's how we actually speak: you fully define the persons the first time you mention them, then you refer to them with a placeholder. "I met my younger brother at the pub. He was drinking a beer".
LWN's style is the same: full name and surname (and possibly role in the kernel community) at first mention, unadorned surname afterwards.
There's no need for your cheat sheet, if you don't remember who is who, all you have to do is go back some paragraphs.
Posted Sep 10, 2017 13:07 UTC (Sun)
by nix (subscriber, #2304)
[Link] (2 responses)
If these people were in the habit of introducing themselves to other people by their surname, using surnames as identifiers in news reporting might make sense. (For, e.g. political reporting, this is often true). But until Linus is is the habit of calling himself 'Torvalds' on the linux-kernel list, and other people call him that, I think it's the wrong identifier to use, and needlessly confusing. It seems rather disrespectful, too. Why call someone 'Machek' when he's made it clear in every post he makes that he wants to be called Pavel?
(This may be a generation-gap thing, too. A lifetime ago, perhaps before WWII and definitely before WWI, it was disrespectful to not call your elders and betters by their surnames whether or not they called each other by anything else, but in my view this has completely inverted by now.)
Posted Sep 11, 2017 7:02 UTC (Mon)
by mcortese (guest, #52099)
[Link] (1 responses)
Posted Sep 11, 2017 11:52 UTC (Mon)
by nix (subscriber, #2304)
[Link]
(Also, you don't have to be *in* the inner group. That's the beauty of work in the open: you just have to read the same mailing lists!)
printk() and KERN_CONT
printk() and KERN_CONT
That will take some getting used to...
;)
That will take some getting used to...
That will take some getting used to...
Wol
That will take some getting used to...
That will take some getting used to...
That will take some getting used to...
I think you can't apply the same rules to the inner group of co-workers who have daily interactions and the broader audience of a newsletter.
I've never thought of LWN as targeting the same people who is involved in the kernel development and is thus familiar with its jargon, nicknames, and abbreviations. In that restricted group it might be OK to use first names, as it's also OK to use well-known acronyms like BKL. For the rest of us, LWN provides a great service defining them on first use and applying a consistent scheme.
That will take some getting used to...
That will take some getting used to...