7c2869
From 7af9edd57ea7222dad59321d0779df00301d48bb Mon Sep 17 00:00:00 2001
7c2869
From: Atin Mukherjee <amukherj@redhat.com>
7c2869
Date: Tue, 17 Oct 2017 21:32:44 +0530
7c2869
Subject: [PATCH 636/642] glusterd: clean up portmap on brick disconnect
7c2869
7c2869
GlusterD's portmap entry for a brick is cleaned up when a PMAP_SIGNOUT event is
7c2869
initiated by the brick process at the shutdown. But if the brick process crashes
7c2869
or gets killed through SIGKILL then this event is not initiated and glusterd
7c2869
ends up with a stale port. Since GlusterD's portmap traversal happens both ways,
7c2869
forward for allocation and backward for registry search, there is a possibility
7c2869
that glusterd might end up running with a stale port for a brick which
7c2869
eventually will end up with clients to fail to connect to the bricks.
7c2869
7c2869
Solution is to clean up the port entry in case the process is down as
7c2869
part of the brick disconnect event. Although with this the handling
7c2869
PMAP_SIGNOUT event becomes redundant in most of the cases, but this is
7c2869
the safeguard method to avoid glusterd getting into the stale port
7c2869
issues.
7c2869
7c2869
>upstream patch : https://review.gluster.org/#/c/18541
7c2869
7c2869
Change-Id: I04c5be6d11e772ee4de16caf56dbb37d5c944303
7c2869
BUG: 1526371
7c2869
Signed-off-by: Atin Mukherjee <amukherj@redhat.com>
7c2869
Reviewed-on: https://code.engineering.redhat.com/gerrit/125945
7c2869
Tested-by: RHGS Build Bot <nigelb@redhat.com>
7c2869
---
7c2869
 xlators/mgmt/glusterd/src/glusterd-handler.c | 25 +++++++++++++++++++++++++
7c2869
 xlators/mgmt/glusterd/src/glusterd-pmap.c    | 26 +++++++++++++++++---------
7c2869
 xlators/mgmt/glusterd/src/glusterd-pmap.h    |  3 ++-
7c2869
 xlators/mgmt/glusterd/src/glusterd.c         |  3 ++-
7c2869
 4 files changed, 46 insertions(+), 11 deletions(-)
7c2869
7c2869
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
7c2869
index 350ef23..83f0e7d 100644
7c2869
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
7c2869
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
7c2869
@@ -6025,6 +6025,8 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
7c2869
         int                      temp              = 0;
7c2869
         glusterd_brickinfo_t    *brickinfo_tmp     = NULL;
7c2869
         glusterd_brick_proc_t   *brick_proc        = NULL;
7c2869
+        int32_t                  pid               = -1;
7c2869
+        char                     pidfile[PATH_MAX] = {0};
7c2869
 
7c2869
         brickid = mydata;
7c2869
         if (!brickid)
7c2869
@@ -6123,6 +6125,29 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
7c2869
                                   "peer=%s;volume=%s;brick=%s",
7c2869
                                   brickinfo->hostname, volinfo->volname,
7c2869
                                   brickinfo->path);
7c2869
+                        /* In case of an abrupt shutdown of a brick PMAP_SIGNOUT
7c2869
+                         * event is not received by glusterd which can lead to a
7c2869
+                         * stale port entry in glusterd, so forcibly clean up
7c2869
+                         * the same if the process is not running
7c2869
+                         */
7c2869
+                        GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo,
7c2869
+                                                    brickinfo, conf);
7c2869
+                        if (!gf_is_service_running (pidfile, &pid)) {
7c2869
+                                ret = pmap_registry_remove (
7c2869
+                                                      THIS, brickinfo->port,
7c2869
+                                                      brickinfo->path,
7c2869
+                                                      GF_PMAP_PORT_BRICKSERVER,
7c2869
+                                                      NULL, _gf_true);
7c2869
+                                if (ret) {
7c2869
+                                        gf_msg (this->name, GF_LOG_WARNING,
7c2869
+                                                GD_MSG_PMAP_REGISTRY_REMOVE_FAIL,
7c2869
+                                                0, "Failed to remove pmap "
7c2869
+                                                "registry for port %d for "
7c2869
+                                                "brick %s", brickinfo->port,
7c2869
+                                                brickinfo->path);
7c2869
+                                        ret = 0;
7c2869
+                                }
7c2869
+                        }
7c2869
                 }
7c2869
 
