哈尔滨海月数据恢复,技术亚洲领先 设为首页加入收藏RSS订阅
中国区:哈尔滨(总部)郑州福建深圳沈阳合肥大连包头淄博上海广州
    南京杭州嘉兴武汉济南青岛新疆太原
亚太区:印度韩国泰国新加坡马来西亚澳大利亚
Linux
Linux数据传输技术Relay的原理及实例 (2)

  面向内核空间的 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)

 
客户服务 +more
上门服务
服务承诺
异地恢复
收费标准
付款方式
疑难解答
服务特色 +more
·免费检测
·免费提供3天备份
·专业工程师提供服务
·免费清洁送修的介质
·数据恢复前报价,客户确认后工程师开始数据恢复
·数据恢复不成功不收费
·与客户签订保密协议,对客户的数
 据严格保密,整个恢复过程不会对
 客户的原盘有任何的写操作,以确
 保原盘的数据完全

·免费参观恢复全过程

·工程师在线免费咨询

·专业工程师提供服务
服务器数据恢复 点击这里给我发消

息
数据库修复
点击这里给我发

消息
硬盘数据恢复
点击这里给我发消

息