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