b7d4d7
From 71fc5b7949e00c4448f5ec1291e756b201a70082 Mon Sep 17 00:00:00 2001
b7d4d7
From: Ravishankar N <ravishankar@redhat.com>
b7d4d7
Date: Thu, 29 Apr 2021 18:34:57 +0530
b7d4d7
Subject: [PATCH 543/543] glusterd: handle custom xlator failure cases
b7d4d7
b7d4d7
Problem-1:
b7d4d7
custom xlator insertion was failing for those xlators in the brick graph
b7d4d7
whose dbg_key was NULL in the server_graph_table. Looking at the git log,
b7d4d7
the dbg_key was added in commit d1397dbd7d6cdbd2d81d5d36d608b6175d449db4
b7d4d7
for inserting debug xlators.
b7d4d7
b7d4d7
Fix: I think it is fine to define it for all brick xlators below server.
b7d4d7
b7d4d7
Problem-2:
b7d4d7
In the commit-op phase, glusterd_op_set_volume() updates the volinfo
b7d4d7
dict with the key-value pairs and then proceeds to create the volfiles.
b7d4d7
If any of the steps fail, the volinfo dict retains those key-values,
b7d4d7
until glusterd is restarted or `gluster vol reset $VOLNAME` is issued.
b7d4d7
b7d4d7
Fix:
b7d4d7
Make a copy of the volinfo dict and if there are any failures in
b7d4d7
proceeding with the set volume logic, restore the dict to its original
b7d4d7
state.
b7d4d7
b7d4d7
Backport of:
b7d4d7
> Upstream-patch-link: https://github.com/gluster/glusterfs/pull/2371
b7d4d7
> Change-Id: I9010dab33d0139b8e6d603308e331b6d220a4849
b7d4d7
> Updates: #2370
b7d4d7
> Signed-off-by: Ravishankar N <ravishankar@redhat.com>
b7d4d7
b7d4d7
Change-Id: I9010dab33d0139b8e6d603308e331b6d220a4849
b7d4d7
BUG: 1953901
b7d4d7
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
b7d4d7
Reviewed-on: https://code.engineering.redhat.com/gerrit/239889
b7d4d7
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
b7d4d7
---
b7d4d7
 tests/basic/user-xlator.t                   | 16 ++++++++++++++--
b7d4d7
 xlators/mgmt/glusterd/src/glusterd-op-sm.c  | 16 ++++++++++++++++
b7d4d7
 xlators/mgmt/glusterd/src/glusterd-volgen.c | 14 +++++++-------
b7d4d7
 3 files changed, 37 insertions(+), 9 deletions(-)
b7d4d7
b7d4d7
diff --git a/tests/basic/user-xlator.t b/tests/basic/user-xlator.t
b7d4d7
index a711f9f..ed2d831 100755
b7d4d7
--- a/tests/basic/user-xlator.t
b7d4d7
+++ b/tests/basic/user-xlator.t
b7d4d7
@@ -35,8 +35,18 @@ EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}4
b7d4d7
 EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}5
b7d4d7
 EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}6
b7d4d7
 
b7d4d7
-TEST $CLI volume set $V0 user.xlator.hoge trash
b7d4d7
-TEST grep -q 'user/hoge' ${SERVER_VOLFILE}
b7d4d7
+# Test that the insertion at all positions between server and posix is successful.
b7d4d7
+# It is not guaranteed that the brick process will start/work in all positions though.
b7d4d7
+TESTS_EXPECTED_IN_LOOP=34
b7d4d7
+declare -a brick_side_xlators=("decompounder" "io-stats" "quota" "index" "barrier"
b7d4d7
+                               "marker" "selinux" "io-threads" "upcall" "leases"
b7d4d7
+                               "read-only" "worm" "locks"  "access-control"
b7d4d7
+                               "bitrot-stub" "changelog" "trash")
b7d4d7
+for xlator in "${brick_side_xlators[@]}"
b7d4d7
+  do
b7d4d7
+    TEST_IN_LOOP $CLI volume set $V0 user.xlator.hoge $xlator
b7d4d7
+    TEST_IN_LOOP grep -q 'user/hoge' ${SERVER_VOLFILE}
b7d4d7
+  done
b7d4d7
 
b7d4d7
 TEST $CLI volume stop $V0
b7d4d7
 TEST $CLI volume start $V0
b7d4d7
@@ -49,6 +59,8 @@ EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}6
b7d4d7
 
b7d4d7
 TEST ! $CLI volume set $V0 user.xlator.hoge unknown
b7d4d7
 TEST grep -q 'user/hoge' ${SERVER_VOLFILE} # When the CLI fails, the volfile is not modified.
b7d4d7
+# User xlator insert failures must not prevent setting other volume options.
b7d4d7
+TEST $CLI volume set $V0 storage.reserve 10%
b7d4d7
 
b7d4d7
 TEST $CLI volume stop $V0
b7d4d7
 TEST $CLI volume start $V0
