diff options
Diffstat (limited to 'plugins/gfapi.py')
-rw-r--r-- | plugins/gfapi.py | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/plugins/gfapi.py b/plugins/gfapi.py new file mode 100644 index 0000000..4df3531 --- /dev/null +++ b/plugins/gfapi.py @@ -0,0 +1,161 @@ +# +# Copyright 2014 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Refer to the README and COPYING files for full details of the license +# +import ctypes +from ctypes.util import find_library +import os + + +GLUSTER_VOL_PROTOCAL = 'tcp' +GLUSTER_VOL_HOST = 'localhost' +GLUSTER_VOL_PORT = 24007 +GLUSTER_VOL_PATH = "/" + + +class GlusterLibgfapiException(Exception): + message = "Gluster Libgfapi Exception" + + def __init__(self, rc=0, err=()): + self.rc = rc + self.err = err + + def __str__(self): + s = self.message + if self.err: + e = '\n'.join(self.err) + s += '\nerror: ' + e + if self.rc: + s += '\nreturn code: %s' % self.rc + return s + + +class GlfsStatvfsException(GlusterLibgfapiException): + message = "Failed to get Gluster volume Size info" + + +class GlfsInitException(GlusterLibgfapiException): + message = "glfs init failed" + + +class GlfsFiniException(GlusterLibgfapiException): + message = "glfs fini failed" + + +class StatVfsStruct(ctypes.Structure): + _fields_ = [ + ('f_bsize', ctypes.c_ulong), + ('f_frsize', ctypes.c_ulong), + ('f_blocks', ctypes.c_ulong), + ('f_bfree', ctypes.c_ulong), + ('f_bavail', ctypes.c_ulong), + ('f_files', ctypes.c_ulong), + ('f_ffree', ctypes.c_ulong), + ('f_favail', ctypes.c_ulong), + ('f_fsid', ctypes.c_ulong), + ('f_flag', ctypes.c_ulong), + ('f_namemax', ctypes.c_ulong), + ('__f_spare', ctypes.c_int * 6), + ] + + +def glfsInit(volumeId, host, port, protocol): + fs = _glfs_new(volumeId) + + rc = _glfs_set_volfile_server(fs, + protocol, + host, + port) + if rc != 0: + raise GlfsInitException( + rc=rc, err=["setting volfile server failed"] + ) + + rc = _glfs_init(fs) + if rc == 0: + return fs + elif rc == 1: + raise GlfsInitException( + rc=rc, err=["Volume:%s is stopped." % volumeId] + ) + elif rc == -1: + raise GlfsInitException( + rc=rc, err=["Volume:%s not found." % volumeId] + ) + else: + raise GlfsInitException(rc=rc, err=["unknown error."]) + + +def glfsFini(fs, volumeId): + rc = _glfs_fini(fs) + if rc != 0: + raise GlfsFiniException(rc=rc) + + +def getVolumeStatvfs(volumeId, host=GLUSTER_VOL_HOST, + port=GLUSTER_VOL_PORT, + protocol=GLUSTER_VOL_PROTOCAL): + statvfsdata = StatVfsStruct() + + fs = glfsInit(volumeId, host, port, protocol) + + rc = _glfs_statvfs(fs, GLUSTER_VOL_PATH, ctypes.byref(statvfsdata)) + if rc != 0: + raise GlfsStatvfsException(rc=rc) + + glfsFini(fs, volumeId) + + # To convert to os.statvfs_result we need to pass tuple/list in + # following order: bsize, frsize, blocks, bfree, bavail, files, + # ffree, favail, flag, namemax + return os.statvfs_result((statvfsdata.f_bsize, + statvfsdata.f_frsize, + statvfsdata.f_blocks, + statvfsdata.f_bfree, + statvfsdata.f_bavail, + statvfsdata.f_files, + statvfsdata.f_ffree, + statvfsdata.f_favail, + statvfsdata.f_flag, + statvfsdata.f_namemax)) + +# C function prototypes for using the library gfapi + +_lib = ctypes.CDLL(find_library("gfapi"), + use_errno=True) + +_glfs_new = ctypes.CFUNCTYPE( + ctypes.c_void_p, ctypes.c_char_p)(('glfs_new', _lib)) + +_glfs_set_volfile_server = ctypes.CFUNCTYPE( + ctypes.c_int, + ctypes.c_void_p, + ctypes.c_char_p, + ctypes.c_char_p, + ctypes.c_int)(('glfs_set_volfile_server', _lib)) + +_glfs_init = ctypes.CFUNCTYPE( + ctypes.c_int, ctypes.c_void_p)(('glfs_init', _lib)) + +_glfs_fini = ctypes.CFUNCTYPE( + ctypes.c_int, ctypes.c_void_p)(('glfs_fini', _lib)) + +_glfs_statvfs = ctypes.CFUNCTYPE(ctypes.c_int, + ctypes.c_void_p, + ctypes.c_char_p, + ctypes.c_void_p)(('glfs_statvfs', _lib)) |