硬盘数据恢复导航
RAID数据恢复导航
 | 网站首页 | 数据恢复资料 | 数据恢复软件 | 咨询留言 | 数据恢复博客 | 数据恢复论坛 | 
数据恢复软件下载
公司简介 数据恢复成功案例 数据恢复报价 数据恢复培训 数据恢复技术文章 数据恢复客服中心 数据恢复服务联系方式
您现在的位置: 北亚数据恢复技术站 >> 数据恢复资料 >> UNIX及LINUX文栏 >> 文章正文
Linux数据传输技术Relay的原理及实例 (2)          【字体:
Linux数据传输技术Relay的原理及实例 (2)
作者:佚名    文章来源:互联网    点击数:    更新时间:2007-3-7

面向内核空间的 API

这些API接口向位于内核空间的用户提供了管理relay通道、数据写入等功能。下面介绍其中主要的部分,完整的API接口列表请参见这里。

●relay_open() - 创建一个relay通道,包括创建每个CPU对应的relay缓冲区。

●relay_close() - 关闭一个relay通道,包括释放所有的relay缓冲区,在此之前会调用relay_switch()来处理这些relay缓冲区以保证已读取但是未满的数据不会丢失

●relay_write() - 将数据写入到当前CPU对应的relay缓冲区内。由于它使用了local_irqsave()保护,因此也可以在中断上下文中使用。

●relay_reserve() - 在relay通道中保留一块连续的区域来留给未来的写入操作。这通常用于那些希望直接写入到relay缓冲区的用户。考虑到性能或者其它因素,这些用户不希望先把数据写到一个临时缓冲区中,然后再通过relay_write()进行写入。

Relay的例子

我们用一个最简单的例子来介绍怎么使用Relay。这个例子由两部分组成:一部分是位于内核空间将数据写入relay文件的程序,使用时需要作为一个内核模块被加载;另一部分是位于用户空间从relay文件中读取数据的程序,使用时作为普通用户态程序运行。

内核空间的程序主要操作是:

加载模块时,打开一个relay通道,并且往打开的relay通道中写入消息;

卸载模块时,关闭relay通道。

程序内容:


/*

* hello-mod.c

* a kernel-space client example of relayfs filesystem

*/

#include

#include

static struct rchan *hello_rchan;

int init_module(void)

{

const char *msg="Hello world\n";

hello_rchan = relay_open("cpu", NULL, 8192, 2, NULL);

if(!hello_rchan){

printk("relay_open() failed.\n");

return -ENOMEM;

}

relay_write(hello_rchan, msg, strlen(msg));

return 0;

}

void cleanup_module(void)

{

if(hello_rchan) {

relay_close(hello_rchan);

hello_rchan = NULL;

}

return;

}

MODULE_LICENSE ("GPL");

MODULE_DESCRIPTION ("Simple example of Relay");

用户空间的函数主要操作是:

●如果relayfs文件系统还没有被mount,则将其mount到目录/mnt/relay上;

●遍历每一个CPU对应的缓冲文件;

●打开文件;

●读取所有文件内容;

●关闭文件;

●最后,umount掉relay文件系统。

程序内容:


/*

* audience.c

* a user-space client example of relayfs filesystem

*/

#include

#include

#include

#include

#include

#include

#include

#define MAX_BUFLEN 256

const char filename_base[]="/mnt/relay/cpu";

// implement your own get_cputotal() before compilation

static int get_cputotal(void);

int main(void)

{

char filename[128]={0};

char buf[MAX_BUFLEN];

int fd, c, i, bytesread, cputotal = 0;

if(mount("relayfs", "/mnt/relay", "relayfs", 0, NULL)

&& (errno != EBUSY)) {

printf("mount() failed: %s\n", strerror(errno));

return 1;

}

cputotal = get_cputotal();

if(cputotal <= 0) {

printf("invalid cputotal value: %d\n", cputotal);

return 1;

}

for(i=0; i // open per-cpu file

sprintf(filename, "%s%d", filename_base, i);

fd = open(filename, O_RDONLY);

if (fd < 0) {

printf("fopen() failed: %s\n", strerror(errno));

return 1;

}

// read per-cpu file

bytesread = read(fd, buf, MAX_BUFLEN);

while(bytesread > 0) {

buf[bytesread] = '\0';

puts(buf);

bytesread = read(fd, buf, MAX_BUFLEN);

};

// close per-cpu file

if(fd > 0) {

close(fd);

fd = 0;

}

}

if(umount("/mnt/relay") && (errno != EINVAL)) {

printf("umount() failed: %s\n", strerror(errno));

return 1;

}

return 0;

}

上面这个例子给出了使用relay的一个最简单的情形,并没有实际用处,但是形象描述了从用户空间和内核空间两个方面使用relay的基本流程。实际应用中对relay的使用当然要比这复杂得多。更多的例子请参见relay的主页。(T002)

文章录入:飘    责任编辑:飘 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    关于我们 | RAID数据恢复 | 友情链接 | RSS生成 | XML生成 | 文章HTML地图 | 下载HTML地图

    版权所有 北亚数据恢复中心
    全国统一客服电话:4006-505-808
    北京市海淀区永丰基地丰慧中路7号新材料创业大厦B座205室
    京ICP备05011939
    *