b7d4d7
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
b7d4d7
index 1e84f5f..893af29 100644
b7d4d7
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
b7d4d7
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
b7d4d7
@@ -2911,6 +2911,7 @@ glusterd_op_set_volume(dict_t *dict, char **errstr)
b7d4d7
     uint32_t new_op_version = 0;
b7d4d7
     gf_boolean_t quorum_action = _gf_false;
b7d4d7
     glusterd_svc_t *svc = NULL;
b7d4d7
+    dict_t *volinfo_dict_orig = NULL;
b7d4d7
 
b7d4d7
     this = THIS;
b7d4d7
     GF_ASSERT(this);
b7d4d7
@@ -2918,6 +2919,10 @@ glusterd_op_set_volume(dict_t *dict, char **errstr)
b7d4d7
     priv = this->private;
b7d4d7
     GF_ASSERT(priv);
b7d4d7
 
b7d4d7
+    volinfo_dict_orig = dict_new();
b7d4d7
+    if (!volinfo_dict_orig)
b7d4d7
+        goto out;
b7d4d7
+
b7d4d7
     ret = dict_get_int32n(dict, "count", SLEN("count"), &dict_count);
b7d4d7
     if (ret) {
b7d4d7
         gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
b7d4d7
@@ -2949,6 +2954,11 @@ glusterd_op_set_volume(dict_t *dict, char **errstr)
b7d4d7
         goto out;
b7d4d7
     }
b7d4d7
 
b7d4d7
+    if (dict_copy(volinfo->dict, volinfo_dict_orig) == NULL) {
b7d4d7
+        ret = -ENOMEM;
b7d4d7
+        goto out;
b7d4d7
+    }
b7d4d7
+
b7d4d7
     /* TODO: Remove this once v3.3 compatibility is not required */
b7d4d7
     check_op_version = dict_get_str_boolean(dict, "check-op-version",
b7d4d7
                                             _gf_false);
b7d4d7
@@ -3171,6 +3181,12 @@ out:
b7d4d7
     gf_msg_debug(this->name, 0, "returning %d", ret);
b7d4d7
     if (quorum_action)
b7d4d7
         glusterd_do_quorum_action();
b7d4d7
+    if (ret < 0 && count > 1) {
b7d4d7
+        if (dict_reset(volinfo->dict) == 0)
b7d4d7
+            dict_copy(volinfo_dict_orig, volinfo->dict);
b7d4d7
+    }
b7d4d7
+    if (volinfo_dict_orig)
b7d4d7
+        dict_unref(volinfo_dict_orig);
b7d4d7
     return ret;
b7d4d7
 }
b7d4d7
 
b7d4d7
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
b7d4d7
index 71aed08..aa85bdb 100644
b7d4d7
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
b7d4d7
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
b7d4d7
@@ -2706,24 +2706,24 @@ out:
b7d4d7
 static volgen_brick_xlator_t server_graph_table[] = {
b7d4d7
     {brick_graph_add_server, NULL},
b7d4d7
     {brick_graph_add_decompounder, "decompounder"},
b7d4d7
-    {brick_graph_add_io_stats, "NULL"},
b7d4d7
+    {brick_graph_add_io_stats, "io-stats"},
b7d4d7
     {brick_graph_add_sdfs, "sdfs"},
b7d4d7
     {brick_graph_add_namespace, "namespace"},
b7d4d7
-    {brick_graph_add_cdc, NULL},
b7d4d7
+    {brick_graph_add_cdc, "cdc" },
b7d4d7
     {brick_graph_add_quota, "quota"},
b7d4d7
     {brick_graph_add_index, "index"},
b7d4d7
-    {brick_graph_add_barrier, NULL},
b7d4d7
+    {brick_graph_add_barrier, "barrier" },
b7d4d7
     {brick_graph_add_marker, "marker"},
b7d4d7
     {brick_graph_add_selinux, "selinux"},
b7d4d7
     {brick_graph_add_fdl, "fdl"},
b7d4d7
     {brick_graph_add_iot, "io-threads"},
b7d4d7
     {brick_graph_add_upcall, "upcall"},
b7d4d7
     {brick_graph_add_leases, "leases"},
b7d4d7
-    {brick_graph_add_pump, NULL},
b7d4d7
-    {brick_graph_add_ro, NULL},
b7d4d7
-    {brick_graph_add_worm, NULL},
b7d4d7
+    {brick_graph_add_pump, "pump" },
b7d4d7
+    {brick_graph_add_ro, "read-only" },
b7d4d7
+    {brick_graph_add_worm, "worm" },
b7d4d7
     {brick_graph_add_locks, "locks"},
b7d4d7
-    {brick_graph_add_acl, "acl"},
b7d4d7
+    {brick_graph_add_acl, "access-control"},
b7d4d7
     {brick_graph_add_bitrot_stub, "bitrot-stub"},
b7d4d7
     {brick_graph_add_changelog, "changelog"},
b7d4d7
 #if USE_GFDB /* changetimerecorder depends on gfdb */
b7d4d7
-- 
b7d4d7
1.8.3.1
b7d4d7