图像
08/17/2016 01:14

     在熟悉了glusterfs的基本原理和操作之后,今天对glusterfs的外部编程接口函数进行了学习,进一步加深了对glusterfs的理解。对glusterfs的使用也有了一些新的想法。查阅网上的资料发现,glusterfsAPI函数库方面的资料很少,于是选择了阅读API的源代码来学习。      

      GlusterFS从3.4版本开始提供了libgfapi接口,通过缩减I/O路径,帮助各种应用进一步提升性能。Libgfapi是一个用户空间的GlusterFS数据访问接口API函数库,可以绕开FUSE挂载点直接访问glusterfs卷,直接在应用程序通过调用API来访问数据。它缩减了FUSE和内核VFS层的I/O访问路径,通过它访问glusterfs卷,性能和latency均可以得到大幅提升。

     Libgfapi中所有的库函数都使用了glfs这一结构体对象,这一对象包含了卷名、上下文及分卷等标签性信息。任何程序在使用libgfapi这一函数库之前都必须先创建一个新的glfs对象:

//glfs_t 为glfs结构体类型。@volname为卷名
glfs_t glfs_new (const char volname) ;
glfs_new函数返回一个新的glfs对象,在这一对象基础上我们还需要调用Libgfapi库函数配置静态的配置文件或者动态设置master节点。


/*  使用配置文件进行静态配置
  @fs: 使用配置文件进行配置的glfs对象
  @volfile: glusterfs配置文件的路径
  返回值 0 : Success. -1 : Failure..
*/
int glfs_set_volfile (glfs_t *fs, const char *volfile) __THROW
        GFAPI_PUBLIC(glfs_set_volfile, 3.4.0);


/**
动态配置volume
  @fs: glfs对象
  @transport: 传输形式 "tcp", "rdma", "unix" 等
  @host: master节点位置.形式可以为:
              - FQDN: storage01.company.com
              - ASCII : 192.168.22.1
              - Socket:/var/run/glusterd.socket
  @port: glusterfs进行监听的TCP端口号。当使用socket传输时此参数不   需要
  返回值 0 : Success.
       -1 : Failure. 
*/
int glfs_set_volfile_server (glfs_t *fs, const char *transport,
                             const char *host, int port) __THROW
        GFAPI_PUBLIC(glfs_set_volfile_server, 3.4.0);

//配置失败后清除已经配置的环境
int glfs_unset_volfile_server (glfs_t fs, const char transport,const char *host, int port) ;

配置完后还需要设置log操作以及对glfs对象进行初始化


/*
@logfile:日志文件
@loglevel:日志等级
*/
int glfs_set_logging (glfs_t fs, const char logfile, int loglevel) ;


