尝试将参数传递给 ioctl 调用将参数归零

Posted

技术标签:

【中文标题】尝试将参数传递给 ioctl 调用将参数归零【英文标题】:Attempting to pass argument to ioctl call zeros out argument 【发布时间】:2013-03-08 19:41:28 【问题描述】:

我试图在我的玩具文件系统模块中调用一个 ioctl 函数。我只是想让这个 ioctl 设置一个由调用者传入的变量。到目前为止,我已经建立了允许我进行 ioctl 调用的 ioctl 基础设施。我的模块中有这个函数来处理 ioctl。

int ospfs_ioctl(struct inode *inode, struct file *filp,
      unsigned int cmd, unsigned long arg)

    if(cmd == OSPFSIOCRASH)
    
        eprintk("crash: %ld\n", arg);
        return 0;
    
    else
        return -ENOTTY;

我的测试函数是这样的。

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#define OSPFSIOCRASH 42

int main()

    int fd = open("/tmp/cs111/lab3-thief/test/hello.txt", O_RDWR);
    printf("ioctl call: %d\n", ioctl(fd, OSPFSIOCRASH, 100));
    close(fd);

我希望输出是

crash: 100
ioctl call: 0

但输出实际上是

crash: 0
ioctl call: 0

我敢打赌我做错了一些简单的事情。有人可以帮忙并指出问题所在吗?非常感谢。

【问题讨论】:

您的目标平台是什么? x86? 如何设置OSPFSIOCRASH?它需要对参数的方向和大小进行编码,可能使用_IOW(type, nr, unsigned long) 这是一个运行 Debian 2.6.18-6-486 的 x86 模拟器 (QEMU)。如果这有什么不同的话。如何设置_IOW(type, nr, unsigned long)? 我想我一直在懒惰地实现 ioctl。我从另一个人的代码中复制了支持基础设施。总共有一个进入内核.ioctl = ospfs_ioctl 的钩子,在模块头OSPFSIOCRASH 中定义了一个常量cmd 编号,并且有一个ioctl 处理函数(上图)。这就是其他项目拥有的所有 ioctl 代码。我只是注意到另一个项目在使用 ioctl 时没有传递任何参数......我不太确定我需要什么才能使它工作。 测试程序真的应该检查open()的结果。我不知道我有多少不必要的头痛,因为文件系统没有正确重新安装。 【参考方案1】:

这可能不是解决您问题的解决方案,但根据您的问题和 cmets 提供的有限信息,这是我可以收集的。

根据问题和 cmets,您似乎以这种方式定义了 struct file_operations 结构:

struct file_operations fops =  .ioctl=ospfs_ioctl ;

您的ospfs_ioctl 的签名表明您使用的是较旧的ioctl。

使用最近的内核(至少在 2.6.35+ 之后),建议使用.unlocked_ioctl 而不是.ioctl

struct file_operations fops =  .unlocked_ioctl=ospfs_ioctl ;

ospfs_ioctl 函数的定义将更改为:

long ospfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

unlocked_ioctl 和常规 ioctl 之间的区别可以在here 中找到。简而言之,它在调用 ioctl 之前不需要使用可怕的 BKL

根据Chris Dodd 的建议,您应该仔细检查您是如何定义OSPFIOCRASH 的。推荐的方法是使用_IO(magic, some_num_for_ioctl)

【讨论】:

嘿 tuxdude,这很有趣,我稍后可能会尝试更改为 .unlocked_ioctl。现在,由于一些评论建议,我已经让 ioctl 开始工作。我的解决方法是在下面的答案中。【参考方案2】:

根据 Chris Dodd 的建议,我将 #define OSPFIOCRASH 42 更改为 #define OSPFSIOCRASH _IO(magic, 0) 并获得了所需的行为。

【讨论】:

以上是关于尝试将参数传递给 ioctl 调用将参数归零的主要内容,如果未能解决你的问题,请参考以下文章

将参数传递给 jQuery 的 select2 ajax 调用

如何将参数传递给使用 libevent 创建的事件函数?

将对象作为参数传递给函数

如何通过asp.net schtasks将参数传递给bat文件

将额外的参数传递给IntersectionObserver?

MSBuild 将参数传递给 CallTarget