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