Blob Blame History Raw
From 6d65c0a40278c8879f5fdba3d3120c3ea6b5a2b2 Mon Sep 17 00:00:00 2001
From: Kaushal M <kaushal@redhat.com>
Date: Wed, 4 Sep 2013 16:19:01 +0530
Subject: [PATCH 30/80] glusterd: Fix connected clients check during 'volume set'

  Backport of 28f5829 from upstream/release-3.7

Use the volume's newly calulatedclient-op-version for the connected
clients check. This prevents rejection of server options of higher
op-version when clients of lower op-version are connected. Also,
initialize the variables of the newly calculated volume op-version and
client-op-version with the current values, instead of the cluster
op-version.

Change-Id: Ieb36f97c677a5457feba54bef20e154c0456e70e
BUG: 1298955
Signed-off-by: Kaushal M <kaushal@redhat.com>
Reviewed-upstream-on: http://review.gluster.org/13814
Reviewed-on: https://code.engineering.redhat.com/gerrit/70826
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Tested-by: Atin Mukherjee <amukherj@redhat.com>
---
 xlators/mgmt/glusterd/src/glusterd-op-sm.c |   76 +++++++++++++++-------------
 1 files changed, 41 insertions(+), 35 deletions(-)

diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 444408f..378a397 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -865,35 +865,36 @@ out:
 static int
 glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
 {
-        int                             ret                     = -1;
-        char                            *volname                = NULL;
-        int                             exists                  = 0;
-        char                            *key                    = NULL;
-        char                            *key_fixed              = NULL;
-        char                            *value                  = NULL;
-        char                            *val_dup                = NULL;
-        char                            str[100]                = {0, };
-        char                            *trash_path             = NULL;
-        int                             trash_path_len          = 0;
-        int                             count                   = 0;
-        int                             dict_count              = 0;
-        char                            errstr[PATH_MAX]        = {0, };
-        glusterd_volinfo_t              *volinfo                = NULL;
-        glusterd_brickinfo_t            *brickinfo              = NULL;
-        dict_t                          *val_dict               = NULL;
-        gf_boolean_t                    global_opt              = _gf_false;
-        glusterd_volinfo_t              *voliter                = NULL;
-        glusterd_conf_t                 *priv                   = NULL;
-        xlator_t                        *this                   = NULL;
-        uint32_t                        new_op_version          = 0;
-        uint32_t                        local_new_op_version    = 0;
-        uint32_t                        key_op_version          = 0;
-        uint32_t                        local_key_op_version    = 0;
-        gf_boolean_t                    origin_glusterd         = _gf_true;
-        gf_boolean_t                    check_op_version        = _gf_true;
-        gf_boolean_t                    trash_enabled           = _gf_false;
-        gf_boolean_t                    all_vol                 = _gf_false;
-        struct          stat            stbuf                   = {0, };
+        int                   ret                         = -1;
+        char                 *volname                     = NULL;
+        int                   exists                      = 0;
+        char                 *key                         = NULL;
+        char                 *key_fixed                   = NULL;
+        char                 *value                       = NULL;
+        char                 *val_dup                     = NULL;
+        char                  str[100]                    = {0, };
+        char                 *trash_path                  = NULL;
+        int                   trash_path_len              = 0;
+        int                   count                       = 0;
+        int                   dict_count                  = 0;
+        char                  errstr[PATH_MAX]            = {0, };
+        glusterd_volinfo_t   *volinfo                     = NULL;
+        glusterd_brickinfo_t *brickinfo                   = NULL;
+        dict_t               *val_dict                    = NULL;
+        gf_boolean_t          global_opt                  = _gf_false;
+        glusterd_volinfo_t   *voliter                     = NULL;
+        glusterd_conf_t      *priv                        = NULL;
+        xlator_t             *this                        = NULL;
+        uint32_t              new_op_version              = GD_OP_VERSION_MIN;
+        uint32_t              local_new_op_version        = GD_OP_VERSION_MIN;
+        uint32_t              local_new_client_op_version = GD_OP_VERSION_MIN;
+        uint32_t              key_op_version              = GD_OP_VERSION_MIN;
+        uint32_t              local_key_op_version        = GD_OP_VERSION_MIN;
+        gf_boolean_t          origin_glusterd             = _gf_true;
+        gf_boolean_t          check_op_version            = _gf_true;
+        gf_boolean_t          trash_enabled               = _gf_false;
+        gf_boolean_t          all_vol                     = _gf_false;
+        struct stat           stbuf                       = {0, };
 
         GF_ASSERT (dict);
         this = THIS;
@@ -1007,12 +1008,14 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
                 ret = glusterd_validate_volume_id (dict, volinfo);
                 if (ret)
                         goto out;
+
+                local_new_op_version = volinfo->op_version;
+                local_new_client_op_version = volinfo->client_op_version;
+
         } else {
                 all_vol = _gf_true;
         }
 
-        local_new_op_version = priv->op_version;
-
         for ( count = 1; ret != 1 ; count++ ) {
                 global_opt = _gf_false;
                 sprintf (str, "key%d", count);
@@ -1170,6 +1173,9 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
                 local_key_op_version = glusterd_get_op_version_for_key (key);
                 if (local_key_op_version > local_new_op_version)
                         local_new_op_version = local_key_op_version;
+                if (gd_is_client_option (key) &&
+                    (local_key_op_version > local_new_client_op_version))
+                        local_new_client_op_version = local_key_op_version;
 
                 sprintf (str, "op-version%d", count);
                 if (origin_glusterd) {
@@ -1350,10 +1356,10 @@ 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);
+        /* Check if all the connected clients support the new client-op-version
+         */
+        ret = glusterd_check_client_op_version_support
+                (volname, local_new_client_op_version, op_errstr);
         if (ret)
                 goto out;
 
-- 
1.7.1