The Gluster Blog

Gluster blog stories provide high-level spotlights on our users all over the world

Play with libgfapi and its python bindings..

April 10, 2014

What is libgfapi ?

User-space library for accessing data in GlusterFS
Filesystem-like API
Runs in application process
no FUSE, no copies, no context switches
…but same volfiles, translators, etc.
Could be used for Apache/nginx modules, MPI I/O
(maybe), Ganesha, etc. ad infinitum
BTW it’s usable from Python too :)

Yes, I copied it from

libgfapi improves gluster performance by avoiding “fuse” layer. Its a different route to access glusterfs data. Imagine that, libgfapi sits in the application layer. Different bindings are available to access libgfapi.

In this article, I will introduce the python bindings of libgfapi.

The libgfapi python binding is available on GitHub, with a mirror on the Gluster Forge:

1) First of all, clone the git repo:

    $ git clone
    $ cd libgfapi-python

2) Then run the setup script:

    $ sudo python install

Once its done, you are almost done with the dev environment :)

Now its really easy to use the functions provided by libgfapi. Let me mention some of the gluster functions available through the python bindings:

glfs_discard(self.fd, offset, len)
glfs_fallocate(self.fd, mode, offset, len)
glfs_fchown(self.fd, uid, gid)
glfs_fstat(self.fd, ctypes.byref(s))
glfs_read(self.fd, rbuf, buflen, flags)
glfs_write(self.fd, buf, len(buf))
glfs_readdir_r(self.fd, ctypes.byref(entry),
gfs_set_volfile_server(self.fs, proto, host, port)
glfs_set_logging(self.fs, path, level)
glfs_chown(self.fs, path, uid, gid)
glfs_getxattr(self.fs, path, key, buf, maxlen)
glfs_listxattr(self.fs, path, buf, 512)
glfs_lstat(self.fs, path, ctypes.byref(s))
glfs_mkdir(self.fs, path, mode)
glfs_creat(self.fs, path, flags, mode)
glfs_open(self.fs, path, flags)
glfs_opendir(self.fs, path)
glfs_removexattr(self.fs, path, key)
glfs_rename(self.fs, opath, npath)
glfs_rmdir(self.fs, path)
glfs_setxattr(self.fs, path, key, value, vlen, 0)
glfs_stat(self.fs, path, ctypes.byref(s))
glfs_statvfs(self.fs, path, ctypes.byref(s))  --------------> [1]
glfs_symlink(self.fs, source, link_name)
glfs_unlink(self.fs, path)

The Libgfapi functions available through the bindings are:

    def close(self):
    def discard(self, offset, len):
    def dup(self):
    def fallocate(self, mode, offset, len):
    def fchown(self, uid, gid):
    def fdatasync(self):
    def fstat(self):
    def fsync(self):
    def lseek(self, pos, how):
    def read(self, buflen, flags=0):
    def write(self, data):
    def next(self):
    def set_logging(self, path, level):
    def mount(self):
    def chown(self, path, uid, gid):
    def exists(self, path):
    def getatime(self, path):
    def getctime(self, path):
    def getmtime(self, path):
    def getsize(self, filename):
    def getxattr(self, path, key, maxlen):
    def isdir(self, path):
    def isfile(self, path):
    def islink(self, path):
    def listdir(self, path):
    def listxattr(self, path):
    def lstat(self, path):
    def makedirs(self, name, mode):
    def mkdir(self, path, mode):
    def open(self, path, flags, mode=0777):
    def opendir(self, path):
    def removexattr(self, path, key):
    def rename(self, opath, npath):
    def rmdir(self, path):
    def rmtree(self, path, ignore_errors=False, onerror=None):
    def setxattr(self, path, key, value, vlen):
    def stat(self, path):
    def statvfs(self, path): -------------------------------->[1]
    def symlink(self, source, link_name):
    def unlink(self, path):
    def walk(self, top, topdown=True, onerror=None, followlinks=False):

[1] The patch ( ) for “statvfs” is not merged as of now , :)

I have a gluster setup where I created a distributed volume called “vol2″ :

