Linux kernel linux内核和用户空间之间通信和同步的最佳方式
我的目标是从内核记录许多活动。为此,我需要写入基于磁盘的文件系统 因此,我实现了一个字符设备驱动程序,以及一个从这个虚拟设备读取数据的用户空间进程。驱动程序将数据复制到用户空间缓冲区,用户进程将其写入文件 我的问题是如何同步数据。我开始在fifo的内核实现中使用kfifo。因此,无论我想在哪里记录,我都使用kfifo API将数据复制到fifo中。虚拟设备驱动程序读取fifo并将其复制到用户空间。由于正在记录的数据是巨大的,我需要同步,如生产者消费者。linux内核中有这样的支持吗Linux kernel linux内核和用户空间之间通信和同步的最佳方式,linux-kernel,device-driver,kernel,kernel-module,Linux Kernel,Device Driver,Kernel,Kernel Module,我的目标是从内核记录许多活动。为此,我需要写入基于磁盘的文件系统 因此,我实现了一个字符设备驱动程序,以及一个从这个虚拟设备读取数据的用户空间进程。驱动程序将数据复制到用户空间缓冲区,用户进程将其写入文件 我的问题是如何同步数据。我开始在fifo的内核实现中使用kfifo。因此,无论我想在哪里记录,我都使用kfifo API将数据复制到fifo中。虚拟设备驱动程序读取fifo并将其复制到用户空间。由于正在记录的数据是巨大的,我需要同步,如生产者消费者。linux内核中有这样的支持吗 netlin
netlink套接字解决了这样的问题吗???您可能想使用中继接口,请参阅文档/filesystems/relay.txt。我认为netlink套接字比char设备更适合您的用途。内核将在任何时候写入套接字,等待该套接字的用户程序将从中读取并将其写入文件
此外,如果您只是试图从内核中记录一些信息,而不是编写模块或更改linux内核以供生产使用,那么从内核中打开和写入文件与开发时一样简单、快速。您也可以使用简单的双缓冲原则,如果您有很多数据要记录,并且不想丢失任何日志数据 我不确定kfifo,但是在您的角色设备驱动程序的读取调用中,如果没有数据要从设备读取,您可以将用户空间进程置于睡眠状态。无论何时内核写入字符设备,它都可以唤醒设备上睡眠的任何进程。例如
In kernel
struct logbufStruct {
char *kbuf; //by kmalloc or any means you wish.
int ptr; //ptr to next writeable byte in kbuf.
size_t kbuf_size;
unsigned int flags;
wait_queue_head_t data_wait;
}
read(inode, filep, buf, size) {
logbufStruct = filep->private_data
if (!test_bit(HAS_DATA, &logbufstruct.flags))
wait_event_interruptible(&logbufstruct->data_wait,
test_bit(HAS_DATA, &logbufstruct.flags)||
test_bit(ERROR, &logbufstruct.flags));
/*
* When this call returns, you would either have woken up
* on data available or some signal interrupt which you should
* handle in your character device and set appropriate flags.
*/
if (test_bit(ERROR, &logbufstruct.flags) return -1;
numbytes = copy_data(logbufStruct, buf, size);
if(!has_more_data(logbufstruct)) clear_bit(HAS_DATA, &logbufstruct.flags);
return numbytes;
}
/* This is the function your modules would call to log data
* to be sent to userspace.
*/
int mylogger_log(logbufstruct, char *msg, size_t n)
{
if (logbufstruct->ptr + n > logbufstruct->kbuf_size)
return -1;
copy the data.
wake_up_interruptible(&logbufstruct->data_wait);
}
//initialization
init_waitqueue_head(&logbufstruct->data_wait);
logbufstruct->kbuf = kmalloc or whatever way you have to allocate
space for holding log messages in memory.