私は、私は次の操作を行うために拡張したい(https://github.com/asimkadav/block-filterから取られた)基本的なLinuxのブロックフィルタドライバがあります。別のデバイスへのデバイス Linuxのブロックフィルタドライバ
- 録音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 "bi-> bi_size"(printk行のコメントアウト - 問題は発生しません)を試みているときにハングしていると仮定しています。システムが完全にハングするので、正確にどこがクラッシュするのかが分かりません。 – curious
'original_request_fn()'をコメントアウトするとどうなりますか?おそらく、これは再入国の問題です。私はハング/クラッシュが 'printk()'にヌルポインタを逆参照しているとスタックトレースを与えると思います。 –