我有一个基本的Linux块过滤器驱动程序(取自https://github.com/asimkadav/block-filter),我想扩展它来执行以下操作:
在设备上记录IO模式
将IO复制到其他设备
我正试图将调试信息添加到“misc_request_fn”函数中,但内核一直崩溃。
我不知道我做错了什么。
更进一步-如何识别写操作并将其复制到另一个设备?

#include <linux/pci.h>
#include <linux/bug.h>
#include <linux/kallsyms.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/rtnetlink.h>
#include <linux/lockdep.h>
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/swap.h>
#include <linux/completion.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/blkdev.h>

#ifndef _MISCDEVICE_H
#define _MISCDEVICE_H

// Driver number
#define MISC_MINOR      45


// Fault injection op-codes
//
#define MISC_GET 0x101
#define MISC_PUT 0x102

#endif



static struct miscdevice misc_help;
static struct block_device *blkdev;
static void (*original_request_fn) (struct request_queue*, struct bio*);


/* Sample ioctl code - not used. Can be used to trigger on/off filtering. */
static long mischelp_ioctl(/*struct inode *inode,*/ struct file *fp,
                unsigned int cmd, unsigned long arg) {

        if (cmd == MISC_GET)    {
                printk ("Can perform get ops %d.\n", (int) arg);
        }

        if (cmd == MISC_PUT)    {
                printk ("Can perform put ops %d.\n", (int) arg);
        }

        return 0;
}


struct file_operations misc_fops = {
        .unlocked_ioctl = mischelp_ioctl,
        .owner = THIS_MODULE,
        .mmap = NULL,
};

void misc_request_fn(struct request_queue *q, struct bio *bio) {
        //printk ("we are passing bios.\n");
        // here is where we trace requests...
        printk ("IO size %d\n",bio->bi_size);
        original_request_fn (q, bio);
        return;
}


void register_block_device(char *path)  {

        struct request_queue *blkdev_queue = NULL;

        if (path == NULL)       {
                printk ("Block device empty.\n");
                return;
        }

        printk ("Will open %s.\n", path);

        blkdev = lookup_bdev(path);

        if (IS_ERR(blkdev))     {
                printk ("No such block device.\n");
                return;
        }

        printk ("Found block device %p with bs %d.\n", blkdev, blkdev->bd_block_size);
        blkdev_queue = bdev_get_queue(blkdev);
        original_request_fn = blkdev_queue->request_fn;
        blkdev_queue->request_fn = misc_request_fn;
}

void unregister_block_device(void)      {
        struct request_queue *blkdev_queue = NULL;

        blkdev_queue = bdev_get_queue(blkdev);

        if ((blkdev_queue->request_fn != NULL) &&
                        (original_request_fn != NULL))  {

                blkdev_queue->request_fn = original_request_fn;
                printk ("Successfully unregistered block device.\n");
        }
}



int init_module(void)   {
        int retval = 0;
        static char *mischelp_name = "mischelp";

        misc_help.minor = MISC_MINOR;
        misc_help.name = mischelp_name;
        misc_help.fops = &misc_fops;
        retval = misc_register(&misc_help);

        if (retval)
                return retval;

        register_block_device("/dev/sdg");

        printk ("block tracer initialized successfully.\n");
        return 0;
}

void cleanup_module(void){
        int number = 0;

        unregister_block_device();

        number = misc_deregister(&misc_help);
        if (number < 0) {
                printk ("misc_deregister failed. %d\n", number);
        }

        printk ("It's over for block tracer.. \n");
}

最佳答案

替换代码中的以下行
blkdev=查找路径;
使用,
blkdev=blkdev_get_by_path(path,fmode_read fmode_write,空);
这应该可以解决内核重启问题。

关于c - Linux块过滤器驱动程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42012344/

10-11 14:34