我有一个基本的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/