b51a1f
From 854ab79dbef449c39adf66e3faebb4681359fce4 Mon Sep 17 00:00:00 2001
b51a1f
From: mohit84 <moagrawa@redhat.com>
b51a1f
Date: Thu, 18 Feb 2021 09:40:44 +0530
b51a1f
Subject: [PATCH 533/538] glusterd: Rebalance cli is not showing correct status
b51a1f
 after reboot (#2172)
b51a1f
b51a1f
Rebalance cli is not showing correct status after reboot.
b51a1f
b51a1f
The CLI is not correct status because defrag object is not
b51a1f
valid at the time of creating a rpc connection to show the status.
b51a1f
The defrag object is not valid because at the time of start a glusterd
b51a1f
glusterd_restart_rebalance can be call almost at the same time by two
b51a1f
different synctask and glusterd got a disconnect on rpc object and it
b51a1f
cleanup the defrag object.
b51a1f
b51a1f
Solution: To avoid the defrag object populate a reference count before
b51a1f
          create a defrag rpc object.
b51a1f
>Fixes: #1339
b51a1f
>Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
b51a1f
>Change-Id: Ia284015d79beaa3d703ebabb92f26870a5aaafba
b51a1f
Upstream Patch : https://github.com/gluster/glusterfs/pull/2172
b51a1f
b51a1f
BUG: 1832306
b51a1f
Change-Id: Ia284015d79beaa3d703ebabb92f26870a5aaafba
b51a1f
Signed-off-by: srijan-sivakumar <ssivakum@redhat.com>
b51a1f
Reviewed-on: https://code.engineering.redhat.com/gerrit/228249
b51a1f
Tested-by: RHGS Build Bot <nigelb@redhat.com>
b51a1f
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
b51a1f
---
b51a1f
 xlators/mgmt/glusterd/src/glusterd-rebalance.c | 35 ++++++++++-----
b51a1f
 xlators/mgmt/glusterd/src/glusterd-syncop.c    |  1 +
b51a1f
 xlators/mgmt/glusterd/src/glusterd-utils.c     | 59 +++++++++++++++++++++++++-
b51a1f
 xlators/mgmt/glusterd/src/glusterd-utils.h     |  5 +++
b51a1f
 xlators/mgmt/glusterd/src/glusterd.h           |  1 +
b51a1f
 5 files changed, 90 insertions(+), 11 deletions(-)
b51a1f
b51a1f
diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
b51a1f
index b419a89..fcd5318 100644
b51a1f
--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c
b51a1f
+++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
b51a1f
@@ -86,6 +86,7 @@ __glusterd_defrag_notify(struct rpc_clnt *rpc, void *mydata,
b51a1f
     glusterd_conf_t *priv = NULL;
b51a1f
     xlator_t *this = NULL;
b51a1f
     int pid = -1;
b51a1f
+    int refcnt = 0;
b51a1f
 
b51a1f
     this = THIS;
b51a1f
     if (!this)
b51a1f
@@ -125,11 +126,12 @@ __glusterd_defrag_notify(struct rpc_clnt *rpc, void *mydata,
b51a1f
         }
b51a1f
 
b51a1f
         case RPC_CLNT_DISCONNECT: {
b51a1f
-            if (!defrag->connected)
b51a1f
-                return 0;
b51a1f
-
b51a1f
             LOCK(&defrag->lock);
b51a1f
             {
b51a1f
+                if (!defrag->connected) {
b51a1f
+                    UNLOCK(&defrag->lock);
b51a1f
+                    return 0;
b51a1f
+                }
b51a1f
                 defrag->connected = 0;
b51a1f
             }
b51a1f
             UNLOCK(&defrag->lock);
b51a1f
@@ -146,11 +148,11 @@ __glusterd_defrag_notify(struct rpc_clnt *rpc, void *mydata,
b51a1f
             glusterd_defrag_rpc_put(defrag);
b51a1f
             if (defrag->cbk_fn)
b51a1f
                 defrag->cbk_fn(volinfo, volinfo->rebal.defrag_status);
b51a1f
-
b51a1f
-            GF_FREE(defrag);
b51a1f
+            refcnt = glusterd_defrag_unref(defrag);
b51a1f
             gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_REBALANCE_DISCONNECTED,
b51a1f
-                   "Rebalance process for volume %s has disconnected.",
b51a1f
-                   volinfo->volname);
b51a1f
+                   "Rebalance process for volume %s has disconnected"
b51a1f
+                   " and defrag refcnt is %d.",
b51a1f
+                   volinfo->volname, refcnt);
b51a1f
             break;
b51a1f
         }
b51a1f
         case RPC_CLNT_DESTROY:
b51a1f
@@ -309,7 +311,11 @@ glusterd_handle_defrag_start(glusterd_volinfo_t *volinfo, char *op_errstr,
b51a1f
         gf_msg_debug("glusterd", 0, "rebalance command failed");
b51a1f
         goto out;
b51a1f
     }
b51a1f
-
b51a1f
+    /* Take reference before sleep to save defrag object cleanup while
b51a1f
+       glusterd_restart_rebalance call for other bricks by syncktask
b51a1f
+       at the time of restart a glusterd.
b51a1f
+    */
b51a1f
+    glusterd_defrag_ref(defrag);
b51a1f
     sleep(5);
b51a1f
 
b51a1f
     ret = glusterd_rebalance_rpc_create(volinfo);
b51a1f
@@ -372,6 +378,7 @@ glusterd_rebalance_rpc_create(glusterd_volinfo_t *volinfo)
b51a1f
     GF_ASSERT(this);
b51a1f
     priv = this->private;
b51a1f
     GF_ASSERT(priv);
b51a1f
+    struct rpc_clnt *rpc = NULL;
b51a1f
 
b51a1f
     // rebalance process is not started
b51a1f
     if (!defrag)
b51a1f
@@ -396,13 +403,21 @@ glusterd_rebalance_rpc_create(glusterd_volinfo_t *volinfo)
b51a1f
     }
