小编nda*_*ers的帖子

如何识别linux块设备的请求队列

我正在研究通过网络连接硬盘的驱动程序.有一个错误,如果我在计算机上启用两个或更多硬盘,只有第一个硬盘可以查看和识别分区.结果是,如果我在hda上有1个分区,在hdb上有1个分区,只要我连接hda,就会有一个可以挂载的分区.所以hda1一旦安装就会得到一个blkid xyz123.但是当我继续安装hdb1时,它也会出现相同的blkid,实际上,驱动程序是从hda而不是hdb读取它.

所以我想我找到了司机弄乱的地方.下面是一个调试输出,包括dump_stack,我把它放在第一个看似访问错误设备的地方.

这是代码部分:

/*basically, this is just the request_queue processor. In the log output that
  follows, the second device, (hdb) has just been connected, right after hda
  was connected and hda1 was mounted to the system. */

void nblk_request_proc(struct request_queue *q)
{
struct request *req;
ndas_error_t err = NDAS_OK;

dump_stack();

while((req = NBLK_NEXT_REQUEST(q)) != NULL)
{
    dbgl_blk(8,"processing queue request from slot %d",SLOT_R(req));

    if (test_bit(NDAS_FLAG_QUEUE_SUSPENDED, &(NDAS_GET_SLOT_DEV(SLOT_R(req))->queue_flags)))  {
        printk ("ndas: Queue is suspended\n");
        /* Queue is suspended */
#if ( LINUX_VERSION_CODE …
Run Code Online (Sandbox Code Playgroud)

linux linux-kernel block-device

80
推荐指数
1
解决办法
3504
查看次数

如何在内核模块代码中包含C backtrace?

所以我试图找出哪些内核进程正在调用块驱动程序中的某些函数.我认为在C库中包含backtrace()可以让它变得简单.但是我无法加载回溯.

我复制了这个示例函数来显示回溯:

http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l1.html

所有编译尝试都在一个地方或另一个地方发生错误,导致无法找到文件或未定义函数.

这是最接近的.

在Makefile中我放了编译器指令:

 -rdynamic -I/usr/include 
Run Code Online (Sandbox Code Playgroud)

如果我省略第二个,-I/usr/include,那么编译器报告它找不到所需的头文件execinfo.h.

接下来,在我想要进行回溯的代码中,我从示例中复制了该函数:

//trying to include the c backtrace capability
#include <execinfo.h>

void show_stackframe() {
void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;

trace_size = backtrace(trace, 16);
messages = backtrace_symbols(trace, trace_size);
printk(KERN_ERR "[bt] Execution path:\n");
for (i=0; i<trace_size; ++i)
    printk(KERN_ERR "[bt] %s\n", messages[i]);
}
//backtrace function
Run Code Online (Sandbox Code Playgroud)

我稍后在块驱动程序函数中调用此函数,其中发生错误的第一个符号.只是:

show_stackframe();
Run Code Online (Sandbox Code Playgroud)

所以当我编译它时,会出现以下错误:

user@slinux:~/2.6-32$ make -s
Invoking make againt the kernel at /lib/modules/2.6.32-5-686/build
In file included from /usr/include/features.h:346,
        from /usr/include/execinfo.h:22,
        from /home/linux/2.6-32/block/block26.c:49:
/usr/include/sys/cdefs.h:287:1: …
Run Code Online (Sandbox Code Playgroud)

c kernel backtrace linux-device-driver

24
推荐指数
2
解决办法
3万
查看次数

有人可以帮我替换块设备驱动程序上的"lock_kernel"吗?

谢谢你看这篇文章.我正在尝试修补网络块设备驱动程序.如果您需要查看源代码,请访问http://code.ximeta.com.

我注意到从linux 2.6.37开始,lock_kernel()似乎已被弃用.我读了"ioctl()的新方法",发现设备驱动程序现在应该在操作之前执行特定的锁定.

所以如果可能的话,我想要一些建议.

我在块文件夹部分找到了当前代码中我认为相关的两个部分.

Source 
      block->io.c
           ->ctrldev.c
Run Code Online (Sandbox Code Playgroud)

我把每个片段都放在你的考虑范围内.

io.c包含对lock_kernel的一次调用:

NDAS_SAL_API xbool     sal_file_get_size(sal_file file, xuint64* size)
{
    definitions and declarations etc..

lock_kernel();

#ifdef HAVE_UNLOCKED_IOCTL
    if (filp->f_op->unlocked_ioctl) {   
       some small statements

       error = filp->f_op->unlocked_ioctl(filp, BLKGETSIZE64, (unsigned long)size);

       actions if error or not etc.
   }
#endif

   unlock_kernel(); 
   return ret;
}
Run Code Online (Sandbox Code Playgroud)

并且ctrldev.c包含主要的io函数:

#include <linux/spinlock.h> // spinklock_t
#include <linux/semaphore.h> // struct semaphore
#include <asm/atomic.h> // atomic
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/ide.h>
#include <linux/smp_lock.h>
#include <linux/time.h>

......

int ndas_ctrldev_ioctl(struct inode *inode, struct …
Run Code Online (Sandbox Code Playgroud)

ioctl linux-device-driver linux-kernel

6
推荐指数
2
解决办法
1万
查看次数