Why are kernel log messages in the syslog file (or those redirected to terminal) exactly one 'message' behind? - linux

I wrote a simple hello-world module on Ubuntu 10.04 machine. When loading and unloading the module, printk should log messages from the following hello_world and bye_world functions.
static int hello_world()
{
printk(KERN_INFO "Hello, beautiful world");
return 0;
}
static void bye_world()
{
printk(KERN_INFO "Good-bye kernel uncle");
}
module_init(hello_world);
module_exit(bye_world);
However, when actually inserting and removing the hello.ko module, I see that the message printed on the terminal (I redirected it to the current terminal) is exactly one message behind.
# rmmod hello.ko
# Jul 8 16:34:02 panchavati kernel: [64599.954113] Hello, beautiful world
# insmod hello.ko
# Jul 8 16:34:57 panchavati kernel: [65456.367422] Good-bye kernel uncle
From dmesg output, I can see the next message entry (corresponding to insmod) has been already logged, just that it is not being printed yet.
chanakya#panchavati:~$ dmesg | tail -2
[65456.367422] Good-bye kernel uncle
[65511.198299] Hello, beautiful world
The entry [65511.198299] is there in the kernel log, but only the previous entry [65456.367422] Good-bye kernel uncle was printed. Why is it so?
I earlier thought that '-' specifier used in /etc/syslog.conf might have to do something with this (it prevents synchronization after every write), but removing it didn't work either.

Have you tried using tailf (or tail -f)? It will print out the messages as they arrive. For example:
tailf /var/log/messages

Try ending your strings with a newline ("\n").

Related

Debug messages not being printed on the console

I am trying to enable printing the debug messages on the console.
#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int test_hello_init(void)
{
printk(KERN_INFO"%s: In init\n", __func__);
return 0;
}
static void test_hello_exit(void)
{
printk(KERN_INFO"%s: In exit\n", __func__);
}
module_init(test_hello_init);
module_exit(test_hello_exit);
To get the Info messages on the console, i executed the following command: dmesg -n7
cat /proc/sys/kernel/printk
7 4 1 7
When I load the module using insmod, i don't get any message on the terminal, while it is available when I type dmesg. What mistake i am making here.
Messages from kernel are not printed on terminal (unless it's specified as console= in kernel cmdline). They are appended to kernel log, which exists in kernel. It's accessible to user space programs via device file /dev/kmsg. This file is read by dmesg command in order to print kernel log content on terminal.

Can dmesg print truncated lines in Linux?

I am going to monitor dmesg by calling:
dmesg -c
every 1 second. I will look for specific strings in the output and then I will execute an action depending on the found strings.
However, I am worried about this scenario:
The Kernel prints a 20-chars message into the dmesg ring buffer, for example:
printk("Hello World !!!!!!!!"))
Right when the Kernel is printing a specific char... let's say the 10th char, the user calls dmesg
The last line was not completely written by the Kernel when we read the buffer
What will "dmesg -c" print?
a) A truncated line with only its first 10 chars (Hello Worl)
b) Omits the pending line
And then, in a next call of "dmesg -c", will it...
a) print the missing 10 chars of the pending line (d !!!!!!!!), or
b) print the full pending line?
This worries me because I will look for specific strings and if they get truncated then my idea will not work.
I am using Linux 2.6.31 and dmesg is run through busybox:
rwxrwxrwx 1 root root 7 Jun 3 07:36 dmesg -> busybox
BusyBox v1.19.3 () multi-call binary.
Usage: dmesg [-c] [-n LEVEL] [-s SIZE]
I have run dmesg several times and I have never noticed a truncated line, but it's better to know if it has only been luck.
Thanks.

how can i find the info i modified in kernel

I added a printk() in the function void __init setup_arch(char **cmdline_p) in /usr/src/linux/arch/x86/kernel/setup.c. And then run make and then dmesg /var/log and couldn't see my printk content,how and where can i see them
Take help from kernel log-level
http://elinux.org/Debugging_by_printing#Log_Levels
you can use following for enable all logs of kernel
echo 7 > /proc/sys/kernel/printk
hopefully it will help you.
To see kernel logs use -> dmesg it shows you printf of ring buffer of linux().
if there is problem to logs on console then use dmesg > log_file (logs will store in file you can find logs in file)
for more logs of system you can use following
vim /var/log/messages
vim /var/log/syslog
in /var/log/ directory all the system logs exist.

