我有一个基本的linux块过滤器驱动程序(取自https://github.com/asimkadav/block-filter),我想扩展它以执行以下操作:
我试图将调试信息添加到“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"); }
答案 0 :(得分:1)
从代码中替换以下行
blkdev = lookup_bdev(路径);
并使用,
blkdev = blkdev_get_by_path(path,FMODE_READ | FMODE_WRITE,NULL);
这应解决内核重启问题。