e7a346
From afcb244f1264af8b0df42b5c79905fd52f01b924 Mon Sep 17 00:00:00 2001
e7a346
From: Mohammed Rafi KC <rkavunga@redhat.com>
e7a346
Date: Thu, 15 Nov 2018 13:18:36 +0530
e7a346
Subject: [PATCH 449/450] glusterd/mux: Optimize brick disconnect handler code
e7a346
e7a346
Removed unnecessary iteration during brick disconnect
e7a346
handler when multiplex is enabled.
e7a346
e7a346
	>Change-Id: I62dd3337b7e7da085da5d76aaae206e0b0edff9f
e7a346
	>fixes: bz#1650115
e7a346
	>Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
e7a346
upstream patch : https://review.gluster.org/#/c/glusterfs/+/21651/
e7a346
e7a346
Change-Id: I62dd3337b7e7da085da5d76aaae206e0b0edff9f
e7a346
BUG: 1649651
e7a346
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
e7a346
Reviewed-on: https://code.engineering.redhat.com/gerrit/156327
e7a346
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e7a346
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
e7a346
---
e7a346
 xlators/mgmt/glusterd/src/glusterd-handler.c |  74 ++++------------
e7a346
 xlators/mgmt/glusterd/src/glusterd-utils.c   | 122 +++++++++++++--------------
e7a346
 xlators/mgmt/glusterd/src/glusterd-utils.h   |   3 +-
e7a346
 xlators/mgmt/glusterd/src/glusterd.h         |  21 +++--
e7a346
 4 files changed, 87 insertions(+), 133 deletions(-)
e7a346
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
e7a346
index a129afc..cab0dec 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
e7a346
@@ -6046,37 +6046,6 @@ out:
e7a346
 
e7a346
 static int gd_stale_rpc_disconnect_log;
e7a346
 
e7a346
-static int
e7a346
-glusterd_mark_bricks_stopped_by_proc (glusterd_brick_proc_t *brick_proc) {
e7a346
-        glusterd_brickinfo_t     *brickinfo        =  NULL;
e7a346
-        glusterd_brickinfo_t     *brickinfo_tmp    =  NULL;
e7a346
-        glusterd_volinfo_t       *volinfo          =  NULL;
e7a346
-        int                       ret              =  -1;
e7a346
-
e7a346
-        cds_list_for_each_entry (brickinfo, &brick_proc->bricks, brick_list) {
e7a346
-                ret =  glusterd_get_volinfo_from_brick (brickinfo->path,
e7a346
-                                                        &volinfo);
e7a346
-                if (ret) {
e7a346
-                        gf_msg (THIS->name, GF_LOG_ERROR, 0,
e7a346
-                                GD_MSG_VOLINFO_GET_FAIL, "Failed to get volinfo"
e7a346
-                                " from brick(%s)", brickinfo->path);
e7a346
-                        goto out;
e7a346
-                }
e7a346
-                cds_list_for_each_entry (brickinfo_tmp, &volinfo->bricks,
e7a346
-                                         brick_list) {
e7a346
-                        if (strcmp (brickinfo->path,
e7a346
-                                    brickinfo_tmp->path) == 0) {
e7a346
-                                glusterd_set_brick_status (brickinfo_tmp,
e7a346
-                                                           GF_BRICK_STOPPED);
e7a346
-                                brickinfo_tmp->start_triggered = _gf_false;
e7a346
-                        }
e7a346
-                }
e7a346
-        }
e7a346
-        return 0;
e7a346
-out:
e7a346
-        return ret;
e7a346
-}
e7a346
-
e7a346
 int
e7a346
 __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
e7a346
                              rpc_clnt_event_t event, void *data)
e7a346
@@ -6087,7 +6056,6 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
e7a346
         glusterd_brickinfo_t    *brickinfo         = NULL;
e7a346
         glusterd_volinfo_t      *volinfo           = NULL;
e7a346
         xlator_t                *this              = NULL;
e7a346
-        int                      temp              = 0;
e7a346
         int32_t                  pid               = -1;
e7a346
         glusterd_brickinfo_t    *brickinfo_tmp     = NULL;
e7a346
         glusterd_brick_proc_t   *brick_proc        = NULL;
e7a346
@@ -6218,33 +6186,21 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
e7a346
                         }
e7a346
                 }
