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