Linux kernel 在系统调用期间交互用户空间
我正在尝试编写实现读/写操作的块设备驱动程序。 棘手的是,信息不在硬件中,而是在用户空间进程中。因此,在读/写系统调用期间,我希望与用户空间进行交互(即向用户空间发送信号)。 但是,我的用户空间进程仅在读/写系统调用返回后才捕获信号。在系统调用实现中添加等待似乎被忽略了 我在读取系统调用时使用了以下代码:Linux kernel 在系统调用期间交互用户空间,linux-kernel,signals,system-calls,Linux Kernel,Signals,System Calls,我正在尝试编写实现读/写操作的块设备驱动程序。 棘手的是,信息不在硬件中,而是在用户空间进程中。因此,在读/写系统调用期间,我希望与用户空间进行交互(即向用户空间发送信号)。 但是,我的用户空间进程仅在读/写系统调用返回后才捕获信号。在系统调用实现中添加等待似乎被忽略了 我在读取系统调用时使用了以下代码: ssize\u t sleepy\u read(结构文件*filp,字符*buf,大小计数,loff\u t*f\u pos) { 结构siginfo信息; 结构任务_struct*t; in
ssize\u t sleepy\u read(结构文件*filp,字符*buf,大小计数,loff\u t*f\u pos)
{
结构siginfo信息;
结构任务_struct*t;
int ret;
#定义SIG_测试44
memset(&info,0,sizeof(struct siginfo));
info.si_signo=SIG_测试;
info.si_code=si_队列;
info.si_int=1234;
rcu_读取_锁定();
t=pid_任务(查找pid_ns(当前->pid,&init_pid_ns),pid类型pid);
如果(t==NULL){
printk(KERN_ERR“无此类pid”);
rcu_读取_解锁();
return-ENODEV;
}
rcu_读取_解锁();
ret=send_sig_info(sig_TEST,&info,t);//发送信号
如果(ret<0){
printk(“发送信号时出错”);
返回ret;
}
等待事件可中断(wq,标志!=0);
msleep(10000);
返回(0);
}
用户空间中的此代码:
#定义信号单元测试44
int g_devFile=-1;
无效接收数据(int n,siginfo\u t*info,无效*未使用)
{
printf(“收到的值%i\n”,信息->si\u int);
}
内部主(空)
{
结构sig动作sig;
sig.sa_sigaction=接收数据;
sig.sa_flags=sa_SIGINFO;
SIG动作(SIG_测试和SIG,空);
g_devFile=open(devname,O_RDWR);
if(g_devFile<0){
fprintf(stderr,“错误打开设备[%s]文件错误[%s]\n”,devname,strerror(errno));
返回-1;
}否则{
fprintf(stderr,“设备已打开。ptr=%p\n”,(void*)g_devFile);
}
i=读取(g_devFile和buff,11);
}
目前,我只在10秒睡眠时间后(等待似乎被忽略)才捕捉到我的信号(在用户空间中)。
任何想法都会被告知。谢谢。在读取所有数据之前,您是否有任何理由不能简单地阻止
读取调用?何时以及如何更改标志
?您建议如何阻止读取
?你的意思是从用户空间?我无法控制用户空间。只是内核空间。代码示例中的标志在write
功能期间更改。但这只是一个例子。我只是想找到一种方法来阻止read
系统调用启用我的用户空间应用程序cpu时间,这样它就可以处理我刚刚发送给它的信号
ssize_t sleepy_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
struct siginfo info;
struct task_struct *t;
int ret;
#define SIG_TEST 44
memset(&info, 0, sizeof(struct siginfo));
info.si_signo = SIG_TEST;
info.si_code = SI_QUEUE;
info.si_int = 1234;
rcu_read_lock();
t = pid_task(find_pid_ns(current->pid, &init_pid_ns), PIDTYPE_PID);
if(t == NULL){
printk(KERN_ERR "no such pid\n");
rcu_read_unlock();
return -ENODEV;
}
rcu_read_unlock();
ret = send_sig_info(SIG_TEST, &info, t); //send the signal
if (ret < 0) {
printk("error sending signal\n");
return ret;
}
wait_event_interruptible(wq, flag != 0);
msleep(10000);
return (0);
}
#define SIG_TEST 44
int g_devFile = -1;
void receiveData(int n, siginfo_t *info, void *unused)
{
printf("received value %i\n", info->si_int);
}
int main(void)
{
struct sigaction sig;
sig.sa_sigaction = receiveData;
sig.sa_flags = SA_SIGINFO;
sigaction(SIG_TEST, &sig, NULL);
g_devFile = open(devname, O_RDWR);
if ( g_devFile < 0 ) {
fprintf(stderr,"Error opening device[%s] file err[%s]\n",devname,strerror(errno));
return -1;
} else {
fprintf (stderr, "device opened. ptr=%p\n", (void*)g_devFile);
}
i = read(g_devFile, &buff, 11);
}