
从Linux-2.6.14内核(2.6.12需要打补丁,2.6.13的内核手头没有,不知道)开始,relayfs开始成为内核中File System选项中伪文件系统(Pseudo File System)来发生,这是一个新特点。
File System--->
Pseudo filesystems---->
Relayfs File System Support
我们知道,Pseduo File System 另外一个很有名的东西是Proc FileSystem,几乎每位学习Linux的都清楚使用这个文件系统来查看cpu型号,内存容量等等其他众多的runtimeinformation。ProcFS为users提供了一个方便的接口来查询这些只有内核能够查看的信息,比如:cpuinfo,meminfo,interrupts等等,这些都并非kernel管理的对象,但是我们可以以一个普通users的身份也可以查看java linux trace,procFS将内核信息可以动态地释放出去,供普通的process随时查看,某些状况下,用户也可以将信息传递至内核空间,比如:echo1>/proc/sys/net/ipv4/ip_forward。同样地,relayfs也是可以一种内核和客户空间交换数据的软件,不同的是,它支持大容量的数据交换。
relayfs中有一个很重要的概念称作”channel“,具体来说,一个channel就是由这些个内核的buffer组成的一个集合,这些内核的buffer在relayfs中就表现为一个个的文件。当kernel中的程序把数据写入某个channel时,这些数据实际上自动填入这些channel的buffer。用户空间的应用程序mmap()将relayfs中的这种文件做个映射,然后在适度的之后把数据提取下来。
写入channel的数据格式完全取决于最终从channel中提取数据的程序,relayfs可以提取一些hook程序,这些hook程序允许relayfs的数据提取程序(relayfs的客户端)为buffer中的数据提高一些数据结构。这个过程,就像解码和编码的关系一样,你使用的编码程序跟解码程序只有对应就可以,与存储程序无关,当然,你在传输的同时也可以对它进行一些编码,但是这种取决于你最后的解码。但是,relayfs不提供任何手段的数据过滤,这些任务交给relayfs客户端去完成。 relayfs的设计目标就是尽可能地简单。

每一个relayfs channel都有一个buffer(单CPU情况),每一个buffer又有一个或者多个二级buffer。消息是从第一个二级buffer开始写入的,直到这个buffer满为止。然后即使第二个二级buffer可用,就写入第二个二级部分甚至,一次类推。所以,如果第一个二级buffer被填满,那么经常通知客户空间,同时,kernel就会去写第二个二级buffer。
如果kernel发出通知说一个二级buffer被填满了,那么kernel肯定知道填了多少字节。userspace根据这个数字就可以只是拷贝合法的数据。拷贝完毕,userpsace通知kernel说一个二级buffer已经被使用了。
relayfs采用这样一种模式java linux trace,它会直接去覆盖数据仍然很多数据还没有被userspace所收集。(一个问题,如何维持传输的完整性,目前我也不知道)
下面说说relayfs的user space API:
relayfs为了促使空间程序可以访问channel里面的buffer数据,实现了基本的文件操作。文件操作函数如下:
open 打开一个存在的buffer
mmap 可以并且channel的buffer被映射到调用函数的存储空间,注意,你不能部分映射,而是应映射整个文件。

reald 读取channel buffer的内容
poll 通知用户空间程序二级buffer空间已满
close 关闭
为了促使用户空间的程序可以使用relayfs文件,relayfs必须被mount,格式和proc差不多,like this:
mount -t relayfs relayfs /mnt/relay/
下面是kernel空间的一些API:
relay_open(base_filename, parent, subbuf_size, n_subbufs, callbacks)

relay_close(chan)
relay_flush(chan)
relay_reset(chan)
relayfs_create_dir(name, parent)
relayfs_remove_dir(dentry)
relayfs_create_file(name, parent, mode, fops, data)
relayfs_remove_file(dentry)

relay_subbufs_consumed(chan, cpu, subbufs_consumed)
relay_write(chan, data, length)
__relay_write(chan, data, length)
relay_reserve(chan, length)
subbuf_start(buf, subbuf, prev_subbuf, prev_padding)
buf_mapped(buf, filp)
buf_unmapped(buf, filp)
create_buf_file(filename, parent, mode, buf, is_global)
remove_buf_file(dentry)
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-134411-1.html
大家都很现实
什么船撞得过他
此时此刻特别怀念毛主席