21ab4e
From c0860a9b9736b2d5bbe74f96039e1a2ccb90b2b0 Mon Sep 17 00:00:00 2001
21ab4e
From: moagrawa <moagrawa@redhat.com>
21ab4e
Date: Fri, 2 Jun 2017 16:44:27 +0530
21ab4e
Subject: [PATCH 483/486] terfs: Not able to mount running volume after enable
21ab4e
 brick mux and stopped any volume
21ab4e
21ab4e
Problem: After enabled brick mux if any volume has down and then try ot run mount
21ab4e
         with running volume , mount command is hung.
21ab4e
21ab4e
Solution: After enable brick mux server has shared one data structure server_conf
21ab4e
          for all associated subvolumes.After down any subvolume in some
21ab4e
          ungraceful manner (remove brick directory) posix xlator sends
21ab4e
          GF_EVENT_CHILD_DOWN event to parent xlatros and server notify
21ab4e
          updates the child_up to false in server_conf.When client is trying
21ab4e
          to communicate with server through mount it checks conf->child_up
21ab4e
          and it is FALSE so it throws message "translator are not yet ready".
21ab4e
          From this patch updated structure server_conf to save child_up status
21ab4e
          for xlator wise. Another improtant correction from this patch is
21ab4e
          cleanup threads from server side xlators after stop the volume.
21ab4e
21ab4e
> BUG: 1453977
21ab4e
> Change-Id: Ic54da3f01881b7c9429ce92cc569236eb1d43e0d
21ab4e
> Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
21ab4e
> Reviewed-on: https://review.gluster.org/17356
21ab4e
> Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
21ab4e
> Reviewed-by: Raghavendra Talur <rtalur@redhat.com>
21ab4e
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> Reviewed-by: Jeff Darcy <jeff@pl.atyp.us>
21ab4e
> Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
21ab4e
> (cherry picked from commit dba55ae364a2772904bb68a6bd0ea87289ee1470)
21ab4e
21ab4e
BUG: 1451598
21ab4e
Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
21ab4e
21ab4e
Change-Id: I174110264de74bb76ffdb635da797cf55fe65ee5
21ab4e
Signed-off-by: moagrawa <moagrawa@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/108021
21ab4e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
---
21ab4e
 glusterfsd/src/glusterfsd-mgmt.c                   | 113 +++++++++++----------
21ab4e
 libglusterfs/src/defaults-tmpl.c                   |  11 ++
21ab4e
 rpc/xdr/src/glusterfs-fops.x                       |   4 +-
21ab4e
 .../bug-1444596_brick_mux_posix_hlth_chk_status.t  |   3 +
21ab4e
 xlators/features/bit-rot/src/stub/bit-rot-stub.c   |  31 ++++++
21ab4e
 xlators/features/changelog/src/changelog.c         |  15 +++
21ab4e
 .../changetimerecorder/src/changetimerecorder.c    |  26 +++++
21ab4e
 xlators/features/index/src/index.c                 |  22 +++-
21ab4e
 xlators/features/index/src/index.h                 |   1 +
21ab4e
 xlators/mgmt/glusterd/src/glusterd.c               |   2 +-
21ab4e
 xlators/performance/io-threads/src/io-threads.c    |   3 +-
21ab4e
 xlators/protocol/server/src/Makefile.am            |   3 +-
21ab4e
 xlators/protocol/server/src/server-handshake.c     |  24 +++--
21ab4e
 xlators/protocol/server/src/server-mem-types.h     |   1 +
21ab4e
 xlators/protocol/server/src/server-messages.h      |  10 +-
21ab4e
 xlators/protocol/server/src/server.c               |  95 +++++++++++++++--
21ab4e
 xlators/protocol/server/src/server.h               |  10 +-
21ab4e
 xlators/storage/posix/src/posix-helpers.c          |  37 ++++---
21ab4e
 xlators/storage/posix/src/posix.c                  |  20 ++++
21ab4e
 19 files changed, 333 insertions(+), 98 deletions(-)