e7a346
 
e7a346
-                if (is_brick_mx_enabled()) {
e7a346
-                        cds_list_for_each_entry (brick_proc, &conf->brick_procs,
e7a346
-                                                 brick_proc_list) {
e7a346
-                                cds_list_for_each_entry (brickinfo_tmp,
e7a346
-                                                         &brick_proc->bricks,
e7a346
-                                                         brick_list) {
e7a346
-                                        if (strcmp (brickinfo_tmp->path,
e7a346
-                                                    brickinfo->path) == 0) {
e7a346
-                                                ret  = glusterd_mark_bricks_stopped_by_proc
e7a346
-                                                       (brick_proc);
e7a346
-                                                if (ret) {
e7a346
-                                                        gf_msg(THIS->name,
e7a346
-                                                               GF_LOG_ERROR, 0,
e7a346
-                                                               GD_MSG_BRICK_STOP_FAIL,
e7a346
-                                                               "Unable to stop "
e7a346
-                                                               "bricks of process"
e7a346
-                                                               " to which brick(%s)"
e7a346
-                                                               " belongs",
e7a346
-                                                               brickinfo->path);
e7a346
-                                                        goto out;
e7a346
-                                                }
e7a346
-                                                temp = 1;
e7a346
-                                                break;
e7a346
-                                        }
e7a346
-                                }
e7a346
-                                if (temp == 1)
e7a346
-                                        break;
e7a346
+                if (is_brick_mx_enabled() && glusterd_is_brick_started(brickinfo)) {
e7a346
+                        brick_proc = brickinfo->brick_proc;
e7a346
+                        if (!brick_proc)
e7a346
+                            break;
e7a346
+                        cds_list_for_each_entry(brickinfo_tmp, &brick_proc->bricks,
e7a346
+                                                mux_bricks)
e7a346
+                        {
e7a346
+                            glusterd_set_brick_status(brickinfo_tmp, GF_BRICK_STOPPED);
e7a346
+                            brickinfo_tmp->start_triggered = _gf_false;
e7a346
+                            /* When bricks are stopped, ports also need to
e7a346
+                             * be cleaned up
e7a346
+                             */
e7a346
+                            pmap_registry_remove(
e7a346
+                                THIS, brickinfo_tmp->port, brickinfo_tmp->path,
e7a346
+                                GF_PMAP_PORT_BRICKSERVER, NULL, _gf_true);
e7a346
                         }
e7a346
                 } else {
e7a346
                         glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED);
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
e7a346
index 7179a68..ec7e27a 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
e7a346
@@ -1088,6 +1088,7 @@ glusterd_brickinfo_new (glusterd_brickinfo_t **brickinfo)
e7a346
                 goto out;
e7a346
 
e7a346
         CDS_INIT_LIST_HEAD (&new_brickinfo->brick_list);
e7a346
+        CDS_INIT_LIST_HEAD (&new_brickinfo->mux_bricks);
e7a346
         pthread_mutex_init (&new_brickinfo->restart_mutex, NULL);
e7a346
         *brickinfo = new_brickinfo;
e7a346
 
e7a346
@@ -1978,6 +1979,7 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t  *volinfo,
e7a346
         struct rpc_clnt         *rpc = NULL;
e7a346
         rpc_clnt_connection_t   *conn  = NULL;
e7a346
         int                     pid    = -1;
e7a346
+        glusterd_brick_proc_t   *brick_proc = NULL;
e7a346
 
e7a346
         GF_ASSERT (volinfo);
e7a346
         GF_ASSERT (brickinfo);
e7a346
@@ -2188,15 +2190,20 @@ retry:
e7a346
                 goto out;
e7a346
         }
e7a346
 
e7a346
-        ret = glusterd_brick_process_add_brick (brickinfo);
e7a346
+        ret = glusterd_brickprocess_new(&brick_proc);
e7a346
         if (ret) {
e7a346
-                gf_msg (this->name, GF_LOG_ERROR, 0,
e7a346
-                        GD_MSG_BRICKPROC_ADD_BRICK_FAILED, "Adding brick %s:%s "
e7a346
-                        "to brick process failed.", brickinfo->hostname,
e7a346
-                        brickinfo->path);
e7a346
+                gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICKPROC_NEW_FAILED,
e7a346
+                       "Failed to create new brick process instance");
e7a346
                 goto out;
e7a346
         }
