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