21ab4e
21ab4e
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
21ab4e
index 6256030..365706e 100644
21ab4e
--- a/glusterfsd/src/glusterfsd-mgmt.c
21ab4e
+++ b/glusterfsd/src/glusterfsd-mgmt.c
21ab4e
@@ -200,10 +200,11 @@ glusterfs_handle_terminate (rpcsvc_request_t *req)
21ab4e
 {
21ab4e
         gd1_mgmt_brick_op_req   xlator_req      = {0,};
21ab4e
         ssize_t                 ret;
21ab4e
-        xlator_t                *top = NULL;
21ab4e
-        xlator_t                *victim = NULL;
21ab4e
-        glusterfs_ctx_t         *ctx    = NULL;
21ab4e
-        xlator_list_t           **trav_p;
21ab4e
+        glusterfs_ctx_t         *ctx            = NULL;
21ab4e
+        xlator_t                *top            = NULL;
21ab4e
+        xlator_t                *victim         = NULL;
21ab4e
+        xlator_list_t           **trav_p        = NULL;
21ab4e
+        gf_boolean_t            lockflag        = _gf_false;
21ab4e
 
21ab4e
         ret = xdr_to_generic (req->msg[0], &xlator_req,
21ab4e
                               (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
21ab4e
@@ -216,57 +217,54 @@ glusterfs_handle_terminate (rpcsvc_request_t *req)
21ab4e
         LOCK (&ctx->volfile_lock);
21ab4e
         {
21ab4e
                 /* Find the xlator_list_t that points to our victim. */
21ab4e
-                top = glusterfsd_ctx->active->first;
21ab4e
-                for (trav_p = &top->children; *trav_p;
21ab4e
-                     trav_p = &(*trav_p)->next) {
21ab4e
-                        victim = (*trav_p)->xlator;
21ab4e
-                        if (strcmp (victim->name, xlator_req.name) == 0) {
21ab4e
-                                break;
21ab4e
+                if (glusterfsd_ctx->active) {
21ab4e
+                        top = glusterfsd_ctx->active->first;
21ab4e
+                        for (trav_p = &top->children; *trav_p;
21ab4e
+                                                    trav_p = &(*trav_p)->next) {
21ab4e
+                                victim = (*trav_p)->xlator;
21ab4e
+                                if (strcmp (victim->name, xlator_req.name) == 0) {
21ab4e
+                                        break;
21ab4e
+                                }
21ab4e
                         }
21ab4e
                 }
21ab4e
-
21ab4e
-                if (!*trav_p) {
21ab4e
-                        gf_log (THIS->name, GF_LOG_ERROR,
21ab4e
-                                "can't terminate %s - not found",
21ab4e
-                                xlator_req.name);
21ab4e
-                        /*
21ab4e
-                         * Used to be -ENOENT.  However, the caller asked us to
21ab4e
-                         * make sure it's down and if it's already down that's
21ab4e
-                         * good enough.
21ab4e
-                         */
21ab4e
-                        glusterfs_terminate_response_send (req, 0);
21ab4e
-                        goto err;
21ab4e
-                }
21ab4e
-
21ab4e
+        }
21ab4e
+        if (!*trav_p) {
21ab4e
+                gf_log (THIS->name, GF_LOG_ERROR,
21ab4e
+                        "can't terminate %s - not found",
21ab4e
+                          xlator_req.name);
21ab4e
+                /*
21ab4e
+                 * Used to be -ENOENT.  However, the caller asked us to
21ab4e
+                 * make sure it's down and if it's already down that's
21ab4e
+                 * good enough.
21ab4e
+                 */
21ab4e
                 glusterfs_terminate_response_send (req, 0);
21ab4e
-                if ((trav_p == &top->children) && !(*trav_p)->next) {
21ab4e
-                        gf_log (THIS->name, GF_LOG_INFO,
21ab4e
-                                "terminating after loss of last child %s",
21ab4e
-                                xlator_req.name);
21ab4e
-                        glusterfs_mgmt_pmap_signout (glusterfsd_ctx,
21ab4e
-                                                     xlator_req.name);
21ab4e
-                        kill (getpid(), SIGTERM);
21ab4e
-                } else {
21ab4e
-                        /*
21ab4e
-                         * This is terribly unsafe without quiescing or shutting
21ab4e
-                         * things down properly but it gets us to the point
21ab4e
-                         * where we can test other stuff.
21ab4e
-                         *
21ab4e
-                         * TBD: finish implementing this "detach" code properly
21ab4e
-                         */
21ab4e
-                        gf_log (THIS->name, GF_LOG_INFO, "detaching not-only"
21ab4e
-                                " child %s", xlator_req.name);
21ab4e
-                        top->notify (top, GF_EVENT_TRANSPORT_CLEANUP, victim);
21ab4e
-                        glusterfs_mgmt_pmap_signout (glusterfsd_ctx,
21ab4e
-                                                     xlator_req.name);
21ab4e
-
21ab4e
-                        *trav_p = (*trav_p)->next;
21ab4e
-                        glusterfs_autoscale_threads (THIS->ctx, -1);
21ab4e
-                }
21ab4e
+                goto err;
21ab4e
+        }
21ab4e
 
21ab4e
+        glusterfs_terminate_response_send (req, 0);
21ab4e
+        if ((trav_p == &top->children) && !(*trav_p)->next) {
21ab4e
+                gf_log (THIS->name, GF_LOG_INFO,
21ab4e
+                        "terminating after loss of last child %s",
21ab4e
+                        xlator_req.name);
21ab4e
+                glusterfs_mgmt_pmap_signout (glusterfsd_ctx, xlator_req.name);
21ab4e
+                kill (getpid(), SIGTERM);
21ab4e
+        } else {
21ab4e
+                /*
21ab4e
+                 * This is terribly unsafe without quiescing or shutting
21ab4e
+                 * things down properly but it gets us to the point
21ab4e
+                 * where we can test other stuff.
21ab4e
+                 *
21ab4e
+                 * TBD: finish implementing this "detach" code properly
21ab4e
+                 */
21ab4e
+                UNLOCK (&ctx->volfile_lock);
21ab4e
+                lockflag = _gf_true;
21ab4e
+                gf_log (THIS->name, GF_LOG_INFO, "detaching not-only"
21ab4e
+                         " child %s", xlator_req.name);
21ab4e
+                top->notify (top, GF_EVENT_CLEANUP, victim);
21ab4e
         }
21ab4e
 err:
21ab4e
-        UNLOCK (&ctx->volfile_lock);
21ab4e
+        if (!lockflag)
21ab4e
+                UNLOCK (&ctx->volfile_lock);
21ab4e
         free (xlator_req.name);
21ab4e
         xlator_req.name = NULL;
21ab4e
         return 0;
21ab4e
@@ -840,6 +838,7 @@ glusterfs_handle_attach (rpcsvc_request_t *req)
21ab4e
         int32_t                 ret             = -1;
21ab4e
         gd1_mgmt_brick_op_req   xlator_req      = {0,};
21ab4e
         xlator_t                *this           = NULL;
21ab4e
+        xlator_t                *nextchild      = NULL;
21ab4e
         glusterfs_graph_t       *newgraph       = NULL;
21ab4e
         glusterfs_ctx_t         *ctx            = NULL;
21ab4e
 
21ab4e
@@ -864,15 +863,19 @@ glusterfs_handle_attach (rpcsvc_request_t *req)
21ab4e
                         gf_log (this->name, GF_LOG_INFO,
21ab4e
                                 "got attach for %s", xlator_req.name);
21ab4e
                         ret = glusterfs_graph_attach (this->ctx->active,
21ab4e
-                                                      xlator_req.name,
21ab4e
-                                                      &newgraph);
21ab4e
-                        if (ret == 0) {
21ab4e
-                                ret = glusterfs_graph_parent_up (newgraph);
21ab4e
+                                              xlator_req.name, &newgraph);
21ab4e
+                        if (!ret && (newgraph && newgraph->first)) {
21ab4e
+                                nextchild = newgraph->first;
21ab4e
+                                ret = xlator_notify (nextchild,
21ab4e
+                                                     GF_EVENT_PARENT_UP,
21ab4e
+                                                     nextchild);
21ab4e
                                 if (ret) {
21ab4e
-                                        gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
+                                        gf_msg (this->name, GF_LOG_ERROR,
21ab4e
+                                                0,
21ab4e
                                                 LG_MSG_EVENT_NOTIFY_FAILED,
21ab4e
                                                 "Parent up notification "
21ab4e
-                                                "failed");
21ab4e
+                                                "failed for %s ",
21ab4e
+                                                nextchild->name);
21ab4e
                                         goto out;
21ab4e
                                 }
21ab4e
                                 glusterfs_autoscale_threads (this->ctx, 1);
21ab4e
diff --git a/libglusterfs/src/defaults-tmpl.c b/libglusterfs/src/defaults-tmpl.c
21ab4e
index 5b7578b..7454bc8 100644
21ab4e
--- a/libglusterfs/src/defaults-tmpl.c
21ab4e
+++ b/libglusterfs/src/defaults-tmpl.c
21ab4e
@@ -170,6 +170,17 @@ default_notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
                 }
21ab4e
         }
21ab4e
         break;
21ab4e
+        case GF_EVENT_CLEANUP:
21ab4e
+        {
21ab4e
+                xlator_list_t *list = this->children;
21ab4e
+
21ab4e
+                while (list) {
21ab4e
+                        xlator_notify (list->xlator, event, this);
21ab4e
+                        list = list->next;
21ab4e
+                }
21ab4e
+        }
21ab4e
+        break;
21ab4e
+
21ab4e
         default:
21ab4e
         {
21ab4e
                 xlator_list_t *parent = this->parents;
21ab4e
diff --git a/rpc/xdr/src/glusterfs-fops.x b/rpc/xdr/src/glusterfs-fops.x
21ab4e
index c8f00f0..2f8f4ca 100644
21ab4e
--- a/rpc/xdr/src/glusterfs-fops.x
21ab4e
+++ b/rpc/xdr/src/glusterfs-fops.x
21ab4e
@@ -63,7 +63,7 @@ enum glusterfs_fop_t {
21ab4e
 };
21ab4e
 
21ab4e
 /* Note: Removed event GF_EVENT_CHILD_MODIFIED=8, hence
21ab4e
- *to preserve backward compatibiliy, GF_EVENT_TRANSPORT_CLEANUP = 9
21ab4e
+ *to preserve backward compatibiliy, GF_EVEN_CLEANUP = 9
21ab4e
  */
21ab4e
 enum glusterfs_event_t {
21ab4e
         GF_EVENT_PARENT_UP = 1,
21ab4e
@@ -73,7 +73,7 @@ enum glusterfs_event_t {
21ab4e
         GF_EVENT_CHILD_UP,
21ab4e
         GF_EVENT_CHILD_DOWN,
21ab4e
         GF_EVENT_CHILD_CONNECTING,
21ab4e
-        GF_EVENT_TRANSPORT_CLEANUP = 9,
21ab4e
+        GF_EVENT_CLEANUP = 9,
21ab4e
         GF_EVENT_TRANSPORT_CONNECTED,
21ab4e
         GF_EVENT_VOLFILE_MODIFIED,
21ab4e
         GF_EVENT_GRAPH_NEW,
21ab4e
diff --git a/tests/bugs/glusterd/bug-1444596_brick_mux_posix_hlth_chk_status.t b/tests/bugs/glusterd/bug-1444596_brick_mux_posix_hlth_chk_status.t
21ab4e
index 39ab2dd..e082ba1 100644
21ab4e
--- a/tests/bugs/glusterd/bug-1444596_brick_mux_posix_hlth_chk_status.t
21ab4e
+++ b/tests/bugs/glusterd/bug-1444596_brick_mux_posix_hlth_chk_status.t
21ab4e
@@ -34,6 +34,9 @@ EXPECT_WITHIN $PROCESS_UP_TIMEOUT 2 count_up_bricks $V1
21ab4e
 
21ab4e
 EXPECT 1 count_brick_processes
21ab4e
 
21ab4e
+TEST glusterfs -s $H0 --volfile-id $V1 $M0
21ab4e
+TEST touch $M0/file{1..10}
21ab4e
+
21ab4e
 pkill glusterd
21ab4e
 TEST glusterd -LDEBUG
21ab4e
 sleep 5
21ab4e
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.c b/xlators/features/bit-rot/src/stub/bit-rot-stub.c
21ab4e
index 2f2a3d5..ed8251b 100644
21ab4e
--- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c
21ab4e
+++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c
21ab4e
@@ -10,6 +10,7 @@
21ab4e
 
21ab4e
 #include <ctype.h>
21ab4e
 #include <sys/uio.h>
21ab4e
+#include <signal.h>
21ab4e
 
21ab4e
 #include "glusterfs.h"
21ab4e
 #include "xlator.h"
21ab4e
@@ -214,6 +215,36 @@ out:
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
+
21ab4e
+int
21ab4e
+notify (xlator_t *this, int event, void *data, ...)
21ab4e
+{
21ab4e
+        br_stub_private_t *priv = NULL;
21ab4e
+
21ab4e
+        if (!this)
21ab4e
+                return 0;
21ab4e
+
21ab4e
+        priv = this->private;
21ab4e
+        if (!priv)
21ab4e
+                return 0;
21ab4e
+
21ab4e
+        switch (event) {
21ab4e
+        case GF_EVENT_CLEANUP:
21ab4e
+                if (priv->signth) {
21ab4e
+                        (void) gf_thread_cleanup_xint (priv->signth);
21ab4e
+                        priv->signth = 0;
21ab4e
+                }
21ab4e
+                if (priv->container.thread) {
21ab4e
+                        (void) gf_thread_cleanup_xint (priv->container.thread);
21ab4e
+                        priv->container.thread = 0;
21ab4e
+                }
21ab4e
+                break;
21ab4e
+        }
21ab4e
+        default_notify (this, event, data);
21ab4e
+        return 0;
21ab4e
+}
21ab4e
+
21ab4e
+
21ab4e
 void
21ab4e
 fini (xlator_t *this)
21ab4e
 {
21ab4e
diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c
21ab4e
index e74da78..8817359 100644
21ab4e
--- a/xlators/features/changelog/src/changelog.c
21ab4e
+++ b/xlators/features/changelog/src/changelog.c
21ab4e
@@ -2104,6 +2104,7 @@ notify (xlator_t *this, int event, void *data, ...)
21ab4e
         int                     ret             = 0;
21ab4e
         int                     ret1            = 0;
21ab4e
         struct list_head        queue           = {0, };
21ab4e
+        int                     i               = 0;
21ab4e
 
21ab4e
         INIT_LIST_HEAD (&queue);
21ab4e
 
21ab4e
@@ -2111,6 +2112,20 @@ notify (xlator_t *this, int event, void *data, ...)
21ab4e
         if (!priv)
21ab4e
                 goto out;
21ab4e
 
21ab4e
+        if (event == GF_EVENT_CLEANUP) {
21ab4e
+                if (priv->connector) {
21ab4e
+                        (void) gf_thread_cleanup_xint (priv->connector);
21ab4e
+                        priv->connector = 0;
21ab4e
+                }
21ab4e
+
21ab4e
+                for (; i < NR_DISPATCHERS; i++) {
21ab4e
+                        if (priv->ev_dispatcher[i]) {
21ab4e
+                                (void) gf_thread_cleanup_xint (priv->ev_dispatcher[i]);
21ab4e
+                                priv->ev_dispatcher[i] = 0;
21ab4e
+                        }
21ab4e
+               }
21ab4e
+        }
21ab4e
+
21ab4e
         if (event == GF_EVENT_TRANSLATOR_OP) {
21ab4e
 
21ab4e
                 dict = data;
21ab4e
diff --git a/xlators/features/changetimerecorder/src/changetimerecorder.c b/xlators/features/changetimerecorder/src/changetimerecorder.c
21ab4e
index dba4265..ac2406f 100644
21ab4e
--- a/xlators/features/changetimerecorder/src/changetimerecorder.c
21ab4e
+++ b/xlators/features/changetimerecorder/src/changetimerecorder.c
21ab4e
@@ -2162,6 +2162,32 @@ out:
21ab4e
         return 0;
21ab4e
 }
21ab4e
 
21ab4e
+int
21ab4e
+notify (xlator_t *this, int event, void *data, ...)
21ab4e
+{
21ab4e
+
21ab4e
+        gf_ctr_private_t *priv = NULL;
21ab4e
+        int               ret  = 0;
21ab4e
+
21ab4e
+        priv = this->private;
21ab4e
+
21ab4e
+        if (!priv)
21ab4e
+                goto out;
21ab4e
+
21ab4e
+        if (event == GF_EVENT_CLEANUP) {
21ab4e
+                if (fini_db (priv->_db_conn)) {
21ab4e
+                        gf_msg (this->name, GF_LOG_WARNING, 0,
21ab4e
+                                CTR_MSG_CLOSE_DB_CONN_FAILED, "Failed closing "
21ab4e
+                                "db connection");
21ab4e
+                }
21ab4e
+        } else  {
21ab4e
+                ret = default_notify (this, event, data);
21ab4e
+        }
21ab4e
+out:
21ab4e
+        return ret;
21ab4e
+
21ab4e
+}
21ab4e
+
21ab4e
 int32_t
21ab4e
 mem_acct_init (xlator_t *this)
21ab4e
 {
21ab4e
diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c
21ab4e
index f68dd55..ef5a60c 100644
21ab4e
--- a/xlators/features/index/src/index.c
21ab4e
+++ b/xlators/features/index/src/index.c
21ab4e
@@ -2270,7 +2270,6 @@ init (xlator_t *this)
21ab4e
         int ret = -1;
21ab4e
         int64_t count = -1;
21ab4e
         index_priv_t *priv = NULL;
21ab4e
-        pthread_t thread;
21ab4e
         pthread_attr_t  w_attr;
21ab4e
         gf_boolean_t    mutex_inited = _gf_false;
21ab4e
         gf_boolean_t    cond_inited  = _gf_false;
21ab4e
@@ -2380,7 +2379,7 @@ init (xlator_t *this)
21ab4e
         count = index_fetch_link_count (this, XATTROP);
21ab4e
         index_set_link_count (priv, count, XATTROP);
21ab4e
 
21ab4e
-        ret = gf_thread_create (&thread, &w_attr, index_worker, this);
21ab4e
+        ret = gf_thread_create (&priv->thread, &w_attr, index_worker, this);
21ab4e
         if (ret) {
21ab4e
                 gf_log (this->name, GF_LOG_WARNING, "Failed to create "
21ab4e
                         "worker thread, aborting");
21ab4e
@@ -2490,6 +2489,25 @@ int
21ab4e
 notify (xlator_t *this, int event, void *data, ...)
21ab4e
 {
21ab4e
         int     ret = 0;
21ab4e
+        index_priv_t *priv = NULL;
21ab4e
+
21ab4e
+        if (!this)
21ab4e
+                return 0;
21ab4e
+
21ab4e
+        priv = this->private;
21ab4e
+        if (!priv)
21ab4e
+                return 0;
21ab4e
+
21ab4e
+        switch (event) {
21ab4e
+        case GF_EVENT_CLEANUP:
21ab4e
+                if (priv->thread) {
21ab4e
+                        (void) gf_thread_cleanup_xint (priv->thread);
21ab4e
+                        priv->thread = 0;
21ab4e
+                }
21ab4e
+                break;
21ab4e
+        }
21ab4e
+
21ab4e
+
21ab4e
         ret = default_notify (this, event, data);
21ab4e
         return ret;
21ab4e
 }
21ab4e
diff --git a/xlators/features/index/src/index.h b/xlators/features/index/src/index.h
21ab4e
index 5fb5a65..f622cec 100644
21ab4e
--- a/xlators/features/index/src/index.h
21ab4e
+++ b/xlators/features/index/src/index.h
21ab4e
@@ -60,6 +60,7 @@ typedef struct index_priv {
21ab4e
         dict_t  *pending_watchlist;
21ab4e
         dict_t  *complete_watchlist;
21ab4e
         int64_t  pending_count;
21ab4e
+        pthread_t thread;
21ab4e
 } index_priv_t;
21ab4e
 
21ab4e
 typedef struct index_local {
21ab4e
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
21ab4e
index cba1e06..f718d36 100644
21ab4e
--- a/xlators/mgmt/glusterd/src/glusterd.c
21ab4e
+++ b/xlators/mgmt/glusterd/src/glusterd.c
21ab4e
@@ -1973,7 +1973,7 @@ notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
                 case GF_EVENT_POLLERR:
21ab4e
                         break;
21ab4e
 
21ab4e
-                case GF_EVENT_TRANSPORT_CLEANUP:
21ab4e
+                case GF_EVENT_CLEANUP:
21ab4e
                         break;
21ab4e
 
21ab4e
                 default:
21ab4e
diff --git a/xlators/performance/io-threads/src/io-threads.c b/xlators/performance/io-threads/src/io-threads.c
21ab4e
index 72a8208..5e81265 100644
21ab4e
--- a/xlators/performance/io-threads/src/io-threads.c
21ab4e
+++ b/xlators/performance/io-threads/src/io-threads.c
21ab4e
@@ -1046,7 +1046,8 @@ notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
 {
21ab4e
         iot_conf_t *conf = this->private;
21ab4e
 
21ab4e
-        if (GF_EVENT_PARENT_DOWN == event)
21ab4e
+        if ((GF_EVENT_PARENT_DOWN == event) ||
21ab4e
+            (GF_EVENT_CLEANUP == event))
21ab4e
                 iot_exit_threads (conf);
21ab4e
 
21ab4e
         default_notify (this, event, data);
21ab4e
diff --git a/xlators/protocol/server/src/Makefile.am b/xlators/protocol/server/src/Makefile.am
21ab4e
index bb46fda..6981ffa 100644
21ab4e
--- a/xlators/protocol/server/src/Makefile.am
21ab4e
+++ b/xlators/protocol/server/src/Makefile.am
21ab4e
@@ -21,7 +21,8 @@ AM_CPPFLAGS = $(GF_CPPFLAGS) \
21ab4e
 	-DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \
21ab4e
 	-I$(top_srcdir)/xlators/protocol/lib/src \
21ab4e
 	-I$(top_srcdir)/rpc/rpc-lib/src \
21ab4e
-	-I$(top_srcdir)/rpc/xdr/src
21ab4e
+	-I$(top_srcdir)/rpc/xdr/src \
21ab4e
+        -I$(top_srcdir)/glusterfsd/src
21ab4e
 
21ab4e
 AM_CFLAGS = -Wall $(GF_CFLAGS) \
21ab4e
             -DDATADIR=\"$(localstatedir)\"
21ab4e
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c
21ab4e
index f00804a..f8f8f99 100644
21ab4e
--- a/xlators/protocol/server/src/server-handshake.c
21ab4e
+++ b/xlators/protocol/server/src/server-handshake.c
21ab4e
@@ -413,6 +413,7 @@ server_setvolume (rpcsvc_request_t *req)
21ab4e
         int32_t              fop_version   = 0;
21ab4e
         int32_t              mgmt_version  = 0;
21ab4e
         glusterfs_ctx_t     *ctx           = NULL;
21ab4e
+        struct  _child_status *tmp         = NULL;
21ab4e
 
21ab4e
         params = dict_new ();
21ab4e
         reply  = dict_new ();
21ab4e
@@ -512,13 +513,24 @@ server_setvolume (rpcsvc_request_t *req)
21ab4e
                                       "initialised yet. Try again later");
21ab4e
                 goto fail;
21ab4e
         }
21ab4e
-
21ab4e
-        ret = dict_set_int32 (reply, "child_up", conf->child_up);
21ab4e
-        if (ret < 0)
21ab4e
+        list_for_each_entry (tmp, &conf->child_status->status_list,
21ab4e
+                                                                  status_list) {
21ab4e
+                if (strcmp (tmp->name, name) == 0)
21ab4e
+                        break;
21ab4e
+        }
21ab4e
+        if (!tmp->name) {
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
-                        PS_MSG_DICT_GET_FAILED, "Failed to set 'child_up' "
21ab4e
-                        "in the reply dict");
21ab4e
-
21ab4e
+                        PS_MSG_CHILD_STATUS_FAILED,
21ab4e
+                        "No xlator %s is found in "
21ab4e
+                        "child status list", name);
21ab4e
+        } else {
21ab4e
+                ret = dict_set_int32 (reply, "child_up", tmp->child_up);
21ab4e
+                if (ret < 0)
21ab4e
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
+                                PS_MSG_DICT_GET_FAILED,
21ab4e
+                                "Failed to set 'child_up' for xlator %s "
21ab4e
+                                "in the reply dict", tmp->name);
21ab4e
+        }
21ab4e
         ret = dict_get_str (params, "process-uuid", &client_uid);
21ab4e
         if (ret < 0) {
21ab4e
                 ret = dict_set_str (reply, "ERROR",
21ab4e
diff --git a/xlators/protocol/server/src/server-mem-types.h b/xlators/protocol/server/src/server-mem-types.h
21ab4e
index 9165249..76a78ac 100644
21ab4e
--- a/xlators/protocol/server/src/server-mem-types.h
21ab4e
+++ b/xlators/protocol/server/src/server-mem-types.h
21ab4e
@@ -28,6 +28,7 @@ enum gf_server_mem_types_ {
21ab4e
         gf_server_mt_setvolume_rsp_t,
21ab4e
         gf_server_mt_lock_mig_t,
21ab4e
         gf_server_mt_compound_rsp_t,
21ab4e
+        gf_server_mt_child_status,
21ab4e
         gf_server_mt_end,
21ab4e
 };
21ab4e
 #endif /* __SERVER_MEM_TYPES_H__ */
21ab4e
diff --git a/xlators/protocol/server/src/server-messages.h b/xlators/protocol/server/src/server-messages.h
21ab4e
index b8245af..14729ad 100644
21ab4e
--- a/xlators/protocol/server/src/server-messages.h
21ab4e
+++ b/xlators/protocol/server/src/server-messages.h
21ab4e
@@ -40,7 +40,7 @@
21ab4e
  */
21ab4e
 
21ab4e
 #define GLFS_PS_BASE                GLFS_MSGID_COMP_PS
21ab4e
-#define GLFS_NUM_MESSAGES           91
21ab4e
+#define GLFS_NUM_MESSAGES           92
21ab4e
 #define GLFS_MSGID_END              (GLFS_PS_BASE + GLFS_NUM_MESSAGES + 1)
21ab4e
 /* Messages with message IDs */
21ab4e
 #define glfs_msg_start_x GLFS_PS_BASE, "Invalid: Start of messages"
21ab4e
@@ -857,6 +857,14 @@
21ab4e
  */
21ab4e
 
21ab4e
 #define PS_MSG_CLIENT_OPVERSION_GET_FAILED      (GLFS_PS_BASE + 91)
21ab4e
+
21ab4e
+/*!
21ab4e
+ * @messageid
21ab4e
+ * @diagnosis
21ab4e
+ * @recommendedaction
21ab4e
+ *
21ab4e
+ */
21ab4e
+#define PS_MSG_CHILD_STATUS_FAILED               (GLFS_PS_BASE + 92)
21ab4e
 /*------------*/
21ab4e
 #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
21ab4e
 
21ab4e
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
21ab4e
index 87a4252..6acf256 100644
21ab4e
--- a/xlators/protocol/server/src/server.c
21ab4e
+++ b/xlators/protocol/server/src/server.c
21ab4e
@@ -23,6 +23,7 @@
21ab4e
 #include "event.h"
21ab4e
 #include "events.h"
21ab4e
 #include "server-messages.h"
21ab4e
+#include "glusterfsd.h"
21ab4e
 
21ab4e
 rpcsvc_cbk_program_t server_cbk_prog = {
21ab4e
         .progname  = "Gluster Callback",
21ab4e
@@ -1072,7 +1073,9 @@ init (xlator_t *this)
21ab4e
         if (ret)
21ab4e
                 conf->conf_dir = CONFDIR;
21ab4e
 
21ab4e
-        conf->child_up = _gf_false;
21ab4e
+        conf->child_status = GF_CALLOC (1, sizeof (struct _child_status),
21ab4e
+                                          gf_server_mt_child_status);
21ab4e
+        INIT_LIST_HEAD (&conf->child_status->status_list);
21ab4e
 
21ab4e
         /*ret = dict_get_str (this->options, "statedump-path", &statedump_path);
21ab4e
         if (!ret) {
21ab4e
@@ -1396,10 +1399,15 @@ server_process_child_event (xlator_t *this, int32_t event, void *data,
21ab4e
         pthread_mutex_lock (&conf->mutex);
21ab4e
         {
21ab4e
                 list_for_each_entry (xprt, &conf->xprt_list, list) {
21ab4e
-                        rpcsvc_callback_submit (conf->rpc, xprt,
21ab4e
-                                                &server_cbk_prog,
21ab4e
-                                                cbk_procnum,
21ab4e
-                                                NULL, 0, NULL);
21ab4e
+                        if (!xprt->xl_private) {
21ab4e
+                                continue;
21ab4e
+                        }
21ab4e
+                        if (xprt->xl_private->bound_xl == data) {
21ab4e
+                                rpcsvc_callback_submit (conf->rpc, xprt,
21ab4e
+                                                        &server_cbk_prog,
21ab4e
+                                                        cbk_procnum,
21ab4e
+                                                        NULL, 0, NULL);
21ab4e
+                        }
21ab4e
                 }
21ab4e
         }
21ab4e
         pthread_mutex_unlock (&conf->mutex);
21ab4e
@@ -1420,6 +1428,13 @@ notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
         va_list          ap;
21ab4e
         rpc_transport_t  *xprt        = NULL;
21ab4e
         rpc_transport_t  *xp_next     = NULL;
21ab4e
+        xlator_t         *victim      = NULL;
21ab4e
+        xlator_t         *top         = NULL;
21ab4e
+        xlator_t         *travxl      = NULL;
21ab4e
+        xlator_list_t    **trav_p     = NULL;
21ab4e
+        struct  _child_status *tmp    = NULL;
21ab4e
+        gf_boolean_t     victim_found = _gf_false;
21ab4e
+        glusterfs_ctx_t  *ctx         = NULL;
21ab4e
 
21ab4e
         GF_VALIDATE_OR_GOTO (THIS->name, this, out);
21ab4e
         conf = this->private;
21ab4e
@@ -1429,6 +1444,8 @@ notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
         va_start (ap, data);
21ab4e
         output = va_arg (ap, dict_t*);
21ab4e
         va_end (ap);
21ab4e
+        victim = data;
21ab4e
+        ctx    = THIS->ctx;
21ab4e
 
21ab4e
         switch (event) {
21ab4e
         case GF_EVENT_UPCALL:
21ab4e
@@ -1457,7 +1474,24 @@ notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
 
21ab4e
         case GF_EVENT_CHILD_UP:
21ab4e
         {
21ab4e
-                conf->child_up = _gf_true;
21ab4e
+                list_for_each_entry (tmp, &conf->child_status->status_list,
21ab4e
+                                                                 status_list) {
21ab4e
+                        if (tmp->name == NULL)
21ab4e
+                                break;
21ab4e
+                        if (strcmp (tmp->name, victim->name) == 0)
21ab4e
+                                break;
21ab4e
+                }
21ab4e
+                if (tmp->name) {
21ab4e
+                        tmp->child_up = _gf_true;
21ab4e
+                } else {
21ab4e
+                        tmp  = GF_CALLOC (1, sizeof (struct _child_status),
21ab4e
+                                          gf_server_mt_child_status);
21ab4e
+                        INIT_LIST_HEAD (&tmp->status_list);
21ab4e
+                        tmp->name  = gf_strdup (victim->name);
21ab4e
+                        tmp->child_up = _gf_true;
21ab4e
+                        list_add_tail (&tmp->status_list,
21ab4e
+                                              &conf->child_status->status_list);
21ab4e
+                }
21ab4e
                 ret = server_process_child_event (this, event, data,
21ab4e
                                                   GF_CBK_CHILD_UP);
21ab4e
                 if (ret) {
21ab4e
@@ -1466,14 +1500,25 @@ notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
                                 "server_process_child_event failed");
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
-
21ab4e
                 default_notify (this, event, data);
21ab4e
                 break;
21ab4e
         }
21ab4e
 
21ab4e
         case GF_EVENT_CHILD_DOWN:
21ab4e
         {
21ab4e
-                conf->child_up = _gf_false;
21ab4e
+                list_for_each_entry (tmp, &conf->child_status->status_list,
21ab4e
+                                                                  status_list) {
21ab4e
+                        if (strcmp (tmp->name, victim->name) == 0) {
21ab4e
+                                tmp->child_up = _gf_false;
21ab4e
+                                break;
21ab4e
+                        }
21ab4e
+                }
21ab4e
+                if (!tmp->name)
21ab4e
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
+                                PS_MSG_CHILD_STATUS_FAILED,
21ab4e
+                                "No xlator %s is found in "
21ab4e
+                                "child status list", victim->name);
21ab4e
+
21ab4e
                 ret = server_process_child_event (this, event, data,
21ab4e
                                                   GF_CBK_CHILD_DOWN);
21ab4e
                 if (ret) {
21ab4e
@@ -1482,13 +1527,12 @@ notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
                                 "server_process_child_event failed");
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
-
21ab4e
                 default_notify (this, event, data);
21ab4e
                 break;
21ab4e
 
21ab4e
         }
21ab4e
 
21ab4e
-        case GF_EVENT_TRANSPORT_CLEANUP:
21ab4e
+        case GF_EVENT_CLEANUP:
21ab4e
                 conf = this->private;
21ab4e
                 pthread_mutex_lock (&conf->mutex);
21ab4e
                 /*
21ab4e
@@ -1509,8 +1553,37 @@ notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
                                 rpc_transport_disconnect (xprt, _gf_false);
21ab4e
                         }
21ab4e
                 }
21ab4e
+                list_for_each_entry (tmp, &conf->child_status->status_list,
21ab4e
+                                                                 status_list) {
21ab4e
+                        if (strcmp (tmp->name, victim->name) == 0)
21ab4e
+                                break;
21ab4e
+                }
21ab4e
+                if (tmp->name && (strcmp (tmp->name, victim->name) == 0)) {
21ab4e
+                        GF_FREE (tmp->name);
21ab4e
+                        list_del (&tmp->status_list);
21ab4e
+                }
21ab4e
                 pthread_mutex_unlock (&conf->mutex);
21ab4e
-                /* NB: do *not* propagate anywhere else */
21ab4e
+                if (this->ctx->active) {
21ab4e
+                        top = this->ctx->active->first;
21ab4e
+                        LOCK (&ctx->volfile_lock);
21ab4e
+                                for (trav_p = &top->children; *trav_p;
21ab4e
+                                                   trav_p = &(*trav_p)->next) {
21ab4e
+                                        travxl = (*trav_p)->xlator;
21ab4e
+                                        if (travxl &&
21ab4e
+                                                   strcmp (travxl->name, victim->name) == 0) {
21ab4e
+                                                victim_found = _gf_true;
21ab4e
+                                                break;
21ab4e
+                                        }
21ab4e
+                                }
21ab4e
+                        UNLOCK (&ctx->volfile_lock);
21ab4e
+                        if (victim_found)
21ab4e
+                                (*trav_p) = (*trav_p)->next;
21ab4e
+                        glusterfs_mgmt_pmap_signout (glusterfsd_ctx,
21ab4e
+                                                     victim->name);
21ab4e
+                        glusterfs_autoscale_threads (THIS->ctx, -1);
21ab4e
+                        default_notify (victim, GF_EVENT_CLEANUP, data);
21ab4e
+
21ab4e
+                }
21ab4e
                 break;
21ab4e
 
21ab4e
         default:
21ab4e
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
21ab4e
index 3272106..b419b05 100644
21ab4e
--- a/xlators/protocol/server/src/server.h
21ab4e
+++ b/xlators/protocol/server/src/server.h
21ab4e
@@ -73,6 +73,13 @@ struct _volfile_ctx {
21ab4e
         uint32_t             checksum;
21ab4e
 };
21ab4e
 
21ab4e
+struct _child_status {
21ab4e
+        struct list_head status_list;
21ab4e
+        char *name;
21ab4e
+        gf_boolean_t child_up;
21ab4e
+
21ab4e
+};
21ab4e
+
21ab4e
 struct server_conf {
21ab4e
         rpcsvc_t               *rpc;
21ab4e
         struct rpcsvc_config    rpc_conf;
21ab4e
@@ -101,8 +108,7 @@ struct server_conf {
21ab4e
                                             * in case if volume set options
21ab4e
                                             * (say *.allow | *.reject) are
21ab4e
                                             * tweeked */
21ab4e
-        gf_boolean_t            child_up; /* Set to true, when child is up, and
21ab4e
-                                           * false, when child is down */
21ab4e
+        struct _child_status    *child_status;
21ab4e
 
21ab4e
         gf_lock_t               itable_lock;
21ab4e
 };
21ab4e
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
21ab4e
index 0c50967..30f09ac 100644
21ab4e
--- a/xlators/storage/posix/src/posix-helpers.c
21ab4e
+++ b/xlators/storage/posix/src/posix-helpers.c
21ab4e
@@ -1849,9 +1849,11 @@ posix_health_check_thread_proc (void *data)
21ab4e
         xlator_list_t       **trav_p             = NULL;
21ab4e
         int                   count              = 0;
21ab4e
         gf_boolean_t          victim_found       = _gf_false;
21ab4e
+        glusterfs_ctx_t      *ctx                = NULL;
21ab4e
 
21ab4e
         this = data;
21ab4e
         priv = this->private;
21ab4e
+        ctx  = THIS->ctx;
21ab4e
 
21ab4e
         /* prevent races when the interval is updated */
21ab4e
         interval = priv->health_check_interval;
21ab4e
@@ -1860,7 +1862,6 @@ posix_health_check_thread_proc (void *data)
21ab4e
 
21ab4e
         gf_msg_debug (this->name, 0, "health-check thread started, "
21ab4e
                 "interval = %d seconds", interval);
21ab4e
-
21ab4e
         while (1) {
21ab4e
                 /* aborting sleep() is a request to exit this thread, sleep()
21ab4e
                  * will normally not return when cancelled */
21ab4e
@@ -1902,10 +1903,12 @@ abort:
21ab4e
         */
21ab4e
         if (this->ctx->active) {
21ab4e
                 top = this->ctx->active->first;
21ab4e
-                for (trav_p = &top->children; *trav_p;
21ab4e
+                LOCK (&ctx->volfile_lock);
21ab4e
+                        for (trav_p = &top->children; *trav_p;
21ab4e
                                                trav_p = &(*trav_p)->next) {
21ab4e
-                        count++;
21ab4e
-                }
21ab4e
+                                count++;
21ab4e
+                        }
21ab4e
+                UNLOCK (&ctx->volfile_lock);
21ab4e
         }
21ab4e
 
21ab4e
         if (count == 1) {
21ab4e
@@ -1925,26 +1928,28 @@ abort:
21ab4e
                         kill (getpid(), SIGKILL);
21ab4e
 
21ab4e
         } else {
21ab4e
-                for (trav_p = &top->children; *trav_p;
21ab4e
-                     trav_p = &(*trav_p)->next) {
21ab4e
-                        victim = (*trav_p)->xlator;
21ab4e
-                        if (victim &&
21ab4e
-                            strcmp (victim->name, priv->base_path) == 0) {
21ab4e
-                                victim_found = _gf_true;
21ab4e
-                                break;
21ab4e
+                LOCK (&ctx->volfile_lock);
21ab4e
+                        for (trav_p = &top->children; *trav_p;
21ab4e
+                             trav_p = &(*trav_p)->next) {
21ab4e
+                                victim = (*trav_p)->xlator;
21ab4e
+                                if (victim &&
21ab4e
+                                         strcmp (victim->name, priv->base_path) == 0) {
21ab4e
+                                        victim_found = _gf_true;
21ab4e
+                                        break;
21ab4e
+                                }
21ab4e
                         }
21ab4e
-                }
21ab4e
+                UNLOCK (&ctx->volfile_lock);
21ab4e
                 if (victim_found) {
21ab4e
-                        top->notify (top, GF_EVENT_TRANSPORT_CLEANUP, victim);
21ab4e
-                        glusterfs_mgmt_pmap_signout (glusterfsd_ctx,
21ab4e
-                                                     priv->base_path);
21ab4e
-                        glusterfs_autoscale_threads (THIS->ctx, -1);
21ab4e
+                        gf_log (THIS->name, GF_LOG_INFO, "detaching not-only "
21ab4e
+                                " child %s", priv->base_path);
21ab4e
+                        top->notify (top, GF_EVENT_CLEANUP, victim);
21ab4e
                 }
21ab4e
         }
21ab4e
 
21ab4e
         return NULL;
21ab4e
 }
21ab4e
 
21ab4e
+
21ab4e
 void
21ab4e
 posix_spawn_health_check_thread (xlator_t *xl)
21ab4e
 {
21ab4e
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
21ab4e
index 95eaf0c..ecc45f0 100644
21ab4e
--- a/xlators/storage/posix/src/posix.c
21ab4e
+++ b/xlators/storage/posix/src/posix.c
21ab4e
@@ -6588,6 +6588,9 @@ notify (xlator_t *this,
21ab4e
         void *data,
21ab4e
         ...)
21ab4e
 {
21ab4e
+        struct posix_private *priv = NULL;
21ab4e
+
21ab4e
+        priv = this->private;
21ab4e
         switch (event)
21ab4e
         {
21ab4e
         case GF_EVENT_PARENT_UP:
21ab4e
@@ -6596,6 +6599,23 @@ notify (xlator_t *this,
21ab4e
                 default_notify (this, GF_EVENT_CHILD_UP, data);
21ab4e
         }
21ab4e
         break;
21ab4e
+        case GF_EVENT_CLEANUP:
21ab4e
+                if (priv->health_check) {
21ab4e
+                        pthread_cancel (priv->health_check);
21ab4e
+                        priv->health_check = 0;
21ab4e
+                }
21ab4e
+                if (priv->janitor) {
21ab4e
+                        (void) gf_thread_cleanup_xint (priv->janitor);
21ab4e
+                        priv->janitor = 0;
21ab4e
+                }
21ab4e
+                if (priv->fsyncer) {
21ab4e
+                        (void) gf_thread_cleanup_xint (priv->fsyncer);
21ab4e
+                        priv->fsyncer = 0;
21ab4e
+                }
21ab4e
+                if (priv->mount_lock)
21ab4e
+                        (void) sys_closedir (priv->mount_lock);
21ab4e
+
21ab4e
+        break;
21ab4e
         default:
21ab4e
                 /* */
21ab4e
                 break;
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e