2017-02-02 4 views
0

私は、私は次の操作を行うために拡張したい(https://github.com/asimkadav/block-filterから取られた)基本的なLinuxのブロックフィルタドライバがあります。別のデバイスへのデバイス Linuxのブロックフィルタドライバ

  • 重複IO上

    1. 録音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"); 
    } 
    
  • +0

    どこがクラッシュしますか?逆参照する前に 'bio'がNULLであるかどうかを調べてみてください。 –

    +0

    私はIOを監視対象のデバイスに書き込むとハングします。私は、printk "bi-> bi_size"(printk行のコメントアウト - 問題は発生しません)を試みているときにハングしていると仮定しています。システムが完全にハングするので、正確にどこがクラッシュするのかが分かりません。 – curious

    +0

    'original_request_fn()'をコメントアウトするとどうなりますか?おそらく、これは再入国の問題です。私はハング/クラッシュが 'printk()'にヌルポインタを逆参照しているとスタックトレースを与えると思います。 –

    答えて

    1

    コードから次の行を交換

    blkdev = lookup_bdev(パス)。

    及び使用

    blkdev = blkdev_get_by_path(パス、FMODE_READ | FMODE_WRITE、NULL);

    これは、カーネルの再起動の問題を修正するはずです。

    +0

    変更を適用した後にカーネルパニックが発生しています。 – curious

    +0

    @curious、Plsは以下のコードを参照して、私たちのタスクを手伝ってくれました。https://gist.github.com/prashants/3839380 – user6826339