【问题标题】:best way to communicate and synchronize between kernel and user space in linuxlinux内核和用户空间之间通信和同步的最佳方式
【发布时间】:2011-05-25 19:47:29
【问题描述】:

我的目标是从内核记录很多活动。为此,我需要写入基于磁盘的文件系统。

所以,我已经实现了一个字符设备驱动程序和一个从这个虚拟设备读取的用户空间进程。驱动程序将数据复制到用户空间缓冲区,用户进程将其写入文件。

我的问题是如何同步数据。我开始在内核实现中使用 kfifo 来实现 fifo。所以无论我想登录哪里,我都使用 kfifo API 将数据复制到 fifo 中。虚拟设备驱动程序从 fifo 读取并将其复制到用户空间。由于记录的数据很大,我需要同步,例如生产者消费者。 linux内核中是否有这样的支持我可以使用?

netlink socket能解决这样的问题吗??

【问题讨论】:

    标签: linux-kernel device-driver kernel kernel-module


    【解决方案1】:

    您可能想要使用中继接口,请参阅Documentation/filesystems/relay.txt

    【讨论】:

      【解决方案2】:

      我认为 netlink 套接字比 char 设备更能满足您的目的。内核将在它想要写入时写入套接字,并且将在此套接字上等待的用户程序将从它读取并将其写入文件。

      此外,如果您只是尝试从内核记录某些内容以获取一些信息,而不是编写模块或更改 linux 内核以供生产使用,那么从内核中打开和写入文件会更简单、更快(就像在开发时)。

      【讨论】:

        【解决方案3】:

        如果您有大量数据要记录并且不想错过任何日志数据,您也可以使用简单的双缓冲原则。

        我不确定 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.
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-05-17
          • 2011-12-30
          • 2011-03-02
          • 1970-01-01
          • 2017-11-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多