diff options
| -rw-r--r-- | api/src/glfs-mgmt.c | 41 | ||||
| -rw-r--r-- | glusterfsd/src/glusterfsd-mgmt.c | 40 | ||||
| -rw-r--r-- | libglusterfs/src/globals.h | 18 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handshake.c | 72 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 17 | 
5 files changed, 167 insertions, 21 deletions
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c index 2ead93863bc..a76692bfd06 100644 --- a/api/src/glfs-mgmt.c +++ b/api/src/glfs-mgmt.c @@ -477,6 +477,13 @@ out:  	if (rsp.spec)  		free (rsp.spec); +        // Stop if server is running at an unsupported op-version +        if (ENOTSUP == ret) { +                gf_log ("mgmt", GF_LOG_ERROR, "Server is operating at an " +                        "op-version which is not supported"); +                glfs_init_done (fs, -1); +        } +  	if (ret && ctx && !ctx->active) {  		/* Do it only for the first time */  		/* Failed to get the volume file, something wrong, @@ -503,6 +510,7 @@ glfs_volfile_fetch (struct glfs *fs)  	int		  ret = 0;  	call_frame_t	 *frame = NULL;  	glusterfs_ctx_t	 *ctx = NULL; +        dict_t           *dict = NULL;  	ctx = fs->ctx;  	cmd_args = &ctx->cmd_args; @@ -512,10 +520,41 @@ glfs_volfile_fetch (struct glfs *fs)  	req.key = cmd_args->volfile_id;  	req.flags = 0; +        dict = dict_new (); +        if (!dict) { +                ret = -1; +                goto out; +        } + +        // Set the supported min and max op-versions, so glusterd can make a +        // decision +        ret = dict_set_int32 (dict, "min-op-version", GD_OP_VERSION_MIN); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "Failed to set min-op-version" +                        " in request dict"); +                goto out; +        } + +        ret = dict_set_int32 (dict, "max-op-version", GD_OP_VERSION_MAX); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "Failed to set max-op-version" +                        " in request dict"); +                goto out; +        } + +        ret = dict_allocate_and_serialize (dict, &req.xdata.xdata_val, +                                           &req.xdata.xdata_len); +        if (ret < 0) { +                gf_log (THIS->name, GF_LOG_ERROR, +                        "Failed to serialize dictionary"); +                goto out; +        } +  	ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog,  				   GF_HNDSK_GETSPEC, mgmt_getspec_cbk,  				   (xdrproc_t)xdr_gf_getspec_req); -	return ret; +out: +        return ret;  } diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c index 5bebdaf178c..8082ad3d1d4 100644 --- a/glusterfsd/src/glusterfsd-mgmt.c +++ b/glusterfsd/src/glusterfsd-mgmt.c @@ -1639,6 +1639,13 @@ out:          emancipate (ctx, ret); +        // Stop if server is running at an unsupported op-version +        if (ENOTSUP == ret) { +                gf_log ("mgmt", GF_LOG_ERROR, "Server is operating at an " +                        "op-version which is not supported"); +                cleanup_and_exit (0); +        } +          if (ret && ctx && !ctx->active) {                  /* Do it only for the first time */                  /* Failed to get the volume file, something wrong, @@ -1649,6 +1656,7 @@ out:                  cleanup_and_exit (0);          } +          if (tmpfp)                  fclose (tmpfp); @@ -1663,6 +1671,7 @@ glusterfs_volfile_fetch (glusterfs_ctx_t *ctx)          gf_getspec_req    req = {0, };          int               ret = 0;          call_frame_t     *frame = NULL; +        dict_t           *dict = NULL;          cmd_args = &ctx->cmd_args; @@ -1671,9 +1680,40 @@ glusterfs_volfile_fetch (glusterfs_ctx_t *ctx)          req.key = cmd_args->volfile_id;          req.flags = 0; +        dict = dict_new (); +        if (!dict) { +                ret = -1; +                goto out; +        } + +        // Set the supported min and max op-versions, so glusterd can make a +        // decision +        ret = dict_set_int32 (dict, "min-op-version", GD_OP_VERSION_MIN); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "Failed to set min-op-version" +                        " in request dict"); +                goto out; +        } + +        ret = dict_set_int32 (dict, "max-op-version", GD_OP_VERSION_MAX); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "Failed to set max-op-version" +                        " in request dict"); +                goto out; +        } + +        ret = dict_allocate_and_serialize (dict, &req.xdata.xdata_val, +                                           &req.xdata.xdata_len); +        if (ret < 0) { +                gf_log (THIS->name, GF_LOG_ERROR, +                        "Failed to serialize dictionary"); +                goto out; +        } +          ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog,                                     GF_HNDSK_GETSPEC, mgmt_getspec_cbk,                                     (xdrproc_t)xdr_gf_getspec_req); +out:          return ret;  } diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h index e13902b2992..64a1594f5f8 100644 --- a/libglusterfs/src/globals.h +++ b/libglusterfs/src/globals.h @@ -13,6 +13,24 @@  #define GF_DEFAULT_BASE_PORT 24007 +#define GD_OP_VERSION_KEY     "operating-version" +#define GD_MIN_OP_VERSION_KEY "minimum-operating-version" +#define GD_MAX_OP_VERSION_KEY "maximum-operating-version" + +/* Gluster versions - OP-VERSION mapping + * + * 3.3.0                - 1 + * 3.3.Next/3.Next      - 2 + * + * TODO: Change above comment once gluster version is finalised + * TODO: Finalize the op-version ranges + */ +#define GD_OP_VERSION_MIN  1 /* MIN is the fresh start op-version, mostly +                                should not change */ +#define GD_OP_VERSION_MAX  2 /* MAX VERSION is the maximum count in VME table, +                                should keep changing with introduction of newer +                                versions */ +  #include "xlator.h"  /* THIS */ diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c index 6a273df54b6..5b3299d549a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handshake.c +++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c @@ -124,7 +124,17 @@ server_getspec (rpcsvc_request_t *req)          gf_getspec_req        args                   = {0,};          gf_getspec_rsp        rsp                    = {0,};          char                  addrstr[RPCSVC_PEER_STRLEN] = {0}; +        dict_t               *dict                   = NULL; +        xlator_t             *this                   = NULL; +        glusterd_conf_t      *conf                   = NULL; +        int                   client_min_op_version  = 0; +        int                   client_max_op_version  = 0; +        this = THIS; +        GF_ASSERT (this); + +        conf = this->private; +        GF_ASSERT (conf);          ret = xdr_to_generic (req->msg[0], &args,                                (xdrproc_t)xdr_gf_getspec_req); @@ -134,6 +144,63 @@ server_getspec (rpcsvc_request_t *req)                  goto fail;          } +        if (!args.xdata.xdata_len) { +                // For clients <= 3.3.0, only allow if op_version = 1 +                if (1 != conf->op_version) { +                        ret = -1; +                        op_errno = ENOTSUP; +                        gf_log (this->name, GF_LOG_INFO, +                                "Client %s doesn't support required op-version. " +                                "Rejecting getspec request.", +                                req->trans->peerinfo.identifier); +                        goto fail; +                } +        } else { +                // For clients > 3.3, only allow if they can support +                // clusters' op_version +                dict = dict_new (); +                if (!dict) { +                        ret = -1; +                        goto fail; +                } + +                ret = dict_unserialize (args.xdata.xdata_val, +                                        args.xdata.xdata_len, &dict); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Failed to unserialize request dictionary"); +                        goto fail; +                } + +                ret = dict_get_int32 (dict, "min-op-version", +                                      &client_min_op_version); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Failed to get client-min-op-version"); +                        goto fail; +                } + +                ret = dict_get_int32 (dict, "max-op-version", +                                      &client_max_op_version); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Failed to get client-max-op-version"); +                        goto fail; +                } + +                if ((client_min_op_version > conf->op_version) || +                    (client_max_op_version < conf->op_version)) { +                        ret = -1; +                        op_errno = ENOTSUP; +                        //TODO: Add client identifier +                        gf_log (this->name, GF_LOG_INFO, +                                "Client %s doesn't support required op-version. " +                                "Rejecting getspec request.", +                                req->trans->peerinfo.identifier); +                        goto fail; +                } +        } +          volume = args.key;          trans = req->trans; @@ -387,7 +454,7 @@ glusterd_mgmt_hndsk_versions_ack (rpcsvc_request_t *req)          glusterd_conf_t   *conf            = NULL;          int                ret             = -1;          int                op_errno        = EINVAL; -        int32_t            peer_op_version = 0; +        int                peer_op_version = 0;          gf_mgmt_hndsk_req  args            = {{0,},};          gf_mgmt_hndsk_rsp  rsp             = {0,}; @@ -406,8 +473,7 @@ glusterd_mgmt_hndsk_versions_ack (rpcsvc_request_t *req)                                        (args.hndsk.hndsk_len), ret, op_errno,                                        out); -        ret = dict_get_int32 (clnt_dict, GD_OP_VERSION_KEY, -                              &peer_op_version); +        ret = dict_get_int32 (clnt_dict, GD_OP_VERSION_KEY, &peer_op_version);          if (ret) {                  gf_log (this->name, GF_LOG_WARNING,                          "failed to get the op-version key peer=%s", diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index f7bfad697e8..95e23674c57 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -114,23 +114,6 @@ typedef struct {          gf_boolean_t            online;  } nodesrv_t; -#define GD_OP_VERSION_KEY     "operating-version" -#define GD_MIN_OP_VERSION_KEY "minimum-operating-version" -#define GD_MAX_OP_VERSION_KEY "maxium-operating-version" - -/* Gluster versions - OP-VERSION mapping - * - * 3.3.0                - 1 - * 3.3.Next/3.Next      - 2 - * - * (TODO: Change above comment once gluster version is finalised) - */ -#define GD_OP_VERSION_MIN  1 /* MIN is the fresh start op-version, mostly -                                should not change */ -#define GD_OP_VERSION_MAX  2 /* MAX VERSION is the maximum count in VME table, -                                should keep changing with introduction of newer -                                versions */ -  typedef struct {          gf_boolean_t    quorum;          double          quorum_ratio;  | 
