relay – linux kernel relay filesystem

Relay (Relay filesystem) is a mechanisim used to transfer the data from the kernel space to the user space within the Linux OS. The advantage of relay comparing with other means like debugfs or proc is its ability to handle the big data efficiently. This post will show an example of relay using kernel 3.9.6. May it help.

1. relay

http://relayfs.sourceforge.net/

2. kernel doc for relay

https://www.kernel.org/doc/Documentation/filesystems/relay.txt

3. relayArp

relayArp.c under km is the kernel module used to pop up 2 ARP msgs from the kernel space to the user space; relayArp_us.c under us is the user-space programe used to read and decode the 2 ARP msgs from the kernel. All the code could be found in github below. Only key points and running results are listed here for the reference.

/*
 * create_buf_file() callback.  Creates relay file in debugfs.
 */
static struct dentry *create_buf_file_handler(const char *filename,
                                              struct dentry *parent,
                                              int mode,
                                              struct rchan_buf *buf,
                                              int *is_global)
{
        return debugfs_create_file(filename, mode, parent, buf,
                                   &relay_file_operations);
}

/*
 * remove_buf_file() callback.  Removes relay file from debugfs.
 */
static int remove_buf_file_handler(struct dentry *dentry)
{
        debugfs_remove(dentry);

        return 0;
}

/*
 * relay interface callbacks
 */
static struct rchan_callbacks relay_callbacks =
{
        .create_buf_file = create_buf_file_handler,
        .remove_buf_file = remove_buf_file_handler,
};

—————————————————————-

  /* Open the channel */
        global_rchan = relay_open(“cpu_arp”, NULL, 8192, 2, &relay_callbacks, NULL);
        if (global_rchan == NULL)
        {
                printk(KERN_ERR “relay_open failuren”);
                return -ENOMEM;
        }

        /* Write to the channel – no return value for relay_write */
        relay_write(global_rchan, &arp_msg, sizeof(arp_msg));

[root@daveti debug]# pwd
/sys/kernel/debug
[root@daveti debug]# ll
total 0
drwxr-xr-x.  2 root root 0 Jun 28 09:42 acpi
drwxr-xr-x. 19 root root 0 Jun 28 09:42 bdi
drwxr-xr-x.  2 root root 0 Jun 28 09:42 bluetooth
drwxr-xr-x.  3 root root 0 Jun 28 09:42 boot_params
drwxr-xr-x.  2 root root 0 Jun 28 09:42 cleancache
-r——–.  1 root root 0 Jun 28 10:41 cpu_arp0
-r——–.  1 root root 0 Jun 28 10:41 cpu_arp1
-r——–.  1 root root 0 Jun 28 10:41 cpu_arp2
-r——–.  1 root root 0 Jun 28 10:41 cpu_arp3
drwxr-xr-x.  2 root root 0 Jun 28 09:42 cxgb4
drwxr-xr-x.  4 root root 0 Jun 28 09:42 dri
drwxr-xr-x.  2 root root 0 Jun 28 09:42 dynamic_debug
drwxr-xr-x.  2 root root 0 Jun 28 09:42 extfrag
drwxr-xr-x.  2 root root 0 Jun 28 09:42 frontswap
drwxr-xr-x.  4 root root 0 Jun 28 09:42 hid
drwxr-xr-x.  2 root root 0 Jun 28 09:42 kprobes
drwxr-xr-x.  2 root root 0 Jun 28 09:42 kvm
drwxr-xr-x.  2 root root 0 Jun 28 09:42 mce
drwxr-xr-x.  2 root root 0 Jun 28 09:42 regmap
-rw-r–r–.  1 root root 0 Jun 28 09:42 sched_features
-r–r–r–.  1 root root 0 Jun 28 09:42 suspend_stats
drwxr-xr-x.  6 root root 0 Jun 28 09:42 tracing
drwxr-xr-x.  4 root root 0 Jun 28 09:42 usb
drwxr-xr-x.  2 root root 0 Jun 28 09:42 virtio-ports
-r–r–r–.  1 root root 0 Jun 28 09:42 wakeup_sources
drwxr-xr-x.  2 root root 0 Jun 28 09:42 x86
drwxr-xr-x.  3 root root 0 Jun 28 09:42 xen
[root@daveti debug]# cat cpu_arp0
[root@daveti debug]# cat cpu_arp1
[root@daveti debug]# cat cpu_arp2
€Id
H

€Id
HIx!!#

[root@daveti debug]# cat cpu_arp3
[root@daveti us]# ./relayArp_us
ptr[0] = 0x0
ptr[1] = 0x1
ptr[2] = 0x80
ptr[3] = 0x0
ptr[4] = 0x6
ptr[5] = 0x4
ptr[6] = 0x0
ptr[7] = 0x1
ptr[8] = 0x49
ptr[9] = 0x72
ptr[10] = 0x16
ptr[11] = 0x8
ptr[12] = 0x64
ptr[13] = 0x14
ptr[14] = 0x81
ptr[15] = 0x19
ptr[16] = 0xa
ptr[17] = 0x48
ptr[18] = 0x0
ptr[19] = 0x0
ptr[20] = 0x0
ptr[21] = 0x0
ptr[22] = 0x0
ptr[23] = 0x0
ptr[24] = 0x81
ptr[25] = 0x19
ptr[26] = 0xa
ptr[27] = 0xb
ptr[0] = 0x0
ptr[1] = 0x1
ptr[2] = 0x80
ptr[3] = 0x0
ptr[4] = 0x6
ptr[5] = 0x4
ptr[6] = 0x0
ptr[7] = 0x2
ptr[8] = 0x49
ptr[9] = 0x72
ptr[10] = 0x16
ptr[11] = 0x8
ptr[12] = 0x64
ptr[13] = 0x14
ptr[14] = 0x81
ptr[15] = 0x19
ptr[16] = 0xa
ptr[17] = 0x48
ptr[18] = 0x49
ptr[19] = 0x78
ptr[20] = 0x21
ptr[21] = 0x21
ptr[22] = 0x23
ptr[23] = 0x90
ptr[24] = 0x81
ptr[25] = 0x19
ptr[26] = 0xa
ptr[27] = 0xb
[root@daveti us]# ./relayArp_us
open failure for file /sys/kernel/debug/cpu_arp0: No such file or directory
open failure for file /sys/kernel/debug/cpu_arp1: No such file or directory
open failure for file /sys/kernel/debug/cpu_arp2: No such file or directory
open failure for file /sys/kernel/debug/cpu_arp3: No such file or directory
[root@daveti us]#

Project Name: relayArp
Destination: Linux kernel relay example with ARP msg
Language: C
IDE: Vim
Library:
Project Web: https://github.com/daveti/relayArp
Git Read Only: https://github.com/daveti/relayArp.git

About daveti

Interested in kernel hacking, compilers, machine learning and guitars.
This entry was posted in OS, Programming and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s