summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/src/glfs-internal.h4
-rw-r--r--api/src/glfs-mgmt.c250
-rw-r--r--api/src/glfs.h32
-rw-r--r--rpc/rpc-lib/src/protocol-common.h8
-rw-r--r--rpc/xdr/src/glusterfs3-xdr.c79
-rw-r--r--rpc/xdr/src/glusterfs3-xdr.h56
-rw-r--r--rpc/xdr/src/glusterfs3-xdr.x10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c137
8 files changed, 530 insertions, 46 deletions
diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h
index ec1d5579df7..6ed4aeae16f 100644
--- a/api/src/glfs-internal.h
+++ b/api/src/glfs-internal.h
@@ -60,6 +60,7 @@ typedef int (*glfs_init_cbk) (struct glfs *fs, int ret);
struct glfs {
char *volname;
+ uuid_t vol_uuid;
glusterfs_ctx_t *ctx;
@@ -197,4 +198,7 @@ void glfs_iatt_to_stat (struct glfs *fs, struct iatt *iatt, struct stat *stat);
int glfs_loc_link (loc_t *loc, struct iatt *iatt);
int glfs_loc_unlink (loc_t *loc);
+/* 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 5493e89db81..2557186ebd8 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"
@@ -39,8 +40,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)
@@ -135,6 +137,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 = {
@@ -201,6 +204,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)
@@ -502,7 +748,7 @@ mgmt_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
glfs_init_done (fs, -1);
}
- break;
+ break;
default:
break;
}
diff --git a/api/src/glfs.h b/api/src/glfs.h
index 2210c26d34f..964422aab72 100644
--- a/api/src/glfs.h
+++ b/api/src/glfs.h
@@ -257,6 +257,38 @@ int glfs_init (glfs_t *fs);
int glfs_fini (glfs_t *fs);
+
+/*
+ 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/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
index 5876a500bdf..d44de48377c 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,
};
@@ -238,6 +239,13 @@ struct gf_gsync_detailed_status_ {
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.c b/rpc/xdr/src/glusterfs3-xdr.c
index 3205c551e5b..45efd860a0d 100644
--- a/rpc/xdr/src/glusterfs3-xdr.c
+++ b/rpc/xdr/src/glusterfs3-xdr.c
@@ -1587,44 +1587,41 @@ xdr_gfs3_discard_rsp (XDR *xdrs, gfs3_discard_rsp *objp)
bool_t
xdr_gfs3_zerofill_req (XDR *xdrs, gfs3_zerofill_req *objp)
{
- register int32_t *buf;
+ register int32_t *buf;
buf = NULL;
- if (!xdr_opaque (xdrs, objp->gfid, 16))
- return FALSE;
- if (!xdr_quad_t (xdrs, &objp->fd))
- return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->offset))
- return FALSE;
- if (!xdr_u_quad_t (xdrs, &objp->size))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val,
- (u_int *) &objp->xdata.xdata_len, ~0))
- return FALSE;
- return TRUE;
+ if (!xdr_opaque (xdrs, objp->gfid, 16))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->fd))
+ return FALSE;
+ if (!xdr_u_quad_t (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_u_quad_t (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
+ return TRUE;
}
bool_t
xdr_gfs3_zerofill_rsp (XDR *xdrs, gfs3_zerofill_rsp *objp)
{
- register int32_t *buf;
+ register int32_t *buf;
buf = NULL;
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_gf_iatt (xdrs, &objp->statpre))
- return FALSE;
- if (!xdr_gf_iatt (xdrs, &objp->statpost))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val,
- (u_int *) &objp->xdata.xdata_len, ~0))
- return FALSE;
- return TRUE;
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+ if (!xdr_gf_iatt (xdrs, &objp->statpre))
+ return FALSE;
+ if (!xdr_gf_iatt (xdrs, &objp->statpost))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->xdata.xdata_val, (u_int *) &objp->xdata.xdata_len, ~0))
+ return FALSE;
+ return TRUE;
}
-
bool_t
xdr_gfs3_rchecksum_req (XDR *xdrs, gfs3_rchecksum_req *objp)
{
@@ -1763,6 +1760,34 @@ xdr_gf_getspec_rsp (XDR *xdrs, gf_getspec_rsp *objp)
}
bool_t
+xdr_gf_get_volume_info_req (XDR *xdrs, gf_get_volume_info_req *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf_get_volume_info_rsp (XDR *xdrs, gf_get_volume_info_rsp *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_gf_mgmt_hndsk_req (XDR *xdrs, gf_mgmt_hndsk_req *objp)
{
register int32_t *buf;
diff --git a/rpc/xdr/src/glusterfs3-xdr.h b/rpc/xdr/src/glusterfs3-xdr.h
index 13566e69447..ac74cca5cc1 100644
--- a/rpc/xdr/src/glusterfs3-xdr.h
+++ b/rpc/xdr/src/glusterfs3-xdr.h
@@ -937,30 +937,29 @@ struct gfs3_discard_rsp {
typedef struct gfs3_discard_rsp gfs3_discard_rsp;
struct gfs3_zerofill_req {
- char gfid[16];
- quad_t fd;
- u_quad_t offset;
- u_quad_t size;
- struct {
- u_int xdata_len;
- char *xdata_val;
- } xdata;
+ char gfid[16];
+ quad_t fd;
+ u_quad_t offset;
+ u_quad_t size;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_zerofill_req gfs3_zerofill_req;
struct gfs3_zerofill_rsp {
- int op_ret;
- int op_errno;
- struct gf_iatt statpre;
- struct gf_iatt statpost;
- struct {
- u_int xdata_len;
- char *xdata_val;
- } xdata;
+ int op_ret;
+ int op_errno;
+ struct gf_iatt statpre;
+ struct gf_iatt statpost;
+ struct {
+ u_int xdata_len;
+ char *xdata_val;
+ } xdata;
};
typedef struct gfs3_zerofill_rsp gfs3_zerofill_rsp;
-
struct gfs3_rchecksum_req {
quad_t fd;
u_quad_t offset;
@@ -1026,6 +1025,25 @@ struct gf_getspec_rsp {
};
typedef struct gf_getspec_rsp gf_getspec_rsp;
+struct gf_get_volume_info_req {
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
+};
+typedef struct gf_get_volume_info_req gf_get_volume_info_req;
+
+struct gf_get_volume_info_rsp {
+ int op_ret;
+ int op_errno;
+ char *op_errstr;
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
+};
+typedef struct gf_get_volume_info_rsp gf_get_volume_info_rsp;
+
struct gf_mgmt_hndsk_req {
struct {
u_int hndsk_len;
@@ -1268,6 +1286,8 @@ extern bool_t xdr_gf_setvolume_req (XDR *, gf_setvolume_req*);
extern bool_t xdr_gf_setvolume_rsp (XDR *, gf_setvolume_rsp*);
extern bool_t xdr_gf_getspec_req (XDR *, gf_getspec_req*);
extern bool_t xdr_gf_getspec_rsp (XDR *, gf_getspec_rsp*);
+extern bool_t xdr_gf_get_volume_info_req (XDR *, gf_get_volume_info_req*);
+extern bool_t xdr_gf_get_volume_info_rsp (XDR *, gf_get_volume_info_rsp*);
extern bool_t xdr_gf_mgmt_hndsk_req (XDR *, gf_mgmt_hndsk_req*);
extern bool_t xdr_gf_mgmt_hndsk_rsp (XDR *, gf_mgmt_hndsk_rsp*);
extern bool_t xdr_gf_log_req (XDR *, gf_log_req*);
@@ -1368,6 +1388,8 @@ extern bool_t xdr_gf_setvolume_req ();
extern bool_t xdr_gf_setvolume_rsp ();
extern bool_t xdr_gf_getspec_req ();
extern bool_t xdr_gf_getspec_rsp ();
+extern bool_t xdr_gf_get_volume_info_req ();
+extern bool_t xdr_gf_get_volume_info_rsp ();
extern bool_t xdr_gf_mgmt_hndsk_req ();
extern bool_t xdr_gf_mgmt_hndsk_rsp ();
extern bool_t xdr_gf_log_req ();
diff --git a/rpc/xdr/src/glusterfs3-xdr.x b/rpc/xdr/src/glusterfs3-xdr.x
index 1edbda3ada9..1c6bf4be244 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 1420eb692ee..87958d0701b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -591,10 +591,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},
};