diff options
| -rw-r--r-- | rpc/rpc-lib/src/rpc-transport.h | 5 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handshake.c | 16 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 45 | 
3 files changed, 64 insertions, 2 deletions
diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h index 91d802220e2..272de9d7ddc 100644 --- a/rpc/rpc-lib/src/rpc-transport.h +++ b/rpc/rpc-lib/src/rpc-transport.h @@ -71,6 +71,11 @@ struct peer_info {          struct sockaddr_storage sockaddr;          socklen_t sockaddr_len;          char identifier[UNIX_PATH_MAX]; +        // OP-VERSION of clients +        uint32_t max_op_version; +        uint32_t min_op_version; +        //Volume mounted by client +        char volname[1024];  };  typedef struct peer_info peer_info_t; diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c index 5b3299d549a..8b964702669 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handshake.c +++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c @@ -127,8 +127,8 @@ server_getspec (rpcsvc_request_t *req)          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; +        int                   client_min_op_version  = 1;       // OP-VERSIONs start at 1 +        int                   client_max_op_version  = 1;          this = THIS;          GF_ASSERT (this); @@ -199,10 +199,22 @@ server_getspec (rpcsvc_request_t *req)                                  req->trans->peerinfo.identifier);                          goto fail;                  } +          } +        // Store the op-versions supported by the client +        req->trans->peerinfo.max_op_version = client_max_op_version; +        req->trans->peerinfo.min_op_version = client_min_op_version; +          volume = args.key; +        // Store the name of volume  being mounted +        if (volume[0] == '/') +                strncpy (req->trans->peerinfo.volname, &volume[1], +                         strlen(&volume[1])); +        else +                strncpy (req->trans->peerinfo.volname, volume, strlen(volume)); +          trans = req->trans;          ret = rpcsvc_transport_peername (trans, (char *)&addrstr,                                           sizeof (addrstr)); diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index ea2aa0e21db..26e61b4f61c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -339,6 +339,44 @@ out:  }  static int +glusterd_check_client_op_version_support (char *volname, uint32_t op_version, +                                          char **op_errstr) +{ +        int                     ret = 0; +        xlator_t                *this = NULL; +        glusterd_conf_t         *priv = NULL; +        rpc_transport_t         *xprt = NULL; + +        this = THIS; +        GF_ASSERT(this); +        priv = this->private; +        GF_ASSERT(priv); + +        pthread_mutex_lock (&priv->xprt_lock); +        list_for_each_entry (xprt, &priv->xprt_list, list) { +                if ((!strcmp(volname, xprt->peerinfo.volname)) && +                    ((op_version > xprt->peerinfo.max_op_version) || +                     (op_version < xprt->peerinfo.min_op_version))) { +                        ret = -1; +                        break; +                } +        } +        pthread_mutex_unlock (&priv->xprt_lock); + +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "One or more clients " +                        "don't support the required op-version"); +                ret = gf_asprintf (op_errstr, "One or more connected clients " +                                   "cannot support the feature being set. " +                                   "These clients need to be upgraded or " +                                   "disconnected before running this command" +                                   " again"); +                return -1; +        } +        return 0; +} + +static int  glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)  {          int                             ret                     = -1; @@ -622,6 +660,13 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)                  }          } +        // Check if all the connected clients support the new op-version +        ret = glusterd_check_client_op_version_support (volname, +                                                        local_new_op_version, +                                                        op_errstr); +        if (ret) +                goto out; +          if (origin_glusterd) {                  ret = dict_set_uint32 (dict, "new-op-version",                                         local_new_op_version);  | 