7c2869
                 if (is_brick_mx_enabled()) {
7c2869
diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c
7c2869
index 7acee19..1789ef3 100644
7c2869
--- a/xlators/mgmt/glusterd/src/glusterd-pmap.c
7c2869
+++ b/xlators/mgmt/glusterd/src/glusterd-pmap.c
7c2869
@@ -237,7 +237,8 @@ pmap_assign_port (xlator_t *this, int old_port, const char *path)
7c2869
 
7c2869
         if (old_port) {
7c2869
                 ret = pmap_registry_remove (this, 0, path,
7c2869
-                                            GF_PMAP_PORT_BRICKSERVER, NULL);
7c2869
+                                            GF_PMAP_PORT_BRICKSERVER, NULL,
7c2869
+                                            _gf_false);
7c2869
                 if (ret) {
7c2869
                         gf_msg (this->name, GF_LOG_WARNING,
7c2869
                                 GD_MSG_PMAP_REGISTRY_REMOVE_FAIL, 0, "Failed to"
7c2869
@@ -340,7 +341,8 @@ pmap_registry_extend (xlator_t *this, int port, const char *brickname)
7c2869
 
7c2869
 int
7c2869
 pmap_registry_remove (xlator_t *this, int port, const char *brickname,
7c2869
-                      gf_pmap_port_type_t type, void *xprt)
7c2869
+                      gf_pmap_port_type_t type, void *xprt,
7c2869
+                      gf_boolean_t brick_disconnect)
7c2869
 {
7c2869
         struct pmap_registry *pmap = NULL;
7c2869
         int                   p = 0;
7c2869
@@ -387,11 +389,16 @@ remove:
7c2869
          * can delete the entire entry.
7c2869
          */
7c2869
         if (!pmap->ports[p].xprt) {
7c2869
-                brick_str = pmap->ports[p].brickname;
7c2869
-                if (brick_str) {
7c2869
-                        while (*brick_str != '\0') {
7c2869
-                                if (*(brick_str++) != ' ') {
7c2869
-                                        goto out;
7c2869
+                /* If the signout call is being triggered by brick disconnect
7c2869
+                 * then clean up all the bricks (in case of brick mux)
7c2869
+                 */
7c2869
+                if (!brick_disconnect) {
7c2869
+                        brick_str = pmap->ports[p].brickname;
7c2869
+                        if (brick_str) {
7c2869
+                                while (*brick_str != '\0') {
7c2869
+                                        if (*(brick_str++) != ' ') {
7c2869
+                                                goto out;
7c2869
+                                        }
7c2869
                                 }
7c2869
                         }
7c2869
                 }
7c2869
@@ -578,14 +585,15 @@ __gluster_pmap_signout (rpcsvc_request_t *req)
7c2869
                 goto fail;
7c2869
         }
7c2869
         rsp.op_ret = pmap_registry_remove (THIS, args.port, args.brick,
7c2869
-                                           GF_PMAP_PORT_BRICKSERVER, req->trans);
7c2869
+                                           GF_PMAP_PORT_BRICKSERVER, req->trans,
7c2869
+                                           _gf_false);
7c2869
 
7c2869
         ret = glusterd_get_brickinfo (THIS, args.brick, args.port, &brickinfo);
7c2869
         if (args.rdma_port) {
7c2869
                 snprintf(brick_path, PATH_MAX, "%s.rdma", args.brick);
7c2869
                 rsp.op_ret = pmap_registry_remove (THIS, args.rdma_port,
7c2869
                                 brick_path, GF_PMAP_PORT_BRICKSERVER,
7c2869
-                                req->trans);
7c2869
+                                req->trans, _gf_false);
7c2869
         }
7c2869
         /* Update portmap status on brickinfo */
7c2869
         if (brickinfo)
7c2869
diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.h b/xlators/mgmt/glusterd/src/glusterd-pmap.h
7c2869
index 9965a95..253b4cc 100644
7c2869
--- a/xlators/mgmt/glusterd/src/glusterd-pmap.h
7c2869
+++ b/xlators/mgmt/glusterd/src/glusterd-pmap.h
7c2869
@@ -42,7 +42,8 @@ int pmap_registry_bind (xlator_t *this, int port, const char *brickname,
7c2869
                         gf_pmap_port_type_t type, void *xprt);
7c2869
 int pmap_registry_extend (xlator_t *this, int port, const char *brickname);
7c2869
 int pmap_registry_remove (xlator_t *this, int port, const char *brickname,
7c2869
-                          gf_pmap_port_type_t type, void *xprt);
7c2869
+                          gf_pmap_port_type_t type, void *xprt,
7c2869
+                          gf_boolean_t brick_disconnect);
7c2869
 int pmap_registry_search (xlator_t *this, const char *brickname,
7c2869
                           gf_pmap_port_type_t type, gf_boolean_t destroy);
7c2869
 struct pmap_registry *pmap_registry_get (xlator_t *this);
7c2869
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
7c2869
index 34182b0..45587c0 100644
7c2869
--- a/xlators/mgmt/glusterd/src/glusterd.c
7c2869
+++ b/xlators/mgmt/glusterd/src/glusterd.c
7c2869
@@ -423,7 +423,8 @@ glusterd_rpcsvc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
7c2869
                 pthread_mutex_lock (&priv->xprt_lock);
7c2869
                 list_del (&xprt->list);
7c2869
                 pthread_mutex_unlock (&priv->xprt_lock);
7c2869
-                pmap_registry_remove (this, 0, NULL, GF_PMAP_PORT_NONE, xprt);
7c2869
+                pmap_registry_remove (this, 0, NULL, GF_PMAP_PORT_NONE, xprt,
7c2869
+                                      _gf_false);
7c2869
                 break;
7c2869
         }
7c2869
 
7c2869
-- 
7c2869
2.9.3
7c2869