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.

%3CLINGO-SUB%20id%3D%22lingo-sub-1124709%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3EA%20simple%20way%20to%20dump%20kmsg%20into%20mmc%20storage%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1124709%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3E%3CSTRONG%3EKernel%20provides%20mtdoops%20to%20dump%20kmsg%20to%20MTD%20device%2C%20but%20MMC%20card%20is%20not%20a%20MTD%20device.%3C%2FSTRONG%3E%3C%2FP%3E%3CP%3E%3CSTRONG%3EWe%20can%20let%20user-space%20program%20to%20execute%20the%20write%20operation%20to%20dump%20kmsg%20into%20block%20storage.%3C%2FSTRONG%3E%3C%2FP%3E%3CP%3E%3CSTRONG%3EThe%20sample%20code%20is%20below.%3C%2FSTRONG%3E%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3E%3CSPAN%20style%3D%22text-decoration%3A%20underline%3B%22%3E%3CSTRONG%3Ekernel%20space%3C%2FSTRONG%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E--%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%23include%20%3CLINUX%3E%3C%2FLINUX%3E%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3Estatic%20struct%20kmsg_dumper%20dump%3B%3C%2FP%3E%3CP%3Estatic%20struct%20proc_dir_entry%20*my_proc%3B%3C%2FP%3E%3CP%3Estatic%20int%20is_panic%20%3D%200%3B%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3Estatic%20int%20my_proc_show(struct%20seq_file%20*m%2C%20void%20*v)%3C%2FP%3E%3CP%3E%7B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20seq_printf(m%2C%20%22%25d%22%2C%20is_panic)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20return%200%3B%3C%2FP%3E%3CP%3E%7D%3C%2FP%3E%3CP%3Estatic%20int%20my_proc_open(struct%20inode%20*inode%2C%20struct%20file%20*file)%3C%2FP%3E%3CP%3E%7B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20return%20single_open(file%2C%20my_proc_show%2C%20NULL)%3B%3C%2FP%3E%3CP%3E%7D%3C%2FP%3E%3CP%3Estatic%20const%20struct%20file_operations%20my_proc_ops%20%3D%20%7B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20.open%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%3D%20my_proc_open%2C%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20.read%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%3D%20seq_read%2C%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20.llseek%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%3D%20seq_lseek%2C%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20.release%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%3D%20single_release%2C%3C%2FP%3E%3CP%3E%7D%3B%3C%2FP%3E%3CP%3Estatic%20void%20oops_do_dump(struct%20kmsg_dumper%20*dumper%2C%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20enum%20kmsg_dump_reason%20reason%2C%20const%20char%20*s1%2C%20unsigned%20long%20l1%2C%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20const%20char%20*s2%2C%20unsigned%20long%20l2)%3C%2FP%3E%3CP%3E%7B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20int%20i%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20printk(%22%23%23%23%20%5B%25s%3A%25d%5D%20reason%20%3D%20%25d%5Cn%22%2C%20__func__%2C%20__LINE__%2C%20reason)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20is_panic%20%3D%201%3B%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20for%20(i%20%3D%200%3Bi%20%26lt%3B%2010%3B%20i%2B%2B)%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20msleep(1000)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20printk(%22%23%23%23%20%5B%25s%3A%25d%5D%20should%20be%20done%5Cn%22%2C%20__func__%2C%20__LINE__)%3B%3C%2FP%3E%3CP%3E%7D%3C%2FP%3E%3CP%3Estatic%20int%20__init%20my_oops_init(void)%3C%2FP%3E%3CP%3E%7B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20int%20err%3B%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20dump.dump%20%3D%20oops_do_dump%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20err%20%3D%20kmsg_dump_register(%26amp%3Bdump)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20if%20(err)%20%7B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20printk(KERN_ERR%20%22oops%3A%20registering%20kmsg%20dumper%20failed%2C%20error%20%25d%5Cn%22%2C%20err)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20return%20-EINVAL%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%7D%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20my_proc%20%3D%20proc_create(%22dump_tester%22%2C%200%2C%20NULL%2C%20%26amp%3Bmy_proc_ops)%3B%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20return%200%3B%3C%2FP%3E%3CP%3E%7D%3C%2FP%3E%3CP%3Estatic%20void%20__exit%20my_oops_exit(void)%3C%2FP%3E%3CP%3E%7B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20printk(%22%23%23%23%20%5B%25s%3A%25d%5D%5Cn%22%2C%20__func__%2C%20__LINE__)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20if%20(my_proc)%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20remove_proc_entry(%20%22dump_tester%22%2C%20NULL)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20kmsg_dump_unregister(%26amp%3Bdump)%3B%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3E%7D%3C%2FP%3E%3CP%3Emodule_init(my_oops_init)%3B%3C%2FP%3E%3CP%3Emodule_exit(my_oops_exit)%3B%3C%2FP%3E%3CP%3EMODULE_LICENSE(%22GPL%22)%3B%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3EUser%20space%3C%2FP%3E%3CP%3E--%3C%2FP%3E%3CP%3E%23include%20%3CSTDIO.H%3E%3C%2FSTDIO.H%3E%3C%2FP%3E%3CP%3E%23include%20%3CSTDLIB.H%3E%3C%2FSTDLIB.H%3E%3C%2FP%3E%3CP%3E%23include%20%3CSTRING.H%3E%3C%2FSTRING.H%3E%3C%2FP%3E%3CP%3E%23include%20%3CSYS%3E%3C%2FSYS%3E%3C%2FP%3E%3CP%3E%23include%20%3CSYS%3E%3C%2FSYS%3E%3C%2FP%3E%3CP%3E%23include%20%3CUNISTD.H%3E%3C%2FUNISTD.H%3E%3C%2FP%3E%3CP%3E%23include%20%3CFCNTL.H%3E%3C%2FFCNTL.H%3E%3C%2FP%3E%3CP%3E%23include%20%3CPOLL.H%3E%3C%2FPOLL.H%3E%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3E%23define%20BUF_LEN%2040960%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3Evoid%20main(int%20argc%2C%20char%20**argv)%3C%2FP%3E%3CP%3E%7B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20char%20tmp%20%3D%20'X'%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20char%20buf%5BBUF_LEN%5D%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20int%20fd_src%2C%20fd_trg%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20int%20fd%20%3D%20open(%22%2Fproc%2Fdump_tester%22%2C%20O_RDONLY%2C%200)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20while(1)%20%7B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20lseek(fd%2C%200%2C%20SEEK_SET)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20read(fd%2C%20%26amp%3Btmp%2C%201)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%2F%2Fprintf(%22%23%23%23%20%5B%25s%3A%25d%5D%20%3D%3D%26gt%3B%20'%25c'%5Cn%22%2C%20__FUNCTION__%2C%20__LINE__%2C%20tmp)%3B%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20if%20(tmp%20%3D%3D%20'1')%20%7B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20fd_src%20%3D%20open(%22%2Fproc%2Fkmsg%22%2C%20O_RDONLY%2C%200)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20fd_trg%20%3D%20open(%22%2Fdev%2Fblock%2Fmmcblk0p6%22%2C%26nbsp%3B%20O_RDWR%2C%200)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20memset(buf%2C%200%2C%20BUF_LEN)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20write(fd_trg%2C%20buf%2C%20BUF_LEN)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20lseek(fd_trg%2C%200%2C%20SEEK_SET)%3B%3C%2FP%3E%3CP%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20read(fd_src%2C%20buf%2C%20BUF_LEN)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20write(fd_trg%2C%20buf%2C%20BUF_LEN)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20close(fd_src)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20close(fd_trg)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20sleep(1)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20printf(%22%23%23%23%20dump%20panic%20log%20into%20%25s%5Cn%22%2C%20%22%2Fdev%2Fblock%2Fmmcblk0p6%22)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20break%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%7D%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20sleep(1)%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%7D%3C%2FP%3E%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20close(fd)%3B%3C%2FP%3E%3CP%3E%7D%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1124709%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CLINGO-LABEL%3ELinux%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1124710%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3ERe%3A%20A%20simple%20way%20to%20dump%20kmsg%20into%20mmc%20storage%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1124710%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EThe%20above%20source%20makes%20several%20references%20to%20%22panic%22.%26nbsp%3B%20However%2C%20if%20the%20kernel%20is%20actually%20in%20panic%2C%20the%20user-space%20program%20will%20not%20be%20able%20to%20execute%20and%20the%20logs%20will%20not%20be%20dumped.%3C%2FP%3E%3C%2FLINGO-BODY%3E
No ratings
Version history
Last update:
‎10-16-2013 01:12 AM
Updated by: