Originally published on the old depletionmode / 2of1 blog (archived copy).
UPDATE: See comments
Linux purists are going to go crazy at this, but I was looking for a way to write to the kernel ring buffer (read by dmesg) from a userspace script.
I’m not going to debate the ‘whys’ – but in short I like having my sys logs for automated system actions (some which are userspace-launched) in one neat place.
I’m not sure if anyone else will find a use for this, but here’s the very small kernel module I wrote to do the job. At the very least it can serve as an example of how to write a kernel module and create a /proc entry:
/*
* userspace-krb linux kernel module
* (C) 2010, David Kaplan <david@2of1.org>
*
* Module to allow writing to the kernel ring buffer from userspace
*
*/
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
MODULE_LICENSE( "GPL" );
MODULE_DESCRIPTION( "Interface for userspace writing to kernel ring buffer" );
MODULE_AUTHOR( "David Kaplan");
static struct proc_dir_entry *proc_entry;
int krb_write( struct file *fp, const char __user *buf,
unsigned long len, void *data )
{
int res = len;
char *msg = kmalloc( len + 1, GFP_ATOMIC );
msg[len] = 0; /* force \0 termination */
if ( copy_from_user( msg, buf, len ) )
res = -EFAULT;
else
printk( KERN_INFO "%s", msg );
kfree( msg );
return res;
}
int krb_init()
{
if ( ( proc_entry = create_proc_entry( "krb", 0222, NULL ) ) ) {
proc_entry->write_proc = krb_write;
printk( KERN_INFO "userspace-krb: module loaded.\n" );
printk( KERN_INFO "userspace-krb: proc entry 'krb' created.\n" );
return 0;
}
printk( KERN_INFO "userspace-krb: could not create proc entry!\n" );
return -ENOMEM;
}
void krb_exit()
{
remove_proc_entry( "krb", NULL );
printk( KERN_INFO "userspace-krb: module unloaded.\n" );
}
module_init( krb_init );
module_exit( krb_exit );I probably should have checked to make sure that memory for the msg buffer has been allocated correctly but I couldn’t be bothered. ![]()
You can also view the latest code, Makefile, etc. in the git repo.
This is how it works:
$ make -C /usr/src/linux-headers-`uname -r` SUBDIRS=`pwd` modules
make: Entering directory `/usr/src/linux-headers-2.6.35-22-generic'
CC [M] /home/dk/code/userspace-krb/userspace-krb.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/dk/code/userspace-krb/userspace-krb.mod.o
LD [M] /home/dk/code/userspace-krb/userspace-krb.ko
make: Leaving directory `/usr/src/linux-headers-2.6.35-22-generic'
$ sudo insmod userspace-krb.ko
$ sudo dmesg -c | grep userspace-krb
[86826.875656] userspace-krb: module loaded.
[86826.875658] userspace-krb: proc entry' krb' created.
$ sudo echo "This is written from userspace..." > /proc/krb
$ sudo dmesg -c
[86894.116469] This is written from userspace...