Take the 2-minute tour ×

My objective is to log a lot of activities from kernel. For this I need to write into disk based file systems.

So, I have implemented a character device driver, and a user space process which reads from this virtual device. The driver copies the data into the user space buffer, and the user process writes it into a file.

My problem is how to synchronize the data. I started using kfifo an in kernel implementation for fifo. So wherever I want to log I use the kfifo API for copying data into the fifo. The virtual device driver reads from the fifo and copies it into user space. Since the data being logged is huge I need synchronization such as in producer consumer. Is there any such support in linux kernel which I can use?

Does netlink socket solve such a problem??

share|improve this question
add comment

3 Answers

You might want to use the relay interface, see Documentation/filesystems/relay.txt.

share|improve this answer
add comment

I think netlink sockets will serve your purpose better than char device. kernel will write to socket whenever it wants to write and your user program which will be waiting on this socket will read from it and write it to file.

Also if you are just trying to log something from kernel for getting some information and not writing a module or making changes to linux kernel for production use then opening and writing files from within the kernel is simpler and faster (as in development time).

share|improve this answer
add comment

You can also use simple double buffering principles, if you have lot of data to log and dont want to miss any log data.

I am not sure about kfifo, but in your character device driver's read calls, you can put the userspace process to sleep if there is no data to be read from the device. And whenever the kernel writes to the character device, it could wake up any processes sleeping on the device. For e.g.

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))
           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.
  logbufstruct->kbuf = kmalloc or whatever way you have to allocate
   space for holding log messages in memory.
share|improve this answer
add comment

Your Answer