Volume Name: vol2
Type: Distribute
Volume ID: d355c575-d345-4e54-a7f1-d77b1bfebaf9
Status: Stopped
Number of Bricks: 1
Transport-type: tcp
Options Reconfigured:
server.allow-insecure: on

Lets start accessing this volume using Python. To use the gfapi binding, you need to import gfapi as shown below:

>>> from glusterfs import gfapi

Once it’s done, you access the volume with the mount() method like this:

>>> myVol = gfapi.Volume("10.X.X.152","vol2")
>>> myVol_init = myVol.mount()
>>> myVol_init

“10.X.X.152″ is my gluster server and “vol2″ is the volume name:

The mount() method basically initialises the connection to the volume.

These are the methods available for the Volume object:

>>> dir(myVol)
['__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_api', 'chown', 'exists', 'fs', 'getsize', 'getxattr', 'isdir', 'isfile', 'islink', 'listdir', 'listxattr', 'lstat', 'makedirs', 'mkdir', 'mount', 'open', 'opendir', 'removexattr', 'rename', 'rmdir', 'rmtree', 'set_logging', 'setxattr', 'stat', 'statvfs', 'symlink', 'unlink', 'walk']

Lets create some entries in this volume and check further:

[root@ ~]# mount -t glusterfs /hum
[root@ ~]# cd /hum/
[root@ hum]# dd if=/dev/random of=file1 bs=1M count=5
0+5 records in
0+5 records out
54 bytes (54 B) copied, 11.6826 s, 0.0 kB/s
[root@n hum]# 

This created a 5M file called “file1″ inside “vol2″ volume.

To list the files and directories inside the volume, we use the listdir() method:

>>> myVol.listdir("/")

Running a “stat” on the file, from the server, shows this information:

[root@ hum]# stat file1
  File: `file1'
  Size: 54        	Blocks: 1          IO Block: 131072 regular file
Device: 1fh/31d	Inode: 9316719741945628140  Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2014-04-09 19:16:10.209995591 +0530
Modify: 2014-04-09 18:05:00.719006150 +0530
Change: 2014-04-09 18:05:00.719006150 +0530
[root@ hum]# 

Lets prove the python binding works :)

>>> myVol.stat("file1").st_ino
>>> myVol.stat("file1").st_size

If I want to list the extended attributes, I can try something like:

>>> myVol.listxattr("/")

Lets create a directory called “humble”:

>>> myVol.mkdir("humble/", 0775)

Checking on the server using ls, it should be there:

[root@ hum]# ls
file1  humble
[root@ hum]# 

Success! For fun, some ‘stat’ information can be displayed using these methods:

>>> myVol.statvfs("/").f_bavail

>>> myVol.statvfs("/").f_bfree
>>> myVol.statvfs("/").f_files

If you want to mount a gluster volume as a non-root user, you need to follow the steps below.
By default, gluster allows client connections only from privileged ports. To enable connections from unprivileged ports you have to follow below steps.

1. Turn on the allow-insecure option for the volume:

       gluster volume set <volume_name> allow-insecure on

2. Edit /etc/glusterfs/glusterd.vol, adding the line:

       option rpc-auth-allow-insecure on

3. Obviously you should have the permissions on the directory you are accessing for non-root access

4. Start and stop volume


  • 26 Apr 2019
    Gluster Monthly Newsletter, April 2...

    Upcoming Community Happy Hour at Red Hat Summit! Tue, May 7, 2019, 6:30 PM – 7:30 PM EDT has all the details. Gluster 7 Roadmap Discussion kicked off for our 7 roadmap on the mailing lists, see [Gluster-users] GlusterFS v7.0 (and v8.0) roadmap discussion for more details. Community...

    Read more
  • 24 Apr 2019
    Community Survey Feedback, 2019

    In this year’s survey, we asked quite a few questions about how people are using Gluster, how much storage they’re managing, their primary use for Gluster, and what they’d like to see added. Here’s some of the highlights from this year!

    Read more
  • 24 Apr 2019
    How to Deploy the OpenVPN Encryptio...

    This is part of a new series on using Gluster! OpenVPN is open source software that serves as the basis for a Virtual Private Network capable of supporting a point-to-point or site-to-site connection. Along with the fact that it’s free to use, it also has the benefit of being one...

    Read more