linux icon indicating copy to clipboard operation
linux copied to clipboard

Update printk.c

Open invicnaper opened this issue 10 years ago • 11 comments

Adding new function , int type_printk(int type, const char *fmt, ...) , it will print an output and adding type , 1 : [error] . 2 [log] 3 [action] . TODO : other types

invicnaper avatar May 28 '14 17:05 invicnaper

Does we need a 'break' statement at the end of 'case 0' block?

hitmoon avatar May 29 '14 02:05 hitmoon

yes it's been added . others types will be added

invicnaper avatar May 29 '14 15:05 invicnaper

Why does in case 1 sprintf() need to be called before local_irq_save()? Since there is no 'undefined type' for which we don't do anything, local_irq_save() and some other routines are going to be used anyway, why not leave repeated statements out of the switch?

int printk_type(int type, const char *fmt, ...) { unsigned long flags; va_list args; char *buf; int r;

local_irq_save(flags);
buf = __get_cpu_var(printk_sched_buf);

switch(type){
    case 0:
        va_start(args, fmt);
        r = vsnprintf(buf, PRINTK_BUF_SIZE, fmt, args);
        break;
    case 1:
        const char *all_fmt;
        sprintf(all_fmt, "[Error] : %s", fmt);
        va_start(args, all_fmt)
        r = vsnprintf(buf, PRINTK_BUF_SIZE, all_fmt, args);
        break;
}

va_end(args);
__this_cpu_or(printk_pending, PRINTK_PENDING_SCHED);
irq_work_queue(&__get_cpu_var(wake_up_klogd_work));
local_irq_restore(flags);

return r;

}

kjenova avatar May 30 '14 12:05 kjenova

Yes it's been added to , and also the default case .

invicnaper avatar May 30 '14 14:05 invicnaper

Also, if you want the function to be visible inside the kernel API (as printk() is) you should add this underneath the closing brace of the function:

EXPORT_SYMBOL(type_printk);

kjenova avatar May 30 '14 15:05 kjenova

This is exactly why Linus doesn't support pull requests via GitHub. Your willingness to contribute to an open source project is appreciated, but you can't just send pull requests to a major project with broken, untested code. Read the docs, go through the proper vetting process, and THEN submit your pull requests (but not here).

chest-rockwell avatar May 30 '14 18:05 chest-rockwell