e7a346
 
e7a346
+        brick_proc->port = brickinfo->port;
e7a346
+        cds_list_add_tail(&brick_proc->brick_proc_list, &priv->brick_procs);
e7a346
+        brickinfo->brick_proc = brick_proc;
e7a346
+        cds_list_add_tail(&brickinfo->mux_bricks, &brick_proc->bricks);
e7a346
+        brickinfo->brick_proc = brick_proc;
e7a346
+        brick_proc->brick_count++;
e7a346
+
e7a346
 connect:
e7a346
         ret = glusterd_brick_connect (volinfo, brickinfo, socketpath);
e7a346
         if (ret) {
e7a346
@@ -2328,9 +2335,6 @@ glusterd_brick_process_remove_brick (glusterd_brickinfo_t *brickinfo)
e7a346
         xlator_t                *this = NULL;
e7a346
         glusterd_conf_t         *priv = NULL;
e7a346
         glusterd_brick_proc_t   *brick_proc = NULL;
e7a346
-        glusterd_brickinfo_t    *brickinfoiter = NULL;
e7a346
-        glusterd_brick_proc_t   *brick_proc_tmp = NULL;
e7a346
-        glusterd_brickinfo_t    *tmp = NULL;
e7a346
 
e7a346
         this = THIS;
e7a346
         GF_VALIDATE_OR_GOTO ("glusterd", this, out);
e7a346
@@ -2339,48 +2343,44 @@ glusterd_brick_process_remove_brick (glusterd_brickinfo_t *brickinfo)
e7a346
         GF_VALIDATE_OR_GOTO (this->name, priv, out);
e7a346
         GF_VALIDATE_OR_GOTO (this->name, brickinfo, out);
e7a346
 
e7a346
-        cds_list_for_each_entry_safe (brick_proc, brick_proc_tmp,
e7a346
-                                      &priv->brick_procs, brick_proc_list) {
e7a346
-                if (brickinfo->port != brick_proc->port) {
e7a346
-                        continue;
e7a346
-                }
e7a346
-
e7a346
-                GF_VALIDATE_OR_GOTO (this->name, (brick_proc->brick_count > 0), out);
e7a346
+        brick_proc = brickinfo->brick_proc;
e7a346
+        if (!brick_proc) {
e7a346
+            if (brickinfo->status != GF_BRICK_STARTED) {
e7a346
+                /* this function will be called from gluster_pmap_signout and
e7a346
+                 * glusterd_volume_stop_glusterfs. So it is possible to have
e7a346
+                 * brick_proc set as null.
e7a346
+                 */
e7a346
+                ret = 0;
e7a346
+            }
e7a346
+            goto out;
e7a346
+        }
e7a346
 
e7a346
-                cds_list_for_each_entry_safe (brickinfoiter, tmp,
e7a346
-                                              &brick_proc->bricks, brick_list) {
e7a346
-                        if (strcmp (brickinfoiter->path, brickinfo->path) == 0) {
e7a346
-                                cds_list_del_init (&brickinfoiter->brick_list);
e7a346
+        GF_VALIDATE_OR_GOTO(this->name, (brick_proc->brick_count > 0), out);
e7a346
 
e7a346
-                                GF_FREE (brickinfoiter->logfile);
e7a346
-                                GF_FREE (brickinfoiter);
e7a346
-                                brick_proc->brick_count--;
e7a346
-                                break;
e7a346
-                        }
e7a346
-                }
e7a346
+        cds_list_del_init(&brickinfo->mux_bricks);
e7a346
+        brick_proc->brick_count--;
e7a346
 
e7a346
-                /* If all bricks have been removed, delete the brick process */
e7a346
-                if (brick_proc->brick_count == 0) {
e7a346
-                        ret = glusterd_brickprocess_delete (brick_proc);
e7a346
-                        if (ret)
e7a346
-                                goto out;
e7a346
-                }
e7a346
-                break;
e7a346
+        /* If all bricks have been removed, delete the brick process */
e7a346
+        if (brick_proc->brick_count == 0) {
e7a346
+            ret = glusterd_brickprocess_delete(brick_proc);
e7a346
+            if (ret)
e7a346
+                goto out;
e7a346
         }
e7a346
 
e7a346
+        brickinfo->brick_proc = NULL;
e7a346
         ret = 0;
e7a346
 out:
e7a346
         return ret;
e7a346
 }
e7a346
 
e7a346
 int
e7a346
-glusterd_brick_process_add_brick (glusterd_brickinfo_t *brickinfo)
e7a346
+glusterd_brick_process_add_brick (glusterd_brickinfo_t *brickinfo,
e7a346
+                                  glusterd_brickinfo_t *parent_brickinfo)
e7a346
 {
e7a346
         int                      ret = -1;
e7a346
         xlator_t                *this = NULL;
e7a346
         glusterd_conf_t         *priv = NULL;
e7a346
         glusterd_brick_proc_t   *brick_proc = NULL;
e7a346
-        glusterd_brickinfo_t    *brickinfo_dup = NULL;
e7a346
 
e7a346
         this = THIS;
e7a346
         GF_VALIDATE_OR_GOTO ("glusterd", this, out);
e7a346
@@ -2389,37 +2389,28 @@ glusterd_brick_process_add_brick (glusterd_brickinfo_t *brickinfo)
e7a346
         GF_VALIDATE_OR_GOTO (this->name, priv, out);
e7a346
         GF_VALIDATE_OR_GOTO (this->name, brickinfo, out);
e7a346
 
e7a346
-        ret = glusterd_brickinfo_new (&brickinfo_dup);
e7a346
-        if (ret) {
e7a346
-                gf_msg ("glusterd", GF_LOG_ERROR, 0,
e7a346
-                        GD_MSG_BRICK_NEW_INFO_FAIL,
e7a346
-                        "Failed to create new brickinfo");
e7a346
-                goto out;
e7a346
-        }
e7a346
-
e7a346
-        ret = glusterd_brickinfo_dup (brickinfo, brickinfo_dup);
e7a346
-        if (ret) {
e7a346
-                gf_msg (this->name, GF_LOG_ERROR, 0,
e7a346
-                        GD_MSG_BRICK_SET_INFO_FAIL, "Failed to dup brickinfo");
e7a346
-                goto out;
e7a346
-        }
e7a346
-
e7a346
-        ret = glusterd_brick_proc_for_port (brickinfo->port, &brick_proc);
e7a346
-        if (ret) {
e7a346
-                ret = glusterd_brickprocess_new (&brick_proc);
e7a346
+        if (!parent_brickinfo) {
e7a346
+                ret = glusterd_brick_proc_for_port(brickinfo->port,
e7a346
+                                                   &brick_proc);
e7a346
                 if (ret) {
e7a346
-                        gf_msg (this->name, GF_LOG_ERROR, 0,
e7a346
-                                GD_MSG_BRICKPROC_NEW_FAILED, "Failed to create "
e7a346
-                                "new brick process instance");
e7a346
-                        goto out;
e7a346
+                        ret = glusterd_brickprocess_new (&brick_proc);
e7a346
+                        if (ret) {
e7a346
+                                gf_msg(this->name, GF_LOG_ERROR, 0,
e7a346
+                                       GD_MSG_BRICKPROC_NEW_FAILED,
e7a346
+                                       "Failed to create "
e7a346
+                                        "new brick process instance");
e7a346
+                                goto out;
e7a346
+                        }
e7a346
+                        brick_proc->port = brickinfo->port;
e7a346
+                        cds_list_add_tail(&brick_proc->brick_proc_list,
e7a346
+                                          &priv->brick_procs);
e7a346
                 }
e7a346
-
e7a346
-                brick_proc->port = brickinfo->port;
e7a346
-
e7a346
-                cds_list_add_tail (&brick_proc->brick_proc_list, &priv->brick_procs);
e7a346
+        } else {
e7a346
+                ret = 0;
e7a346
+                brick_proc = parent_brickinfo->brick_proc;
e7a346
         }
e7a346
-
e7a346
-        cds_list_add_tail (&brickinfo_dup->brick_list, &brick_proc->bricks);
e7a346
+        cds_list_add_tail(&brickinfo->mux_bricks, &brick_proc->bricks);
e7a346
+        brickinfo->brick_proc = brick_proc;
e7a346
         brick_proc->brick_count++;
e7a346
 out:
e7a346
         return ret;
e7a346
@@ -2538,6 +2529,7 @@ glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo,
e7a346
 
e7a346
         brickinfo->status = GF_BRICK_STOPPED;
e7a346
         brickinfo->start_triggered = _gf_false;
e7a346
+        brickinfo->brick_proc = NULL;
e7a346
         if (del_brick)
e7a346
                 glusterd_delete_brick (volinfo, brickinfo);
e7a346
 out:
e7a346
@@ -5704,7 +5696,8 @@ attach_brick (xlator_t *this,
e7a346
                                         goto out;
e7a346
                                 }
e7a346
                                 brickinfo->port = other_brick->port;
e7a346
-                                ret = glusterd_brick_process_add_brick (brickinfo);
e7a346
+                                ret = glusterd_brick_process_add_brick(brickinfo
e7a346
+                                                                 , other_brick);
e7a346
                                 if (ret) {
e7a346
                                         gf_msg (this->name, GF_LOG_ERROR, 0,
e7a346
                                                 GD_MSG_BRICKPROC_ADD_BRICK_FAILED,
e7a346
@@ -6259,7 +6252,8 @@ glusterd_brick_start (glusterd_volinfo_t *volinfo,
e7a346
                         (void) glusterd_brick_connect (volinfo, brickinfo,
e7a346
                                         socketpath);
e7a346
 
e7a346
-                        ret = glusterd_brick_process_add_brick (brickinfo);
e7a346
+                        ret = glusterd_brick_process_add_brick (brickinfo,
e7a346
+                                                                NULL);
e7a346
                         if (ret) {
e7a346
                                 gf_msg (this->name, GF_LOG_ERROR, 0,
e7a346
                                         GD_MSG_BRICKPROC_ADD_BRICK_FAILED,
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
e7a346
index 8e5320d..69bb8c8 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
e7a346
@@ -179,7 +179,8 @@ int32_t
e7a346
 glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo);
e7a346
 
e7a346
 int
e7a346
-glusterd_brick_process_add_brick (glusterd_brickinfo_t *brickinfo);
e7a346
+glusterd_brick_process_add_brick (glusterd_brickinfo_t *brickinfo,
e7a346
+                                  glusterd_brickinfo_t *parent_brickinfo);
e7a346
 
e7a346
 int
e7a346
 glusterd_brick_process_remove_brick (glusterd_brickinfo_t *brickinfo);
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
e7a346
index edd41aa..3dfbf9c 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd.h
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd.h
e7a346
@@ -211,6 +211,15 @@ typedef enum gf_brick_status {
e7a346
         GF_BRICK_STARTING
e7a346
 } gf_brick_status_t;
e7a346
 
e7a346
+struct glusterd_brick_proc {
e7a346
+        int                     port;
e7a346
+        uint32_t                brick_count;
e7a346
+        struct cds_list_head    brick_proc_list;
e7a346
+        struct cds_list_head    bricks;
e7a346
+};
e7a346
+
e7a346
+typedef struct glusterd_brick_proc glusterd_brick_proc_t;
e7a346
+
e7a346
 struct glusterd_brickinfo {
e7a346
         char               hostname[1024];
e7a346
         char               path[PATH_MAX];
e7a346
@@ -249,19 +258,13 @@ struct glusterd_brickinfo {
e7a346
         gf_boolean_t       port_registered;
e7a346
         gf_boolean_t       start_triggered;
e7a346
         pthread_mutex_t    restart_mutex;
e7a346
+        glusterd_brick_proc_t *brick_proc; /* Information regarding mux bricks */
e7a346
+        struct cds_list_head mux_bricks;
e7a346
+        /* List to store the bricks in brick_proc*/
e7a346
 };
e7a346
 
e7a346
 typedef struct glusterd_brickinfo glusterd_brickinfo_t;
e7a346
 
e7a346
-struct glusterd_brick_proc {
e7a346
-        int                     port;
e7a346
-        uint32_t                brick_count;
e7a346
-        struct cds_list_head    brick_proc_list;
e7a346
-        struct cds_list_head    bricks;
e7a346
-};
e7a346
-
e7a346
-typedef struct glusterd_brick_proc glusterd_brick_proc_t;
e7a346
-
e7a346
 struct gf_defrag_brickinfo_ {
e7a346
         char *name;
e7a346
         int   files;
e7a346
-- 
e7a346
1.8.3.1
e7a346