sending message to printk buffer from user space -- not working

Actually i want my driver messages to reach my terminal for debugging purpose. So i just try to check by following below link.
I refred following link :--
http://elinux.org/Debugging_by_printing
I am using a ubuntu in side vmplayer virtual machine. Ubuntu is running in terminal mode inside virtual machine.
I am trying to send some message to kernel printk buffer, buts echo command fails.
klog demon is also running i confirmed with following command .
ps aux | grep klogd
Cat command on proc printk entry :---
# cat /proc/sys/kernel/printk
4 4 1 7
run echo command :---
#sudo echo "<1>Writing critical printk messages from userspace" >/dev/kmsg
But i am not able to get the message on the terminal. I am getting following error when runs above command :--
-bash: /dev/kmsg: Permission denied
Please suggest how to print on console ?
my actual requirement is to ... send messages of printk() in my driver ... directly to my console. I am just testing here from my console that messages of low priority reaches console or not .
how this post is right then .. ?
linux kprint messages on console
Please suggest.
The error is because the shell is the thing trying to write to /dev/kmsg (via the redirect), and it is not being run with sudo. Also, by default echo is usually a shell builtin, not a binary that can executed in another process, though that's kind of irrelevant here. The right way to do this is
echo "blah" | sudo tee /dev/kmsg
tee is a command that copies stdin to a file and stdout. It's called tee because it's like a T-shaped pipe in a pipeline.

Is there a way to figure out what is using a Linux kernel module?

