diff options
| -rw-r--r-- | api/src/glfs-internal.h | 4 | ||||
| -rw-r--r-- | api/src/glfs-mgmt.c | 250 | ||||
| -rw-r--r-- | api/src/glfs.h | 32 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 8 | ||||
| -rw-r--r-- | rpc/xdr/src/glusterfs3-xdr.c | 79 | ||||
| -rw-r--r-- | rpc/xdr/src/glusterfs3-xdr.h | 56 | ||||
| -rw-r--r-- | rpc/xdr/src/glusterfs3-xdr.x | 10 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handshake.c | 137 | 
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},  };  | 
