A simple way to dump kmsg into mmc storage

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

A simple way to dump kmsg into mmc storage

A simple way to dump kmsg into mmc storage

Kernel provides mtdoops to dump kmsg to MTD device, but MMC card is not a MTD device.

We can let user-space program to execute the write operation to dump kmsg into block storage.

The sample code is below.

kernel space

--

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/console.h>

#include <linux/vmalloc.h>

#include <linux/seq_file.h>

#include <linux/workqueue.h>

#include <linux/sched.h>

#include <linux/wait.h>

#include <linux/delay.h>

#include <linux/interrupt.h>

#include <linux/kmsg_dump.h>

#include <linux/proc_fs.h>

static struct kmsg_dumper dump;

static struct proc_dir_entry *my_proc;

static int is_panic = 0;

static int my_proc_show(struct seq_file *m, void *v)

{

    seq_printf(m, "%d", is_panic);

    return 0;

}

static int my_proc_open(struct inode *inode, struct file *file)

{

    return single_open(file, my_proc_show, NULL);

}

static const struct file_operations my_proc_ops = {

    .open        = my_proc_open,

    .read        = seq_read,

    .llseek        = seq_lseek,

    .release    = single_release,

};

static void oops_do_dump(struct kmsg_dumper *dumper,

        enum kmsg_dump_reason reason, const char *s1, unsigned long l1,

        const char *s2, unsigned long l2)

{

    int i;

    printk("### [%s:%d] reason = %d\n", __func__, __LINE__, reason);

    is_panic = 1;

    for (i = 0;i < 10; i++)

        msleep(1000);

    printk("### [%s:%d] should be done\n", __func__, __LINE__);

}

static int __init my_oops_init(void)

{

    int err;

    dump.dump = oops_do_dump;

    err = kmsg_dump_register(&dump);

    if (err) {

        printk(KERN_ERR "oops: registering kmsg dumper failed, error %d\n", err);

        return -EINVAL;

    }

    my_proc = proc_create("dump_tester", 0, NULL, &my_proc_ops);

    return 0;

}

static void __exit my_oops_exit(void)

{

    printk("### [%s:%d]\n", __func__, __LINE__);

    if (my_proc)

        remove_proc_entry( "dump_tester", NULL);

    kmsg_dump_unregister(&dump);

}

module_init(my_oops_init);

module_exit(my_oops_exit);

MODULE_LICENSE("GPL");

User space

--

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

#include <fcntl.h>

#include <poll.h>

#define BUF_LEN 40960

void main(int argc, char **argv)

{

    char tmp = 'X';

    char buf[BUF_LEN];

    int fd_src, fd_trg;

    int fd = open("/proc/dump_tester", O_RDONLY, 0);

    while(1) {

        lseek(fd, 0, SEEK_SET);

        read(fd, &tmp, 1);

        //printf("### [%s:%d] ==> '%c'\n", __FUNCTION__, __LINE__, tmp);

        if (tmp == '1') {

            fd_src = open("/proc/kmsg", O_RDONLY, 0);

            fd_trg = open("/dev/block/mmcblk0p6",  O_RDWR, 0);

            memset(buf, 0, BUF_LEN);

            write(fd_trg, buf, BUF_LEN);

            lseek(fd_trg, 0, SEEK_SET);

            read(fd_src, buf, BUF_LEN);

            write(fd_trg, buf, BUF_LEN);

            close(fd_src);

            close(fd_trg);

            sleep(1);

            printf("### dump panic log into %s\n", "/dev/block/mmcblk0p6");

            break;

        }

        sleep(1);

    }

    close(fd);

}

Labels (1)
Comments

The above source makes several references to "panic".  However, if the kernel is actually in panic, the user-space program will not be able to execute and the logs will not be dumped.

No ratings
Version history
Last update:
‎10-16-2013 01:12 AM
Updated by: