diff options
author | Mohit Agrawal <moagrawal@redhat.com> | 2018-11-23 09:39:43 +0530 |
---|---|---|
committer | Amar Tumballi <amarts@redhat.com> | 2018-12-13 04:46:50 +0000 |
commit | fb917bf10b4783d5c669e81a5be1f902ca48cb84 (patch) | |
tree | 81a61c54de77f598c1c23648d5e38a3f0fff54aa /xlators/features/changelog/src/changelog.c | |
parent | 52d3f82db2f032eae1b60ffa2f283109858ce3df (diff) |
[geo-rep]: Worker still ACTIVE after killing bricks
Problem: In changelog xlator after destroying listener it call's
unlink to delete changelog socket file but socket file
reference is not cleaned up from process memory
Solution: 1) To cleanup reference completely from process memory
serialize transport cleanup for changelog and then
unlink socket file
2) Brick xlator will notify GF_EVENT_PARENT_DOWN to next
xlator only after cleanup all xprts
Test: To test the same run below steps
1) Setup some volume and enable brick mux
2) kill anyone brick with gf_attach
3) check changelog socket for specific to killed brick
in lsof, it should cleanup completely
fixes: bz#1600145
Change-Id: Iba06cbf77d8a87b34a60fce50f6d8c0d427fa491
Signed-off-by: Mohit Agrawal <moagrawal@redhat.com>
Diffstat (limited to 'xlators/features/changelog/src/changelog.c')
-rw-r--r-- | xlators/features/changelog/src/changelog.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c index 1f42dbe178e..1f22a97a6e9 100644 --- a/xlators/features/changelog/src/changelog.c +++ b/xlators/features/changelog/src/changelog.c @@ -2004,6 +2004,10 @@ notify(xlator_t *this, int event, void *data, ...) struct list_head queue = { 0, }; + uint64_t xprtcnt = 0; + uint64_t clntcnt = 0; + changelog_clnt_t *conn = NULL; + gf_boolean_t cleanup_notify = _gf_false; INIT_LIST_HEAD(&queue); @@ -2011,6 +2015,33 @@ notify(xlator_t *this, int event, void *data, ...) if (!priv) goto out; + if (event == GF_EVENT_PARENT_DOWN) { + priv->victim = data; + gf_log(this->name, GF_LOG_INFO, + "cleanup changelog rpc connection of brick %s", + priv->victim->name); + + this->cleanup_starting = 1; + changelog_destroy_rpc_listner(this, priv); + conn = &priv->connections; + if (conn) + changelog_ev_cleanup_connections(this, conn); + xprtcnt = GF_ATOMIC_GET(priv->xprtcnt); + clntcnt = GF_ATOMIC_GET(priv->clntcnt); + + if (!xprtcnt && !clntcnt) { + LOCK(&priv->lock); + { + cleanup_notify = priv->notify_down; + priv->notify_down = _gf_true; + } + UNLOCK(&priv->lock); + if (!cleanup_notify) + default_notify(this, GF_EVENT_PARENT_DOWN, data); + } + goto out; + } + if (event == GF_EVENT_TRANSLATOR_OP) { dict = data; @@ -2629,8 +2660,10 @@ static void changelog_cleanup_rpc(xlator_t *this, changelog_priv_t *priv) { /* terminate rpc server */ - changelog_destroy_rpc_listner(this, priv); + if (!this->cleanup_starting) + changelog_destroy_rpc_listner(this, priv); + (void)changelog_cleanup_rpc_threads(this, priv); /* cleanup rot buffs */ rbuf_dtor(priv->rbuf); @@ -2703,6 +2736,10 @@ init(xlator_t *this) LOCK_INIT(&priv->lock); LOCK_INIT(&priv->c_snap_lock); + GF_ATOMIC_INIT(priv->listnercnt, 0); + GF_ATOMIC_INIT(priv->clntcnt, 0); + GF_ATOMIC_INIT(priv->xprtcnt, 0); + INIT_LIST_HEAD(&priv->xprt_list); ret = changelog_init_options(this, priv); if (ret) |