If I load a kernel module and list the loaded modules with lsmod, I can get the "use count" of the module (number of other modules with a reference to the module). Is there a way to figure out what is using a module, though?
The issue is that a module I am developing insists its use count is 1 and thus I cannot use rmmod to unload it, but its "by" column is empty. This means that every time I want to re-compile and re-load the module, I have to reboot the machine (or, at least, I can't figure out any other way to unload it).
Actually, there seems to be a way to list processes that claim a module/driver - however, I haven't seen it advertised (outside of Linux kernel documentation), so I'll jot down my notes here:
First of all, many thanks for #haggai_e's answer; the pointer to the functions try_module_get and try_module_put as those responsible for managing the use count (refcount) was the key that allowed me to track down the procedure.
Looking further for this online, I somehow stumbled upon the post Linux-Kernel Archive: [PATCH 1/2] tracing: Reduce overhead of module tracepoints; which finally pointed to a facility present in the kernel, known as (I guess) "tracing"; the documentation for this is in the directory Documentation/trace - Linux kernel source tree. In particular, two files explain the tracing facility, events.txt and ftrace.txt.
But, there is also a short "tracing mini-HOWTO" on a running Linux system in /sys/kernel/debug/tracing/README (see also I'm really really tired of people saying that there's no documentation…); note that in the kernel source tree, this file is actually generated by the file kernel/trace/trace.c. I've tested this on Ubuntu natty, and note that since /sys is owned by root, you have to use sudo to read this file, as in sudo cat or
sudo less /sys/kernel/debug/tracing/README
... and that goes for pretty much all other operations under /sys which will be described here.
First of all, here is a simple minimal module/driver code (which I put together from the referred resources), which simply creates a /proc/testmod-sample file node, which returns the string "This is testmod." when it is being read; this is testmod.c:
/*
https://github.com/spotify/linux/blob/master/samples/tracepoints/tracepoint-sample.c
https://www.linux.com/learn/linux-training/37985-the-kernel-newbie-corner-kernel-debugging-using-proc-qsequenceq-files-part-1
*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h> // for sequence files
struct proc_dir_entry *pentry_sample;
char *defaultOutput = "This is testmod.";
static int my_show(struct seq_file *m, void *v)
{
seq_printf(m, "%s\n", defaultOutput);
return 0;
}
static int my_open(struct inode *inode, struct file *file)
{
return single_open(file, my_show, NULL);
}
static const struct file_operations mark_ops = {
.owner = THIS_MODULE,
.open = my_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int __init sample_init(void)
{
printk(KERN_ALERT "sample init\n");
pentry_sample = proc_create(
"testmod-sample", 0444, NULL, &mark_ops);
if (!pentry_sample)
return -EPERM;
return 0;
}
static void __exit sample_exit(void)
{
printk(KERN_ALERT "sample exit\n");
remove_proc_entry("testmod-sample", NULL);
}
module_init(sample_init);
module_exit(sample_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mathieu Desnoyers et al.");
MODULE_DESCRIPTION("based on Tracepoint sample");
This module can be built with the following Makefile (just have it placed in the same directory as testmod.c, and then run make in that same directory):
CONFIG_MODULE_FORCE_UNLOAD=y
# for oprofile
DEBUG_INFO=y
EXTRA_CFLAGS=-g -O0
obj-m += testmod.o
# mind the tab characters needed at start here:
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
When this module/driver is built, the output is a kernel object file, testmod.ko.
At this point, we can prepare the event tracing related to try_module_get and try_module_put; those are in /sys/kernel/debug/tracing/events/module:
$ sudo ls /sys/kernel/debug/tracing/events/module
enable filter module_free module_get module_load module_put module_request
Note that on my system, tracing is by default enabled:
$ sudo cat /sys/kernel/debug/tracing/tracing_enabled
1
... however, the module tracing (specifically) is not:
$ sudo cat /sys/kernel/debug/tracing/events/module/enable
0
Now, we should first make a filter, that will react on the module_get, module_put etc events, but only for the testmod module. To do that, we should first check the format of the event:
$ sudo cat /sys/kernel/debug/tracing/events/module/module_put/format
name: module_put
ID: 312
format:
...
field:__data_loc char[] name; offset:20; size:4; signed:1;
print fmt: "%s call_site=%pf refcnt=%d", __get_str(name), (void *)REC->ip, REC->refcnt
Here we can see that there is a field called name, which holds the driver name, which we can filter against. To create a filter, we simply echo the filter string into the corresponding file:
sudo bash -c "echo name == testmod > /sys/kernel/debug/tracing/events/module/filter"
Here, first note that since we have to call sudo, we have to wrap the whole echo redirection as an argument command of a sudo-ed bash. Second, note that since we wrote to the "parent" module/filter, not the specific events (which would be module/module_put/filter etc), this filter will be applied to all events listed as "children" of module directory.
Finally, we enable tracing for module:
sudo bash -c "echo 1 > /sys/kernel/debug/tracing/events/module/enable"
From this point on, we can read the trace log file; for me, reading the blocking,
"piped" version of the trace file worked - like this:
sudo cat /sys/kernel/debug/tracing/trace_pipe | tee tracelog.txt
At this point, we will not see anything in the log - so it is time to load (and utilize, and remove) the driver (in a different terminal from where trace_pipe is being read):
$ sudo insmod ./testmod.ko
$ cat /proc/testmod-sample
This is testmod.
$ sudo rmmod testmod
If we go back to the terminal where trace_pipe is being read, we should see something like:
# tracer: nop
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
insmod-21137 [001] 28038.101509: module_load: testmod
insmod-21137 [001] 28038.103904: module_put: testmod call_site=sys_init_module refcnt=2
rmmod-21354 [000] 28080.244448: module_free: testmod
That is pretty much all we will obtain for our testmod driver - the refcount changes only when the driver is loaded (insmod) or unloaded (rmmod), not when we do a read through cat. So we can simply interrupt the read from trace_pipe with CTRL+C in that terminal; and to stop the tracing altogether:
sudo bash -c "echo 0 > /sys/kernel/debug/tracing/tracing_enabled"
Here, note that most examples refer to reading the file /sys/kernel/debug/tracing/trace instead of trace_pipe as here. However, one problem is that this file is not meant to be "piped" (so you shouldn't run a tail -f on this trace file); but instead you should re-read the trace after each operation. After the first insmod, we would obtain the same output from cat-ing both trace and trace_pipe; however, after the rmmod, reading the trace file would give:
<...>-21137 [001] 28038.101509: module_load: testmod
<...>-21137 [001] 28038.103904: module_put: testmod call_site=sys_init_module refcnt=2
rmmod-21354 [000] 28080.244448: module_free: testmod
... that is: at this point, the insmod had already been exited for long, and so it doesn't exist anymore in the process list - and therefore cannot be found via the recorded process ID (PID) at the time - thus we get a blank <...> as process name. Therefore, it is better to log (via tee) a running output from trace_pipe in this case. Also, note that in order to clear/reset/erase the trace file, one simply writes a 0 to it:
sudo bash -c "echo 0 > /sys/kernel/debug/tracing/trace"
If this seems counterintuitive, note that trace is a special file, and will always report a file size of zero anyways:
$ sudo ls -la /sys/kernel/debug/tracing/trace
-rw-r--r-- 1 root root 0 2013-03-19 06:39 /sys/kernel/debug/tracing/trace
... even if it is "full".
Finally, note that if we didn't implement a filter, we would have obtained a log of all module calls on the running system - which would log any call (also background) to grep and such, as those use the binfmt_misc module:
...
tr-6232 [001] 25149.815373: module_put: binfmt_misc call_site=search_binary_handler refcnt=133194
..
grep-6231 [001] 25149.816923: module_put: binfmt_misc call_site=search_binary_handler refcnt=133196
..
cut-6233 [000] 25149.817842: module_put: binfmt_misc call_site=search_binary_handler refcnt=129669
..
sudo-6234 [001] 25150.289519: module_put: binfmt_misc call_site=search_binary_handler refcnt=133198
..
tail-6235 [000] 25150.316002: module_put: binfmt_misc call_site=search_binary_handler refcnt=129671
... which adds quite a bit of overhead (in both log data ammount, and processing time required to generate it).
While looking this up, I stumbled upon Debugging Linux Kernel by Ftrace PDF, which refers to a tool trace-cmd, which pretty much does the similar as above - but through an easier command line interface. There is also a "front-end reader" GUI for trace-cmd called KernelShark; both of these are also in Debian/Ubuntu repositories via sudo apt-get install trace-cmd kernelshark. These tools could be an alternative to the procedure described above.
Finally, I'd just note that, while the above testmod example doesn't really show use in context of multiple claims, I have used the same tracing procedure to discover that an USB module I'm coding, was repeatedly claimed by pulseaudio as soon as the USB device was plugged in - so the procedure seems to work for such use cases.
It says on the Linux Kernel Module Programming Guide that the use count of a module is controlled by the functions try_module_get and module_put. Perhaps you can find where these functions are called for your module.
More info: https://www.kernel.org/doc/htmldocs/kernel-hacking/routines-module-use-counters.html
All you get are a list of which modules depend on which other modules (the Used by column in lsmod). You can't write a program to tell why the module was loaded, if it is still needed for anything, or what might break if you unload it and everything that depends on it.
You might try lsof or fuser.
If you use rmmod WITHOUT the --force option, it will tell you what is using a module. Example:
$ lsmod | grep firewire
firewire_ohci 24695 0
firewire_core 50151 1 firewire_ohci
crc_itu_t 1717 1 firewire_core
$ sudo modprobe -r firewire-core
FATAL: Module firewire_core is in use.
$ sudo rmmod firewire_core
ERROR: Module firewire_core is in use by firewire_ohci
$ sudo modprobe -r firewire-ohci
$ sudo modprobe -r firewire-core
$ lsmod | grep firewire
$
try kgdb and set breakpoint to your module
For anyone desperate to figure out why they can't reload modules, I was able to work around this problem by
Getting the path of the currently used module using "modinfo"
rm -rfing it
Copying the new module I wanted to load to the path it was in
Typing "modprobe DRIVER_NAME.ko".

Resources