233933
From d79cb2cdff6fe8d962c9ac095a7541ddf500302b Mon Sep 17 00:00:00 2001
233933
From: Mohammed Rafi KC <rkavunga@redhat.com>
233933
Date: Mon, 1 Apr 2019 14:44:20 +0530
233933
Subject: [PATCH 099/124] client/fini: return fini after rpc cleanup
233933
233933
There is a race condition in rpc_transport later
233933
and client fini.
233933
233933
Sequence of events to happen the race condition
233933
1) When we want to destroy a graph, we send a parent down
233933
   event first
233933
2) Once parent down received on a client xlator, we will
233933
   initiates a rpc disconnect
233933
3) This will in turn generates a child down event.
233933
4) When we process child down, we first do fini for
233933
   Every xlator
233933
5) On successful return of fini, we delete the graph
233933
233933
Here after the step 5, there is a chance that the fini
233933
on client might not be finished. Because an rpc_tranpsort
233933
ref can race with the above sequence.
233933
233933
So we have to wait till all rpc's are successfully freed
233933
before returning the fini from client
233933
233933
Backport of: https://review.gluster.org/#/c/glusterfs/+/22468/
233933
233933
>Change-Id: I20145662d71fb837e448a4d3210d1fcb2855f2d4
233933
>fixes: bz#1659708
233933
>Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
233933
233933
Change-Id: I848bcfb9443467caed32bae0717244ab01b407fc
233933
BUG: 1471742
233933
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
233933
Reviewed-on: https://code.engineering.redhat.com/gerrit/167831
233933
Tested-by: RHGS Build Bot <nigelb@redhat.com>
233933
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
233933
---
233933
 xlators/protocol/client/src/client.c | 25 ++++++++++++++++++++-----
233933
 xlators/protocol/client/src/client.h |  6 ++++++
233933
 2 files changed, 26 insertions(+), 5 deletions(-)
233933
233933
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c
233933
index 19f5175..a372807 100644
233933
--- a/xlators/protocol/client/src/client.c
233933
+++ b/xlators/protocol/client/src/client.c
233933
@@ -49,11 +49,12 @@ client_fini_complete(xlator_t *this)
233933
     if (!conf->destroy)
233933
         return 0;
233933
 
233933
-    this->private = NULL;
233933
-
233933
-    pthread_spin_destroy(&conf->fd_lock);
233933
-    pthread_mutex_destroy(&conf->lock);
233933
-    GF_FREE(conf);
233933
+    pthread_mutex_lock(&conf->lock);
233933
+    {
233933
+        conf->fini_completed = _gf_true;
233933
+        pthread_cond_broadcast(&conf->fini_complete_cond);
233933
+    }
233933
+    pthread_mutex_unlock(&conf->lock);
233933
 
233933
 out:
233933
     return 0;
233933
@@ -2721,6 +2722,7 @@ init(xlator_t *this)
233933
         goto out;
233933
 
233933
     pthread_mutex_init(&conf->lock, NULL);
233933
+    pthread_cond_init(&conf->fini_complete_cond, NULL);
233933
     pthread_spin_init(&conf->fd_lock, 0);
233933
     INIT_LIST_HEAD(&conf->saved_fds);
233933
 
233933
@@ -2779,6 +2781,7 @@ fini(xlator_t *this)
233933
     if (!conf)
233933
         return;
233933
 
233933
+    conf->fini_completed = _gf_false;
233933
     conf->destroy = 1;
233933
     if (conf->rpc) {
233933
         /* cleanup the saved-frames before last unref */
233933
@@ -2786,6 +2789,18 @@ fini(xlator_t *this)
233933
         rpc_clnt_unref(conf->rpc);
233933
     }
233933
 
233933
+    pthread_mutex_lock(&conf->lock);
233933
+    {
233933
+        while (!conf->fini_completed)
233933
+            pthread_cond_wait(&conf->fini_complete_cond, &conf->lock);
233933
+    }
233933
+    pthread_mutex_unlock(&conf->lock);
233933
+
233933
+    pthread_spin_destroy(&conf->fd_lock);
233933
+    pthread_mutex_destroy(&conf->lock);
233933
+    pthread_cond_destroy(&conf->fini_complete_cond);
233933
+    GF_FREE(conf);
233933
+
233933
     /* Saved Fds */
233933
     /* TODO: */
233933
 
233933
diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h
233933
index f12fa61..8dcd72f 100644
233933
--- a/xlators/protocol/client/src/client.h
233933
+++ b/xlators/protocol/client/src/client.h
233933
@@ -235,6 +235,12 @@ typedef struct clnt_conf {
233933
                                       * up, disconnects can be
233933
                                       * logged
233933
                                       */
233933
+
233933
+    gf_boolean_t old_protocol;         /* used only for old-protocol testing */
233933
+    pthread_cond_t fini_complete_cond; /* Used to wait till we finsh the fini
233933
+                                          compltely, ie client_fini_complete
233933
+                                          to return*/
233933
+    gf_boolean_t fini_completed;
233933
 } clnt_conf_t;
233933
 
233933
 typedef struct _client_fd_ctx {
233933
-- 
233933
1.8.3.1
233933