2017-02-02 23 views
0

У меня есть базовый драйвер блочного фильтра (взятый из https://github.com/asimkadav/block-filter), который я хочу продлить сделать следующее:Linux Block Filter Driver

  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"); 
} 
+0

Куда он падает? Попробуйте проверить, является ли 'bio' NULL до разыменования. –

+0

он будет висеть, как только я напишу IO на контролируемое устройство. Предполагаю, что он висит при попытке распечатать «bio-> bi_size» (комментирование строки printk - проблема не возникает). система полностью зависает, поэтому трудно понять, где именно она разбилась – curious

+0

Что произойдет, если вы закомментируете 'original_request_fn()'? Возможно, это проблема повторного входа. Я бы подумал, что если зависание/сбой были в 'printk()' от разыменования нулевого указателя, это даст вам трассировку стека. –

ответ

1

Заменить строку ниже из кода

blkdev = lookup_bdev (путь);

и использование,

blkdev = blkdev_get_by_path (путь, FMODE_READ | FMODE_WRITE, NULL);

Это должно исправить проблему перезагрузки ядра.

+0

Kernel Panic все еще происходит после применения изменения – curious

+0

@ curious, Pls ссылается на приведенный ниже код, который помог нам решить нашу задачу, https://gist.github.com/prashants/3839380 – user6826339

 Смежные вопросы

  • Нет связанных вопросов^_^