summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xapi/examples/getvolfile.py43
-rw-r--r--api/src/glfs-mgmt.c4
-rw-r--r--api/src/glfs.c20
-rw-r--r--api/src/glfs.h30
4 files changed, 97 insertions, 0 deletions
diff --git a/api/examples/getvolfile.py b/api/examples/getvolfile.py
new file mode 100755
index 00000000000..82d9db05510
--- /dev/null
+++ b/api/examples/getvolfile.py
@@ -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
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c
index afb351da03a..7f62fa259af 100644
--- a/api/src/glfs-mgmt.c
+++ b/api/src/glfs-mgmt.c
@@ -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;
}
diff --git a/api/src/glfs.c b/api/src/glfs.c
index ea10fb55c65..9e9a55ccb65 100644
--- a/api/src/glfs.c
+++ b/api/src/glfs.c
@@ -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;
+}
diff --git a/api/src/glfs.h b/api/src/glfs.h
index 20fb18c9ecf..af6b4899037 100644
--- a/api/src/glfs.h
+++ b/api/src/glfs.h
@@ -253,6 +253,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
*
* What follows are filesystem operations performed on the