A simple way to dump kmsg into mmc storage

Document created by MaxTsai Employee on Oct 16, 2013
Version 1Show Document
  • View in full screen mode

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);

}

Attachments

    Outcomes