One of the known methods to access glusterfs is via fuse module. However, it has some overhead or performance issues because of the number of context switches which need to be performed to complete one i/o transaction as shown below.
To over come this limitation, a new method called ‘libgfapi’ is introduced. libgfapi support is available from GlusterFS-3.4 release.
libgfapi is a userspace library for accessing data in glusterfs. libgfapi library perform IO on gluster volumes directly without FUSE mount. It is a filesystem like api and runs/sits in application process context. libgfapi eliminates the fuse and the kernel vfs layer from the glusterfs volume access. The speed and latency have improved with libgfapi access.
Using libgfapi, various user-space filesystems (like NFS-Ganesha or Samba) or the virtualizer (like QEMU) can interact with GlusterFS which serves as back-end filesystem. Currently below projects integrate with glusterfs using libgfapi interfaces:
* qemu storage layer
* Samba VFS plugin
* NFS-Ganesha
All the APIs in libgfapi make use of `struct glfs` object. This object
contains information about volume name, glusterfs context associated,
subvols in the graph etc which makes it unique for each volume.
For any application to make use of libgfapi, it should typically start
with the below APIs in the following order –
* To create a new glfs object use glfs_new() and it returns glfs_t object:
glfs_t *glfs_new (const char *volname) ;
* On this newly created glfs_t, you need to be either set a volfile path
(glfs_set_volfile) or a volfile server (glfs_set_volfile_server).
In case of failures, the corresponding cleanup routine is
“glfs_unset_volfile_server”
int glfs_set_volfile (glfs_t *fs, const char *volfile);
int glfs_set_volfile_server (glfs_t *fs, const char *transport,const char *host, int port) ;
int glfs_unset_volfile_server (glfs_t *fs, const char *transport,const char *host, int port) ;
* Specify logging parameters using glfs_set_logging():
int glfs_set_logging (glfs_t *fs, const char *logfile, int loglevel) ;
* Initialize the glfs_t object using glfs_init()
int glfs_init (glfs_t *fs) ;
* Incase of failures or to close the connection and destroy glfs_t
object, use glfs_fini().
int glfs_fini (glfs_t *fs) ;
All the fileops are typically divided into below categories
* a) Handle based Operations –
These APIs create/make use of a glfs_object (referred as handles) unique
to each file within a volume.
The structure glfs_object contains inode pointer and gfid.
For example: Since NFS protocol uses file handles to access files, these APIs are
mainly used by NFS-Ganesha server.
Eg:
struct glfs_object *glfs_h_lookupat (struct glfs *fs,
struct glfs_object *parent,
const char *path,
struct stat *stat);
struct glfs_object *glfs_h_creat (struct glfs *fs,
struct glfs_object *parent,
const char *path,
int flags, mode_t mode,
struct stat *sb);
struct glfs_object *glfs_h_mkdir (struct glfs *fs,
struct glfs_object *parent,
const char *path, mode_t flags,
struct stat *sb);
* b) File path/descriptor based Operations –
These APIs make use of file path/descriptor to determine the file on
which it needs to operate on.
For example: Samba uses these APIs for file operations.
Examples of the APIs using file path –
int glfs_chdir (glfs_t *fs, const char *path) ;
char *glfs_realpath (glfs_t *fs, const char *path, char *resolved_path) ;
Once the file is opened, the file-descriptor generated is used for
further operations.
Eg:
int glfs_posix_lock (glfs_fd_t *fd, int cmd, struct flock *flock) ;
glfs_fd_t *glfs_dup (glfs_fd_t *fd) ;
libgfapi bindings :
libgfapi bindings are available for below languages:
– Go
– Java
– python
– Ruby
For more details on these bindings,please refer :
#http://www.gluster.org/community/documentation/index.php/Language_Bindings