b51a1f
 
b51a1f
     glusterd_volinfo_ref(volinfo);
b51a1f
-    ret = glusterd_rpc_create(&defrag->rpc, options, glusterd_defrag_notify,
b51a1f
-                              volinfo, _gf_true);
b51a1f
+    ret = glusterd_rpc_create(&rpc, options, glusterd_defrag_notify, volinfo,
b51a1f
+                              _gf_false);
b51a1f
     if (ret) {
b51a1f
         gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_RPC_CREATE_FAIL,
b51a1f
                "Glusterd RPC creation failed");
b51a1f
         goto out;
b51a1f
     }
b51a1f
+    LOCK(&defrag->lock);
b51a1f
+    {
b51a1f
+        if (!defrag->rpc)
b51a1f
+            defrag->rpc = rpc;
b51a1f
+        else
b51a1f
+            rpc_clnt_unref(rpc);
b51a1f
+    }
b51a1f
+    UNLOCK(&defrag->lock);
b51a1f
     ret = 0;
b51a1f
 out:
b51a1f
     if (options)
b51a1f
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
b51a1f
index df78fef..05c9e11 100644
b51a1f
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
b51a1f
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
b51a1f
@@ -1732,6 +1732,7 @@ gd_brick_op_phase(glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,
b51a1f
         if (!rpc) {
b51a1f
             if (pending_node->type == GD_NODE_REBALANCE && pending_node->node) {
b51a1f
                 volinfo = pending_node->node;
b51a1f
+                glusterd_defrag_ref(volinfo->rebal.defrag);
b51a1f
                 ret = glusterd_rebalance_rpc_create(volinfo);
b51a1f
                 if (ret) {
b51a1f
                     ret = 0;
b51a1f
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
b51a1f
index bc188a2..9fb8eab 100644
b51a1f
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
b51a1f
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
b51a1f
@@ -93,6 +93,44 @@
b51a1f
 #define NLMV4_VERSION 4
b51a1f
 #define NLMV1_VERSION 1
b51a1f
 
b51a1f
+int
b51a1f
+glusterd_defrag_ref(glusterd_defrag_info_t *defrag)
b51a1f
+{
b51a1f
+    int refcnt = 0;
b51a1f
+
b51a1f
+    if (!defrag)
b51a1f
+        goto out;
b51a1f
+
b51a1f
+    LOCK(&defrag->lock);
b51a1f
+    {
b51a1f
+        refcnt = ++defrag->refcnt;
b51a1f
+    }
b51a1f
+    UNLOCK(&defrag->lock);
b51a1f
+
b51a1f
+out:
b51a1f
+    return refcnt;
b51a1f
+}
b51a1f
+
b51a1f
+int
b51a1f
+glusterd_defrag_unref(glusterd_defrag_info_t *defrag)
b51a1f
+{
b51a1f
+    int refcnt = -1;
b51a1f
+
b51a1f
+    if (!defrag)
b51a1f
+        goto out;
b51a1f
+
b51a1f
+    LOCK(&defrag->lock);
b51a1f
+    {
b51a1f
+        refcnt = --defrag->refcnt;
b51a1f
+        if (refcnt <= 0)
b51a1f
+            GF_FREE(defrag);
b51a1f
+    }
b51a1f
+    UNLOCK(&defrag->lock);
b51a1f
+
b51a1f
+out:
b51a1f
+    return refcnt;
b51a1f
+}
b51a1f
+
b51a1f
 gf_boolean_t
b51a1f
 is_brick_mx_enabled(void)
b51a1f
 {
b51a1f
@@ -9370,6 +9408,7 @@ glusterd_volume_defrag_restart(glusterd_volinfo_t *volinfo, char *op_errstr,
b51a1f
     char pidfile[PATH_MAX] = "";
b51a1f
     int ret = -1;
b51a1f
     pid_t pid = 0;
b51a1f
+    int refcnt = 0;
b51a1f
 
b51a1f
     this = THIS;
b51a1f
     GF_ASSERT(this);
b51a1f
@@ -9410,7 +9449,25 @@ glusterd_volume_defrag_restart(glusterd_volinfo_t *volinfo, char *op_errstr,
b51a1f
                              volinfo->volname);
b51a1f
                     goto out;
b51a1f
                 }
b51a1f
-                ret = glusterd_rebalance_rpc_create(volinfo);
b51a1f
+                refcnt = glusterd_defrag_ref(volinfo->rebal.defrag);
b51a1f
+                /* If refcnt value is 1 it means either defrag object is
b51a1f
+                   poulated by glusterd_rebalance_defrag_init or previous
b51a1f
+                   rpc creation was failed.If it is not 1 it means it(defrag)
b51a1f
+                   was populated at the time of start a rebalance daemon.
b51a1f
+                   We need to create a rpc object only while a previous
b51a1f
+                   rpc connection was not established successfully at the
b51a1f
+                   time of restart a rebalance daemon by
b51a1f
+                   glusterd_handle_defrag_start otherwise rebalance cli
b51a1f
+                   does not show correct status after just reboot a node and try
b51a1f
+                   to print the rebalance status because defrag object has been
b51a1f
+                   destroyed during handling of rpc disconnect.
b51a1f
+                */
b51a1f
+                if (refcnt == 1) {
b51a1f
+                    ret = glusterd_rebalance_rpc_create(volinfo);
b51a1f
+                } else {
b51a1f
+                    ret = 0;
b51a1f
+                    glusterd_defrag_unref(volinfo->rebal.defrag);
b51a1f
+                }
b51a1f
                 break;
b51a1f
             }
b51a1f
         case GF_DEFRAG_STATUS_NOT_STARTED:
b51a1f
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
b51a1f
index 02d85d2..4541471 100644
b51a1f
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
b51a1f
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
b51a1f
@@ -886,4 +886,9 @@ int32_t
b51a1f
 glusterd_check_brick_order(dict_t *dict, char *err_str, int32_t type,
b51a1f
                            int32_t sub_count);
b51a1f
 
b51a1f
+int
b51a1f
+glusterd_defrag_ref(glusterd_defrag_info_t *defrag);
b51a1f
+
b51a1f
+int
b51a1f
+glusterd_defrag_unref(glusterd_defrag_info_t *defrag);
b51a1f
 #endif
b51a1f
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
b51a1f
index efe4d0e..9de3f28 100644
b51a1f
--- a/xlators/mgmt/glusterd/src/glusterd.h
b51a1f
+++ b/xlators/mgmt/glusterd/src/glusterd.h
b51a1f
@@ -321,6 +321,7 @@ struct glusterd_defrag_info_ {
b51a1f
     uint64_t total_data;
b51a1f
     uint64_t num_files_lookedup;
b51a1f
     uint64_t total_failures;
b51a1f
+    int refcnt;
b51a1f
     gf_lock_t lock;
b51a1f
     int cmd;
b51a1f
     pthread_t th;
b51a1f
-- 
b51a1f
1.8.3.1
b51a1f