api: add glfs_get_volfile

From the API-header description:

> Sometimes it's useful e.g. for scripts to see the volfile, so that
> they can parse it and find subvolumes to do things like split-brain
> resolution or custom layouts.  The API here was specifically intended
> to make access e.g. from Python as simple as possible.
>
> Note that the volume must be started (not necessarily mounted) for
> this to work.

Change-Id: If3f55ee9611cdf4b77aa53659f0af0d21957817d
Signed-off-by: Jeff Darcy <jdarcy@redhat.com>
Reviewed-on: http://review.gluster.org/7183
Reviewed-by: Anand Avati <avati@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
This commit is contained in:
Jeff Darcy 2014-03-04 16:53:33 +00:00 committed by Anand Avati
parent d6c1468b27
commit 1fbffa0aa4
4 changed files with 97 additions and 0 deletions

43
api/examples/getvolfile.py Executable file
View File

@ -0,0 +1,43 @@
#!/usr/bin/python
import ctypes
import ctypes.util
api = ctypes.CDLL(ctypes.util.find_library("gfapi"))
api.glfs_get_volfile.argtypes = [ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_ulong]
api.glfs_get_volfile.restype = ctypes.c_long;
def get_volfile (host, volume):
# This is set to a large value to exercise the "buffer not big enough"
# path. More realistically, you'd just start with a huge buffer.
BUF_LEN = 0
fs = api.glfs_new(volume)
#api.glfs_set_logging(fs,"/dev/stderr",7)
api.glfs_set_volfile_server(fs,"tcp",host,24007)
api.glfs_init(fs)
vbuf = ctypes.create_string_buffer(BUF_LEN)
vlen = api.glfs_get_volfile(fs,vbuf,BUF_LEN)
if vlen < 0:
vlen = BUF_LEN - vlen
vbuf = ctypes.create_string_buffer(vlen)
vlen = api.glfs_get_volfile(fs,vbuf,vlen)
api.glfs_fini(fs)
if vlen <= 0:
return vlen
return vbuf.value[:vlen]
if __name__ == "__main__":
import sys
try:
res = apply(get_volfile,sys.argv[1:3])
except:
print "fetching volfile failed (volume not started?)"
try:
for line in res.split('\n'):
print line
except:
print "bad return value %s" % res

View File

@ -207,6 +207,8 @@ glusterfs_oldvolfile_update (struct glfs *fs, char *volfile, ssize_t size)
{
int ret = -1;
pthread_mutex_lock (&fs->mutex);
fs->oldvollen = size;
if (!fs->oldvolfile) {
fs->oldvolfile = GF_CALLOC (1, size+1, glfs_mt_volfile_t);
@ -222,6 +224,8 @@ glusterfs_oldvolfile_update (struct glfs *fs, char *volfile, ssize_t size)
ret = 0;
}
pthread_mutex_unlock (&fs->mutex);
return ret;
}

View File

@ -680,3 +680,23 @@ glfs_fini (struct glfs *fs)
return ret;
}
ssize_t
glfs_get_volfile (struct glfs *fs, void *buf, size_t len)
{
ssize_t res;
glfs_lock(fs);
if (len >= fs->oldvollen) {
gf_log ("glfs", GF_LOG_TRACE, "copying %lu to %p", len, buf);
memcpy(buf,fs->oldvolfile,len);
res = len;
}
else {
res = len - fs->oldvollen;
gf_log ("glfs", GF_LOG_TRACE, "buffer is %ld too short", -res);
}
glfs_unlock(fs);
return res;
}

View File

@ -252,6 +252,36 @@ int glfs_init (glfs_t *fs) __THROW;
int glfs_fini (glfs_t *fs) __THROW;
/*
SYNOPSIS
glfs_getvol: Get the volfile associated with a 'virtual mount'
DESCRIPTION
Sometimes it's useful e.g. for scripts to see the volfile, so that they
can parse it and find subvolumes to do things like split-brain resolution
or custom layouts. The API here was specifically intended to make access
e.g. from Python as simple as possible.
Note that the volume must be started (not necessarily mounted) for this
to work.
PARAMETERS
@fs: The 'virtual mount' object for which a volfile is desired
@buf: Pointer to a place for the volfile length to be stored
@len: Length of @buf
RETURN VALUES
>0: filled N bytes of buffer
0: no volfile available
<0: volfile length exceeds @len by N bytes (@buf unchanged)
*/
ssize_t glfs_get_volfile (glfs_t *fs, void *buf, size_t len) __THROW;
/*
* FILE OPERATION
*