summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/src/glfs-internal.h4
-rw-r--r--api/src/glfs-mgmt.c258
-rw-r--r--api/src/glfs.h32
-rw-r--r--configure.ac4
-rw-r--r--rpc/rpc-lib/src/protocol-common.h8
-rw-r--r--rpc/xdr/src/glusterfs3-xdr.x10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c137
7 files changed, 445 insertions, 8 deletions
diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h
index 14e94e2..6fdec96 100644
--- a/api/src/glfs-internal.h
+++ b/api/src/glfs-internal.h
@@ -80,6 +80,7 @@ typedef int (*glfs_init_cbk) (struct glfs *fs, int ret);
struct glfs {
char *volname;
+ uuid_t vol_uuid;
glusterfs_ctx_t *ctx;
@@ -222,4 +223,7 @@ dict_t * dict_for_key_value (const char *name, const char *value, size_t size);
int glfs_getxattr_process (void *value, size_t size, dict_t *xattr,
const char *name);
+/* Sends RPC call to glusterd to fetch required volume info */
+int glfs_get_volume_info (struct glfs *fs);
+
#endif /* !_GLFS_INTERNAL_H */
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c
index 5c7e8b2..bb82dc9 100644
--- a/api/src/glfs-mgmt.c
+++ b/api/src/glfs-mgmt.c
@@ -22,6 +22,7 @@
#endif /* _CONFIG_H */
#include "glusterfs.h"
+#include "glfs.h"
#include "stack.h"
#include "dict.h"
#include "event.h"
@@ -40,8 +41,9 @@
#include "glfs-internal.h"
#include "glfs-mem-types.h"
-
int glfs_volfile_fetch (struct glfs *fs);
+int32_t glfs_get_volume_info_rpc (call_frame_t *frame, xlator_t *this,
+ struct glfs *fs);
int
glfs_process_volfp (struct glfs *fs, FILE *fp)
@@ -136,6 +138,7 @@ char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
[GF_HNDSK_GETSPEC] = "GETSPEC",
[GF_HNDSK_PING] = "PING",
[GF_HNDSK_EVENT_NOTIFY] = "EVENTNOTIFY",
+ [GF_HNDSK_GET_VOLUME_INFO] = "GETVOLUMEINFO",
};
rpc_clnt_prog_t clnt_handshake_prog = {
@@ -202,6 +205,249 @@ out:
return ret;
}
+/*
+ * Callback routine for 'GF_HNDSK_GET_VOLUME_INFO' rpc request
+ */
+int
+mgmt_get_volinfo_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ int ret = 0;
+ char *volume_id_str = NULL;
+ dict_t *dict = NULL;
+ char key[1024] = {0};
+ gf_get_volume_info_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ struct glfs *fs = NULL;
+ struct syncargs *args;
+
+ frame = myframe;
+ ctx = frame->this->ctx;
+ args = frame->local;
+
+ if (!ctx) {
+ gf_log (frame->this->name, GF_LOG_ERROR, "NULL context");
+ errno = EINVAL;
+ ret = -1;
+ goto out;
+ }
+
+ fs = ((xlator_t *)ctx->master)->private;
+
+ if (-1 == req->rpc_status) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "GET_VOLUME_INFO RPC call is not successfull");
+ errno = EINVAL;
+ ret = -1;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_get_volume_info_rsp);
+
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "Failed to decode xdr response for GET_VOLUME_INFO");
+ goto out;
+ }
+
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "Received resp to GET_VOLUME_INFO RPC: %d", rsp.op_ret);
+
+ if (rsp.op_ret == -1) {
+ errno = rsp.op_errno;
+ ret = -1;
+ goto out;
+ }
+
+ if (!rsp.dict.dict_len) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "Response received for GET_VOLUME_INFO RPC call is not valid");
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ dict = dict_new ();
+
+ if (!dict) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &dict);
+
+ if (ret) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ snprintf (key, sizeof (key), "volume_id");
+ ret = dict_get_str (dict, key, &volume_id_str);
+ if (ret) {
+ errno = EINVAL;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (volume_id_str) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "Volume Id: %s", volume_id_str);
+ pthread_mutex_lock (&fs->mutex);
+ uuid_parse (volume_id_str, fs->vol_uuid);
+ pthread_mutex_unlock (&fs->mutex);
+ }
+
+ if (ret) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "In GET_VOLUME_INFO cbk, received error: %s",
+ strerror(errno));
+ }
+
+ if (dict)
+ dict_destroy (dict);
+
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
+
+ if (rsp.op_errstr && *rsp.op_errstr)
+ free (rsp.op_errstr);
+
+ gf_log (frame->this->name, GF_LOG_DEBUG, "Returning: %d", ret);
+
+ __wake (args);
+
+ return ret;
+}
+
+int
+glfs_get_volumeid (struct glfs *fs, char *volid, size_t size)
+{
+ /* TODO: Define a global macro to store UUID size */
+ size_t uuid_size = 16;
+
+ pthread_mutex_lock (&fs->mutex);
+ {
+ /* check if the volume uuid is initialized */
+ if (!uuid_is_null (fs->vol_uuid)) {
+ pthread_mutex_unlock (&fs->mutex);
+ goto done;
+ }
+ }
+ pthread_mutex_unlock (&fs->mutex);
+
+ /* Need to fetch volume_uuid */
+ glfs_get_volume_info (fs);
+
+ if (uuid_is_null (fs->vol_uuid)) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Unable to fetch volume UUID");
+ return -1;
+ }
+
+done:
+ if (!volid || !size) {
+ gf_log (THIS->name, GF_LOG_DEBUG, "volumeid/size is null");
+ return uuid_size;
+ }
+
+ if (size < uuid_size) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Insufficient size passed");
+ errno = ERANGE;
+ return -1;
+ }
+
+ memcpy (volid, fs->vol_uuid, uuid_size);
+
+ gf_log (THIS->name, GF_LOG_INFO, "volume uuid: %s", volid);
+
+ return uuid_size;
+}
+
+int
+glfs_get_volume_info (struct glfs *fs)
+{
+ call_frame_t *frame = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ struct syncargs args = {0, };
+ int ret = 0;
+
+ ctx = fs->ctx;
+ frame = create_frame (THIS, ctx->pool);
+ frame->local = &args;
+
+ __yawn ((&args));
+
+ ret = glfs_get_volume_info_rpc (frame, THIS, fs);
+ if (ret)
+ goto out;
+
+ __yield ((&args));
+
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+
+out:
+ return ret;
+}
+
+int32_t
+glfs_get_volume_info_rpc (call_frame_t *frame, xlator_t *this,
+ struct glfs *fs)
+{
+ gf_get_volume_info_req req = {{0,}};
+ int ret = 0;
+ glusterfs_ctx_t *ctx = NULL;
+ dict_t *dict = NULL;
+ int32_t flags = 0;
+
+ if (!frame || !this || !fs) {
+ ret = -1;
+ goto out;
+ }
+
+ ctx = fs->ctx;
+
+ dict = dict_new ();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ if (fs->volname) {
+ ret = dict_set_str (dict, "volname", fs->volname);
+ if (ret)
+ goto out;
+ }
+
+ // Set the flags for the fields which we are interested in
+ flags = (int32_t)GF_GET_VOLUME_UUID; //ctx->flags;
+ ret = dict_set_int32 (dict, "flags", flags);
+ if (ret) {
+ gf_log (frame->this->name, GF_LOG_ERROR, "failed to set flags");
+ goto out;
+ }
+
+ ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+
+
+ ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog,
+ GF_HNDSK_GET_VOLUME_INFO,
+ mgmt_get_volinfo_cbk,
+ (xdrproc_t)xdr_gf_get_volume_info_req);
+out:
+ if (dict) {
+ dict_unref (dict);
+ }
+
+ GF_FREE (req.dict.dict_val);
+
+ return ret;
+}
static int
glusterfs_oldvolfile_update (struct glfs *fs, char *volfile, ssize_t size)
@@ -514,12 +760,12 @@ mgmt_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
/* Exit the process.. there are some wrong options */
gf_log ("glfs-mgmt", GF_LOG_ERROR,
"failed to fetch volume file (key:%s)",
- ctx->cmd_args.volfile_id);
- errno = EINVAL;
- glfs_init_done (fs, -1);
- }
+ ctx->cmd_args.volfile_id);
+ errno = EINVAL;
+ glfs_init_done (fs, -1);
+ }
- break;
+ break;
default:
break;
}
diff --git a/api/src/glfs.h b/api/src/glfs.h
index 4344df2..8f1d09d 100644
--- a/api/src/glfs.h
+++ b/api/src/glfs.h
@@ -285,6 +285,38 @@ int glfs_fini (glfs_t *fs) __THROW;
ssize_t glfs_get_volfile (glfs_t *fs, void *buf, size_t len) __THROW;
+
+/*
+ SYNOPSIS
+
+ glfs_get_volumeid: Copy the Volume UUID stored in the glfs object fs.
+
+ DESCRIPTION
+
+ This function when invoked for the first time sends RPC call to the
+ the management server (glusterd) to fetch volume uuid and stores it
+ in the glusterfs_context linked to the glfs object fs which can be used
+ in the subsequent calls. Later it parses that UUID to convert it from
+ cannonical string format into an opaque byte array and copy it into
+ the volid array. Incase if either of the input parameters, volid or size,
+ is NULL, number of bytes required to copy the volume UUID is returned.
+
+ PARAMETERS
+
+ @fs: The 'virtual mount' object to be used to retrieve and store
+ volume's UUID.
+ @volid: Pointer to a place for the volume UUID to be stored
+ @size: Length of @volid
+
+ RETURN VALUES
+
+ -1 : Failure. @errno will be set with the type of failure.
+ Others : length of the volume UUID stored.
+*/
+
+int glfs_get_volumeid (struct glfs *fs, char *volid, size_t size);
+
+
/*
* FILE OPERATION
*
diff --git a/configure.ac b/configure.ac
index b824cf9..d16bcb1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -995,7 +995,7 @@ AM_CONDITIONAL([GF_DARWIN_HOST_OS], test "${GF_HOST_OS}" = "GF_DARWIN_HOST_OS")
AM_CONDITIONAL([GF_INSTALL_VAR_LIB_GLUSTERD], test ! -d ${localstatedir}/lib/glusterd && test -d ${sysconfdir}/glusterd )
dnl pkg-config versioning
-GFAPI_VERSION="6.0.0"
+GFAPI_VERSION="7.0.0"
LIBGFCHANGELOG_VERSION="0.0.1"
AC_SUBST(GFAPI_VERSION)
AC_SUBST(LIBGFCHANGELOG_VERSION)
@@ -1005,7 +1005,7 @@ LIBGFXDR_LT_VERSION="0:1:0"
LIBGFRPC_LT_VERSION="0:1:0"
LIBGLUSTERFS_LT_VERSION="0:1:0"
LIBGFCHANGELOG_LT_VERSION="0:1:0"
-GFAPI_LT_VERSION="6:0:0"
+GFAPI_LT_VERSION="7:0:0"
AC_SUBST(LIBGFXDR_LT_VERSION)
AC_SUBST(LIBGFRPC_LT_VERSION)
AC_SUBST(LIBGLUSTERFS_LT_VERSION)
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
index 02e0d24..00ba2d1 100644
--- a/rpc/rpc-lib/src/protocol-common.h
+++ b/rpc/rpc-lib/src/protocol-common.h
@@ -69,6 +69,7 @@ enum gf_handshake_procnum {
GF_HNDSK_PING,
GF_HNDSK_SET_LK_VER,
GF_HNDSK_EVENT_NOTIFY,
+ GF_HNDSK_GET_VOLUME_INFO,
GF_HNDSK_MAXVALUE,
};
@@ -255,6 +256,13 @@ enum glusterd_mgmt_v3_procnum {
typedef struct gf_gsync_detailed_status_ gf_gsync_status_t;
+enum gf_get_volume_info_type {
+ GF_GET_VOLUME_NONE, /* 0 */
+ GF_GET_VOLUME_UUID
+};
+
+typedef enum gf_get_volume_info_type gf_get_volume_info_type;
+
#define GLUSTER_HNDSK_PROGRAM 14398633 /* Completely random */
#define GLUSTER_HNDSK_VERSION 2 /* 0.0.2 */
diff --git a/rpc/xdr/src/glusterfs3-xdr.x b/rpc/xdr/src/glusterfs3-xdr.x
index 72f528e..b2fa4de 100644
--- a/rpc/xdr/src/glusterfs3-xdr.x
+++ b/rpc/xdr/src/glusterfs3-xdr.x
@@ -653,6 +653,16 @@ struct gfs3_fstat_req {
opaque xdata<>; /* Extra data */
} ;
+ struct gf_get_volume_info_req {
+ opaque dict<>; /* Extra data */
+} ;
+ struct gf_get_volume_info_rsp {
+ int op_ret;
+ int op_errno;
+ string op_errstr<>;
+ opaque dict<>; /* Extra data */
+} ;
+
struct gf_mgmt_hndsk_req {
opaque hndsk<>;
} ;
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index 2b89545..dbaa972 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -1001,10 +1001,147 @@ glusterd_mgmt_hndsk_versions_ack (rpcsvc_request_t *req)
__glusterd_mgmt_hndsk_versions_ack);
}
+int
+__server_get_volume_info (rpcsvc_request_t *req)
+{
+ int ret = -1;
+ int32_t op_errno = ENOENT;
+ gf_get_volume_info_req vol_info_req = {{0,}};
+ gf_get_volume_info_rsp vol_info_rsp = {0,};
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ dict_t *dict = NULL;
+ dict_t *dict_rsp = NULL;
+ char *volume_id_str = NULL;
+ int32_t flags = 0;
+
+ ret = xdr_to_generic (req->msg[0], &vol_info_req,
+ (xdrproc_t)xdr_gf_get_volume_info_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+ gf_log ("glusterd", GF_LOG_INFO, "Received get volume info req");
+
+ if (vol_info_req.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+ if (!dict) {
+ gf_log ("", GF_LOG_WARNING, "Out of Memory");
+ op_errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (vol_info_req.dict.dict_val,
+ vol_info_req.dict.dict_len,
+ &dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ op_errno = -ret;
+ ret = -1;
+ goto out;
+ } else {
+ dict->extra_stdfree = vol_info_req.dict.dict_val;
+ }
+ }
+
+ ret = dict_get_int32 (dict, "flags", &flags);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to get flags");
+ op_errno = -ret;
+ ret = -1;
+ goto out;
+ }
+
+ if (!flags) {
+ //Nothing to query about. Just return success
+ gf_log (THIS->name, GF_LOG_ERROR, "No flags set");
+ ret = 0;
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ op_errno = EINVAL;
+ ret = -1;
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ op_errno = EINVAL;
+ ret = -1;
+ goto out;
+ }
+
+ if (flags | (int32_t)GF_GET_VOLUME_UUID) {
+ volume_id_str = gf_strdup (uuid_utoa (volinfo->volume_id));
+ if (!volume_id_str) {
+ op_errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
+
+ dict_rsp = dict_new ();
+ if (!dict_rsp) {
+ gf_log ("", GF_LOG_WARNING, "Out of Memory");
+ op_errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_dynstr (dict_rsp, "volume_id", volume_id_str);
+ if (ret) {
+ op_errno = -ret;
+ ret = -1;
+ goto out;
+ }
+ }
+ ret = dict_allocate_and_serialize (dict_rsp, &vol_info_rsp.dict.dict_val,
+ &vol_info_rsp.dict.dict_len);
+ if (ret) {
+ op_errno = -ret;
+ ret = -1;
+ goto out;
+ }
+
+out:
+ vol_info_rsp.op_ret = ret;
+ vol_info_rsp.op_errno = op_errno;
+ vol_info_rsp.op_errstr = "";
+ glusterd_submit_reply (req, &vol_info_rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_get_volume_info_rsp);
+ ret = 0;
+
+ if (dict) {
+ dict_unref (dict);
+ }
+
+ if (dict_rsp) {
+ dict_unref (dict_rsp);
+ }
+
+ if (vol_info_rsp.dict.dict_val) {
+ GF_FREE (vol_info_rsp.dict.dict_val);
+ }
+ return ret;
+}
+
+int
+server_get_volume_info (rpcsvc_request_t *req)
+{
+ return glusterd_big_locked_handler (req,
+ __server_get_volume_info);
+}
+
rpcsvc_actor_t gluster_handshake_actors[] = {
[GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, NULL, NULL, 0, DRC_NA},
[GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, DRC_NA},
[GF_HNDSK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_HNDSK_EVENT_NOTIFY, server_event_notify, NULL, 0, DRC_NA},
+ [GF_HNDSK_GET_VOLUME_INFO] = {"GETVOLUMEINFO", GF_HNDSK_GET_VOLUME_INFO, server_get_volume_info, NULL, 0, DRC_NA},
};