InsaneCoder
InsaneCoder

Reputation: 8268

What is the scope of pr_cont in linux kernel?

I read about pr_cont() in the documentation here but still not clear. The documentation says that it :

Continues a previous log message in the same line.

As expected, for the below code I get the following output.

void another_func(void)
{
    printk(KERN_INFO "This is another function\n");
    pr_cont(KERN_INFO "Testing\n");
}

OUTPUT :

[  830.463883] This is another function
[  830.463903] Testing

But what is the scope of "previous message" here ? Will it append to any dmesg log preceding it, no matter where that previous dmesg came from?

Upvotes: 0

Views: 127

Answers (1)

Ian Abbott
Ian Abbott

Reputation: 17403

This usage is incorrect:

void another_func(void)
{
    printk(KERN_INFO "This is another function\n");
    pr_cont(KERN_INFO "Testing\n");
}

pr_cont(KERN_INFO "Testing\n"); should be pr_cont("Testing\n"); and is equivalent to printk(KERN_CONT "Testing\n");.

The KERN_CONT tag only continues the previous log message if the previous log message does not end with a newline ('\n'). Otherwise it begins a new log message with the KERN_DEFAULT log level.

Here is an example of correct usage:

void another_func(void)
{
    printk(KERN_INFO "This is another function... ");
    pr_cont("Testing\n"); /* or: printk(KERN_CONT "Testing\n"); */
}

Normally, the two function calls will produce a single log message with at the INFO log-level: This is another function... Testing. However, if another printk call (without KERN_CONT) manages to sneak inbetween, the first log message will be finalized with a newline.

This another_func():

void sneaky(void);

void another_func(void)
{
    printk(KERN_INFO "First message... ");
    sneaky();  /* Could be called during preemption for example. */
    printk(KERN_CONT "Continued first\n");
}

void sneaky(void)
{
    printk(KERN_INFO "Sneaky\n");
}

produces these three messages:

First message ... 
Sneaky
Continued first

Even sneakier, this another_func():

void sneakier(void);

void another_func(void)
{
    printk(KERN_INFO "First message... ");
    sneakier();  /* Could be called during preemption for example. */
    printk(KERN_CONT "Continued first\n");
}

void sneakier(void)
{
    printk(KERN_INFO "Sneaky ... ");
}

produces these two messages with the wrong message continued:

First message ... 
Sneaky ... Continued first

Upvotes: 1

Related Questions