OP's current code doesn't work. I made a working version, for educational purposes. Applying this commit (https://github.com/kjenova/linux/commit/26eb273d60d91a0979468e094ea0718348599d65) to the latest kernel (3.15.0-rc7), building the kernel, running it, compiling this module against the kernel and running this module:

#include "/where_your_3.15rc-7_kernel_source_is/linux/module.h" #include "/where_your_3.15rc-7_kernel_source_is/linux/kernel.h"

int init_module() { printk(KERN_INFO "using printk() with KERN_INFO macro."); printk(KERN_WARNING "using printk() with KERN_WARNING macro."); printk(KERN_ERR "using printk() with KERN_ERR macro.");

printk(KERN_INFO "switching to type_printk().");

type_printk(0, "using type_printk() with normal type.");
type_printk(1, "using type_printk() with error type.");
type_printk(2. "using type_printk() with action type.");
type_printk(-1, "using type_printk() with unsupported type.");

return 0;

}

void exit_module(void) {

}

produces this output on the /usr/var/kern.log of my machine (my .config is http://pastebin.com/BcZCkp8i):

/begin

May 31 17:07:28 kje-desktop kernel: [ 177.015377] test_type_printk: module license 'unspecified' taints kernel. May 31 17:07:28 kje-desktop kernel: [ 177.015382] Disabling lock debugging due to kernel taint May 31 17:07:28 kje-desktop kernel: [ 177.015461] using printk() with KERN_INFO macro. May 31 17:07:28 kje-desktop kernel: [ 177.015463] using printk() with KERN_WARNING macro.using printk() with KERN_ERR macro. May 31 17:07:56 kje-desktop kernel: [ 177.015472] switching to type_printk().using type_printk() with normal type.[Error] : using type_printk() with error type.[Action] : using type_printk() with action type.using type_printk() with unsupported type. May 31 17:07:56 kje-desktop kernel: [ 205.352376] general protection fault: 0000 [#1] SMP May 31 17:07:56 kje-desktop kernel: [ 205.352385] Modules linked in: test_type_printk(PO)

/end

I don't see a reason, why to add this change to the kernel. If there is a reason, go with it through the above mentioned process.

kjenova avatar May 31 '14 15:05 kjenova

Well, the reason your code didn't work is, that you should've put it under the declaration of wake_up_klogd() (as printk_sched(), on which your code is based on, is).

kjenova avatar Jun 01 '14 13:06 kjenova

thank you guys for you comments , i have updated the code

invicnaper avatar Jun 01 '14 14:06 invicnaper

Don't forget to add this line to include/linux/printk.h

/begin

asmlinkage __printf(2, 3) __cold int type_printk(int type, char *fmt, ...);

/end

The macro __printf(2, 3) tells us, that the second (we don't start counting at zero here, zero means argument not supplied) argument will be the format string and the third the va_list. __cold is a compiler hint, it tells us to optimise (but not so "agressively", it's "cold" because of that) this functions and place it near other "cold" functions (from: http://axon.cs.byu.edu/~adam/gatheredinfo/tips/tips_gcc.php).

On a side note: your original function also compiles and works (you should put that func at the very end, however), if you add kmalloc(). You can also use the printk_sched() function (I used it in type_printk_using_printk_sched() function).

The full code:

/include/linux/printk.h

add this:

asmlinkage __printf(2, 3) __cold int type_printk(int type, char *fmt, ...);

asmlinkage __printf(2, 3) __cold int type_printk_using_printk_sched(int type, char *fmt, ...);

/kernel/printk.c

add this:

asmlinkage __visible int type_printk(int type, char *fmt, ...) { va_list args; char *buf; char *all_fmt; int r; unsigned long flags;

local_irq_save(flags);
buf = __get_cpu_var(printk_sched_buf);

switch(type) {
    default:
        va_start(args, fmt);
        r = vsnprintf(buf, PRINTK_BUF_SIZE, fmt, args);
        break;
    case 1:
        all_fmt = kmalloc(sizeof(fmt)+11*sizeof(char), GFP_KERNEL);
        sprintf(all_fmt, "[Error] : %s", fmt);
        va_start(args, all_fmt);
        r = vsnprintf(buf, PRINTK_BUF_SIZE, all_fmt, args);
        kfree(all_fmt);
        break;
    case 2:
        all_fmt = kmalloc(sizeof(fmt)+12*sizeof(char), GFP_KERNEL);
        sprintf(all_fmt, "[Action] : %s", fmt);
        va_start(args, all_fmt);
        r = vsnprintf(buf, PRINTK_BUF_SIZE, all_fmt, args);
        kfree(all_fmt);
        break;
}
va_end(args);
__this_cpu_or(printk_pending, PRINTK_PENDING_SCHED);
irq_work_queue(&__get_cpu_var(wake_up_klogd_work));
local_irq_restore(flags);
return r;

} EXPORT_SYMBOL(type_printk);

asmlinkage __visible int type_printk_using_printk_sched(int type, char *fmt, ...) { va_list args; char *all_fmt; int r;

switch(type) {
    default:
        va_start(args, fmt);
        r = printk_sched(fmt, args);
    case 1:
        all_fmt = kmalloc(sizeof(fmt)+11*sizeof(char), GFP_KERNEL);
        sprintf(all_fmt, "[Error] : %s\n", fmt);
        va_start(args, all_fmt);
        r = printk_sched(all_fmt, args);
        kfree(all_fmt);
        break;
    case 2:
        all_fmt = kmalloc(sizeof(fmt)+12*sizeof(char), GFP_KERNEL);
        sprintf(all_fmt, "[Action] : %s\n", fmt);
        va_start(args, all_fmt);
        r = printk_sched(all_fmt, args);
        kfree(all_fmt);
        break;
}
return r;

} EXPORT_SYMBOL(type_printk_using_printk_sched);

/begin

Jun 1 20:20:15 kje-desktop kernel: [ 67.877502] test_type_printk: module license 'unspecified' taints kernel. Jun 1 20:20:15 kje-desktop kernel: [ 67.877506] Disabling lock debugging due to kernel taint Jun 1 20:20:15 kje-desktop kernel: [ 67.877569] using printk() with KERN_INFO macro. Jun 1 20:20:15 kje-desktop kernel: [ 67.877570] using printk() with KERN_WARNING macro.using printk() with KERN_ERR macro. Jun 1 20:20:15 kje-desktop kernel: [ 67.877572] switching to type_printk().switching to type_printk_using_printk_sched(). Jun 1 20:20:15 kje-desktop kernel: [ 67.877765] [sched_delayed] [Error] : using type_printk_using_printk_sched() with unsupported type.

/end

Important: as seen, only one of the outputs of those functions is seen, due to scheduling. So you're better off with the current version!

kjenova avatar Jun 01 '14 19:06 kjenova

ok I corrected the code

invicnaper avatar Jun 05 '14 18:06 invicnaper