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