【问题标题】:Linux Block Filter DriverLinux 块过滤器驱动程序
【发布时间】:2017-02-02 21:09:50
【问题描述】:

我有一个基本的 linux 块过滤器驱动程序(取自 https://github.com/asimkadav/block-filter),我想扩展它以执行以下操作:

  1. 在设备上记录 IO 模式
  2. 将 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");
}

【问题讨论】:

  • 它在哪里崩溃?在取消引用之前尝试检查 bio 是否为 NULL。
  • 一旦我将 IO 写入受监控的设备,它就会挂起。我假设它在尝试 printk "bio->bi_size" 时挂起(注释掉 printk 行 - 问题不会发生)。系统完全挂起,所以很难看到它到底在哪里崩溃
  • 如果您注释掉 original_request_fn() 会发生什么?也许这是一个重入问题。我认为,如果挂起/崩溃是在 printk() 中解除对空指针的引用,它会给你一个堆栈跟踪。

标签: c linux linux-kernel linux-device-driver block


【解决方案1】:

从您的代码中替换以下行

blkdev = lookup_bdev(路径);

并使用,

blkdev = blkdev_get_by_path(path, FMODE_READ | FMODE_WRITE, NULL);

这应该可以解决内核重启问题。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 1970-01-01
  • 2017-05-24
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多