哪个驱动程序正在处理我的IOCTL

mds*_*ngh 3 driver linux-device-driver linux-kernel embedded-linux

我打开这样的套接字: skfd = socket( AF_INET, SOCK_DGRAM, 0 ); 然后在skfd上做一个ioctl: ioctl(skfd, SIOCETHTOOL, &ifr)
我想知道哪个驱动程序在我的内核中处理这个IOCTL.
我知道如果它是一个字符驱动程序,我可以查找我打开的文件的主要编号,然后cat /proc/devices查找哪个驱动程序已注册该主要编号.
这里必须有类似的方式.

Krz*_*ski 5

您在表示套接字的filedescriptor上调用ioctl.如果检查net/socket.c文件,您将找到socket_file_ops定义sock_ioctl为ioctl回调的结构.因为SIOCETHTOOL,此函数将sock_do_ioctl依次调用(在检查此特定套接字类型(AF_INET - af_inet.c,inet_ioctl函数)本身不处理此ioctl之后)将调用dev_ioctl哪个可以SIOCETHTOOL通过调用来处理dev_ethtool.如果您的驱动程序定义ethtool_ops,则应支持此操作.

现在找到哪个设备驱动程序支持您的网络接口是另一回事,但这并不是很难.一种方法是使用sysfs,只需检查指向的符号链接是什么(eth0用您的接口名称替换):

readlink /sys/class/net/eth0/device/driver/module
../../../../module/e1000e
Run Code Online (Sandbox Code Playgroud)

所以我的以太网卡是由模块驱动的e1000e.

钓竿

现在我通过阅读代码找到了这个.我对内核代码知之甚少,所以我知道应该在哪里看.但是,如果我不这样做,还有其他方法可以找到这个 - 追踪.现在我不确定这一切是否都适用于2.6.32,但至少我在内核3.2上进行了测试(这没有那么大的不同).我不会详细介绍如何配置内核以获得所有这些功能.Ubuntu 12.04已经满足了所有需要,如果你对google感兴趣ftrace:

你需要debugfs挂载和这样的脚本:

#!/bin/sh
DEBUGFS=`/sys/kernel/debug/`
echo $$ > $DEBUGFS/tracing/set_ftrace_pid
echo function > $DEBUGFS/tracing/current_tracer
exec $*
Run Code Online (Sandbox Code Playgroud)

此脚本将设置ftrace为仅关注当前PID,启用函数跟踪器并执行指定为参数的命令(不分叉,因为这会更改PID).

现在,如果您使用此ioctl的应用程序是/tmp/a.out,您可以调用:

~/bin/ftraceme.sh /tmp/a.out
echo -n "" > /sys/kernel/debug/tracing/current_tracer
grep ioctl /sys/kernel/debug/tracing/trace
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我有:

<...>-11009 [007] 596251.750675: sys_ioctl <-system_call_fastpath    (1)
<...>-11009 [007] 596251.750675: fget_light <-sys_ioctl
<...>-11009 [007] 596251.750675: security_file_ioctl <-sys_ioctl
<...>-11009 [007] 596251.750676: cap_file_ioctl <-security_file_ioctl
<...>-11009 [007] 596251.750676: do_vfs_ioctl <-sys_ioctl
<...>-11009 [007] 596251.750676: sock_ioctl <-do_vfs_ioctl           (2)
<...>-11009 [007] 596251.750677: sock_do_ioctl <-sock_ioctl          (3)
<...>-11009 [007] 596251.750677: inet_ioctl <-sock_do_ioctl          (4)
<...>-11009 [007] 596251.750677: udp_ioctl <-inet_ioctl
<...>-11009 [007] 596251.750678: dev_ioctl <-sock_do_ioctl           (5)
<...>-11009 [007] 596251.750678: _cond_resched <-dev_ioctl
<...>-11009 [007] 596251.750679: dev_load <-dev_ioctl
<...>-11009 [007] 596251.750680: rtnl_lock <-dev_ioctl
<...>-11009 [007] 596251.750680: dev_ethtool <-dev_ioctl             (6)
<...>-11009 [007] 596251.750684: rtnl_unlock <-dev_ioctl
<...>-11009 [007] 596251.750685: _cond_resched <-dev_ioctl
Run Code Online (Sandbox Code Playgroud)

这证明了我上面写的内容.