Linux字符驱动程序:阻止ioctl调用

Linux字符驱动程序:阻止ioctl调用,linux,linux-kernel,linux-device-driver,ioctl,Linux,Linux Kernel,Linux Device Driver,Ioctl,我是驱动程序开发新手,我正在尝试编写一个简单的char驱动程序,它具有ioctl,允许用户进程获取我的char驱动程序上次读写的时间(timespec)。 long charmem\u ioctl(结构文件*filp,无符号int cmd,无符号long arg){ struct charmem_dev*dev=filp->private_data; if(可中断(&dev->sem)){ printk(KERN_警告“我被启动了!!\n”); 返回-ERESTARTSYS; } printk

我是驱动程序开发新手,我正在尝试编写一个简单的char驱动程序,它具有ioctl,允许用户进程获取我的char驱动程序上次读写的时间(timespec)。

long charmem\u ioctl(结构文件*filp,无符号int cmd,无符号long arg){
struct charmem_dev*dev=filp->private_data;
if(可中断(&dev->sem)){
printk(KERN_警告“我被启动了!!\n”);
返回-ERESTARTSYS;
}
printk(KERN_警告“charmem:in ioctl;cmd=%d,arg=%d\n”,(int)cmd,(int)arg);
开关(cmd){
案例IOCTL\u获取\u上次读取\u时间:
printk(“charmem_ioctl:返回上次读取时间增量,正在退出…\n”);
向上(&dev->sem);
返回dev->last\u read\u delta.tv\u nsec;
打破
案例IOCTL\u获取\u上次写入时间:
printk(“charmem_ioctl:返回上次写入时间增量,正在退出…\n”);
向上(&dev->sem);
返回dev->last\u write\u delta.tv\u nsec;
打破
case IOCTL_RESET_READ:/*返回指向缓冲区开始的读取指针*/
dev->rp=dev->buffer;
打破
case IOCTL_RESET_WRITE:/*返回指向缓冲区开始的写入指针*/
dev->wp=dev->buffer;
打破
案例IOCTL\u将缓冲区\u加载到\u缓存:
将缓冲区加载到缓存(开发->缓冲区,开发->缓冲区大小);
打破
违约:
printk(“charmem_ioctl:无效的ioctl命令,正在退出…\n”);
向上(&dev->sem);
返回-默认值;
}
向上(&dev->sem);
返回0;
}
结构文件\u操作charmem\u fops={
.owner=此_模块,
.llseek=nollseek,
.read=charmem\u read,
.write=charmem\u write,
.unlocked_ioctl=charmem_ioctl,
.open=charmem\u open,
.release=charmem\u release,
};
main.c
——测试我的字符设备的用户程序:

intfd=0,ret=0;
fd=打开(“/dev/charmem0”,O_RDWR);
如果(fd<0){
printf(“/dev/charmem0无法访问(fd=%d)…正在退出\n”,fd);
返回-1;
}
ret=写入(fd,msg1,10);
ret=读取(fd,用户缓冲区,10);
读取增量=ioctl(fd,ioctl获取上次读取时间);
printf(“读取增量:%d\n”,读取增量);
写入增量=ioctl(fd,ioctl获取上次写入时间);
printf(“写入增量:%d\n”,写入增量);

main.c
是测试我的char设备的程序;程序在打印出
read_delta
value后阻塞,我假设它在ioctl上阻塞。我在代码中做错了什么?

我看不出代码中信号量的上/下有任何问题。程序最可能阻塞的地方是调用down_interruptable()。如果您按下control-c,这将强制down_Interruptable返回,您应该会在dmesg或控制台或系统日志中看到“我启动了”的打印。然后,任务是找出驱动程序中还有什么东西持有该信号量

我想到的另一个想法。。。printf被缓冲。因此,有可能您的GET_LAST_WRITE_TIME ioctl确实返回了,并且输出在标准输出缓冲区中,而您的程序实际上被卡在了更下面的一些代码上。建议在printf(“write delta…”之后添加一个fflush(stdout)以消除这种可能性


Michael

什么让你觉得有问题?(注意:在默认情况下,你不应该返回EFAULT,而是ENOTTY。)当你运行你的程序时,你在内核日志中看到了什么?当你的用户空间程序被阻止时,/proc//stack显示了什么(其中用ioctl将“”替换为被阻止进程的PID号)?你在dmesg中看到了什么?你能在程序阻塞时按住ctrl-C键并杀死它吗?