diff options
Diffstat (limited to 'api/src')
| -rw-r--r-- | api/src/glfs-internal.h | 4 | ||||
| -rw-r--r-- | api/src/glfs-mgmt.c | 258 | ||||
| -rw-r--r-- | api/src/glfs.h | 32 | 
3 files changed, 288 insertions, 6 deletions
diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index 14e94e2116f..6fdec961a1c 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 5c7e8b2fc2a..bb82dc9a188 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 4344df24dc7..8f1d09d1094 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   *  | 
