Linux 数据传输技术 Relay 的原理及实例
Relay 是一种从 Linux 内核到用户空间的高效数据传输技术。通过用户定义的 relay
通道,内核空间的程序能够高效、可靠、便捷地将数据传输到用户空间。Relay 特别适用
于内核空间有大量数据需要传输到用户空间的情形,目前已经广泛应用在内核调试工具如
SystemTap 中。本文介绍了 Relay 的历史和原理,并且用一个简单的实例介绍了 Relay
的具体用法。
Relay 要解决的问题
对于任何在内核工作的程序而言,如何把大量的调试信息从内核空间传输到用户空间
都是一个大麻烦,对于运行中的内核更是如此。特别是对于哪些用于调试内核性能的工具,
更是如此。
对于这种大量数据需要在内核中缓存并传输到用户空间需求,很多传统的方法都已到
达了极限,例如内核程序员很熟悉的 printk() 调用。此外,如果不同的内核子系统都开发
自己的缓存和传输代码,造成很大的代码冗余,而且也带来维护上的困难。
这些,都要求开发一套能够高效可靠地将数据从内核空间转发到用户空间的系统,而
且这个系统应该独立于各个调试子系统。这样就诞生了 RelayFS。
Relay 的发展历史
Relay 的前身是 RelayFS,即作为 Linux 的一个新型文件系统。2003 年 3 月,
RelayFS 的第一个版本的代码被开发出来,在 7 月 14 日,第一个针对 2.6 内核的版本也
开始提供下载。经过广泛 的试用和改进,直到 2005 年 9 月,RelayFS 才被加入
mainline 内核(2.6.14)。同时,RelayFS 也被移植到 2.4 内核中。在 2006 年 2 月,从
2.6.17 开始,RelayFS 不再作为单独的文件系统存在,而是成为内核的一部分。它的源
码也从 fs/目录下转移到 kernel/relay.c 中,名称中也从 RelayFS 改成了 Relay。
RelayFS 目前已经被越来越多的内核工具使用,包括内核调试工具
SystemTap、LTT,以及一些特殊的文件系统例如 DebugFS。
Relay 的基本原理
总的说来,Relay 提供了一种机制,使得内核空间的程序能够通过用户定义的 relay
通道(channel)将大量数据高效的传输到用户空间。
一 个 relay 通道由一组和 CPU 一一对应的内核缓冲区组成。这些缓冲区又被称为
relay 缓冲区(bu+er),其中的每一个在用户空间都用一个常规文 件来表示,这被叫做
relay 文件(,le)。内核空间的用户可以利用 relay 提供的 API 接口来写入数据,这些数据
会被自动的写入当前的 CPU id 对应的那个 relay 缓冲区;同时,这些缓冲区从用户空间
看来,是一组普通文件,可以直接使用 read()进行读取,也可以使用 mmap()进行映 射。
Relay 并不关心数据的格式和内容,这些完全依赖于使用 relay 的用户程序。Relay 的目
的是提供一个足够简单的接口,从而使得基本操作尽可能 的高效。