//初始化glfs对象
int glfs_init (glfs_t *fs) ;


 当初始化完成之后就可以访问glusterfs系统进行各种操作。Libgfapi提供了超过一百个库函数(详细请参考:https://github.com/gluster/glusterfs/blob/master/api/src/glfs.h),里面涵盖了打开、读/写等与标准POSIX C库函数功能及定义很类似的函数,也有设置组/用户ID、设置权限等针对glusterfs系统的函数。,下面参考网上的资料给出一个简单的C示例程序:


#include <stdio.h>  
#include <stdlib.h>  
#include <errno.h>  
#include "api/glfs.h"  
#include "api/glfs-handles.h"  
#include <string.h>  
#include <time.h>  
  
  
int main (int argc, char *argv[])  
{  
   //glfs_t为glfs对象
    glfs_t *fs2 = NULL;  

    int ret = 0; 
   
   //文件描述指针 
    glfs_fd_t *fd = NULL;  
    glfs_fd_t *fd2 = NULL;  
   
   //读写缓存
    char readbuf[32];  
    char  writebuf[32];  
   //文件名
   char*filename = "/filename2";  
  
   if (argc != 3) {  
   printf ("Expect following args\n\t%s <volname> hostname>\n", argv[0]);  
   return -1;  
   }  
  
/* 初始化gluster环境 */ 
   fs2 = glfs_new (argv[1]);  
   if (!fs2) {  
     fprintf (stderr, "glfs_new: returned NULL\n");  
      return 1;  
    }  
   //配置master节点
   ret = glfs_set_volfile_server (fs2, "tcp", argv[2], 24007);  
   //设置日志信息
   ret = glfs_set_logging (fs2, "/dev/stderr", 1);  
   //进行初始化
   ret = glfs_init (fs2);  
   //打印初始化信息
   fprintf (stderr, "glfs_init: returned %d\n", ret);  
   
   /* 进行libgfapi函数调用 */  
   fd = glfs_creat (fs2, filename, O_RDWR, 0644);  

   fprintf (stderr, "%s: (%p) %s\n", filename, fd, strerror (errno)); 
   
   //打开挂载目录下文件,准备写入
   fd2 = glfs_open (fs2, filename, O_RDWR);  
   fprintf (stderr, "%s: (%p) %s\n", filename, fd, strerror (errno));  
   sprintf (writebuf, "hi there\n");  
   ret = glfs_write (fd, writebuf, 32, 0);  

   //glfs_lseek函数功能与POSIX C库函数相同  
   glfs_lseek (fd2, 0, SEEK_SET);  
   //读取数据至读缓存
   ret = glfs_read (fd2, readbuf, 32, 0);  
   printf ("read %d, %s", ret, readbuf);  

   //读写完成后关闭文件
   glfs_close (fd);  
   glfs_close (fd2);  
  
   //Gluster环境释放,所有程序在完成各项操作后都必须执行的函数   
   glfs_fini (fs2);  
  
   return ret; 
}

     编译时需要指定头文件和库文件路径,并链接libgfapi.so动态库。

     由于时间仓促,对其他glusterfs系统方面的函数并没有理解透彻,在本机上的调试还未成功,仍需进一步学习。


回复 (4)
15712?1471931897
李乾坤 7年前
5?1460204756
尹刚 7年前

我希望通过这类api,能够封装形成一个按照我们的需求提供服务的新系统:TrustieGFS,或者GFS+

TrustieGFS(可以简称TGFS)可以提供一种非常方便的调用接口,如Web接口,为其他应用程序提供其管辖的所有GFS系统的基本操作:如目录管理、文件上传、文件迁移、文件删除等等。

我不太理解trustieGFS的具体设想,但glusterfs官网文档提到,glusterfs实现了函数库Libgfapi与Java的绑定(libgfapi bindings for java),似乎可以在Java开发环境下进行glusterfs的一系列操作,这样的话图形界面、网络等编程可能较为容易。我在github上找到了libgfapi bindings for java的开源项目,看了看,一窍不通,把链接贴出来给老师及各位师兄、同学看一下:

https://github.com/semiosis/libgfapi-jni

https://github.com/semiosis/libgfapi-jni/commit/e4d749e506349126885c3ba52a275e2c4087fd8b

https://github.com/semiosis/libgfapi-jni/blob/master/libgfapi-jni/src/test/java/com/peircean/libgfapi_jni/internal/GlusterOpenOptionTest.java

第一条链接是项目主页,第二第三条是给出的一些测试小程序。

15712?1471931897
李乾坤 7年前
5?1460204756
尹刚 7年前

很好!这是我刚才看到的一个博客,有空也可以参考:Gluster libgfapi接口和应用实例

http://www.tuicool.com/articles/FRnUJ3n


我还有一个问题:这个libgfapi能否获取到gfs系统磁盘的信息?比如目录列表、目录大小、文件列表等?

libgfapi中并没有直接的函数调用可以实现目录列表、目录大小等信息的获取,但是提供了可以通过编程获取这些信息的函数,如glfs_telldir(功能类似于Linux c中函数telldir)、glfs_opendir(功能类似于Linux c函数opendir)、glfs_lstat(类似于Linux c函数lstat)等。从Libgfapi库函数列表来看,基本上可以在Linux下实现的对于文件、磁盘均可在glusterfs虚拟系统下实现。但libgfapi函数库只有很少量函数给出了注释,大部分函数都没有给出任何注释,对其具体使用方法尚未掌握,觉得难度不小,也未进行试验。

© Copyright 2007~2021 国防科技大学Trustie团队 & IntelliDE 湘ICP备 17009477号

问题和建议
还能输入50个字符 Submit

加入QQ群

关注微信APP


×