d1681e
From a661f617d22ab7555a039841c1959019af3e80a3 Mon Sep 17 00:00:00 2001
d1681e
From: hari gowtham <hgowtham@redhat.com>
d1681e
Date: Thu, 19 Apr 2018 12:22:07 +0530
d1681e
Subject: [PATCH 230/236] glusterd: volume inode/fd status broken with brick
d1681e
 mux
d1681e
d1681e
        backport of:https://review.gluster.org/#/c/19846/6
d1681e
d1681e
Problem:
d1681e
The values for inode/fd was populated from the ctx received
d1681e
from the server xlator.
d1681e
Without brickmux, every brick from a volume belonged to a
d1681e
single brick from the volume.
d1681e
So searching the server and populating it worked.
d1681e
d1681e
With brickmux, a number of bricks can be confined to a single
d1681e
process. These bricks can be from different volumes too (if
d1681e
we use the max-bricks-per-process option).
d1681e
If they are from different volumes, using the server xlator
d1681e
to populate causes problem.
d1681e
d1681e
Fix:
d1681e
Use the brick to validate and populate the inode/fd status.
d1681e
d1681e
>Signed-off-by: hari gowtham <hgowtham@redhat.com>
d1681e
>Change-Id: I2543fa5397ea095f8338b518460037bba3dfdbfd
d1681e
>fixes: bz#1566067
d1681e
d1681e
Signed-off-by: hari gowtham <hgowtham@redhat.com>
d1681e
Change-Id: I2543fa5397ea095f8338b518460037bba3dfdbfd
d1681e
BUG: 1559452
d1681e
Reviewed-on: https://code.engineering.redhat.com/gerrit/136219
d1681e
Tested-by: RHGS Build Bot <nigelb@redhat.com>
d1681e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
d1681e
---
d1681e
 glusterfsd/src/glusterfsd-mgmt.c             | 34 ++++++------
d1681e
 libglusterfs/src/client_t.c                  | 54 ++++++++++---------
d1681e
 libglusterfs/src/xlator.h                    |  3 +-
d1681e
 tests/basic/volume-status.t                  | 12 +++++
d1681e
 xlators/mgmt/glusterd/src/glusterd-handler.c |  4 ++
d1681e
 xlators/mgmt/glusterd/src/glusterd-op-sm.c   |  3 ++
d1681e
 xlators/nfs/server/src/nfs.c                 |  2 +-
d1681e
 xlators/protocol/server/src/server.c         | 77 ++++++++++++++++------------
d1681e
 8 files changed, 111 insertions(+), 78 deletions(-)
d1681e
d1681e
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
d1681e
index fdf403c..3b9671c 100644
d1681e
--- a/glusterfsd/src/glusterfsd-mgmt.c
d1681e
+++ b/glusterfsd/src/glusterfsd-mgmt.c
d1681e
@@ -1111,14 +1111,14 @@ glusterfs_handle_brick_status (rpcsvc_request_t *req)
d1681e
         glusterfs_ctx_t         *ctx = NULL;
d1681e
         glusterfs_graph_t       *active = NULL;
d1681e
         xlator_t                *this = NULL;
d1681e
-        xlator_t                *any = NULL;
d1681e
-        xlator_t                *xlator = NULL;
d1681e
+        xlator_t                *server_xl = NULL;
d1681e
+        xlator_t                *brick_xl = NULL;
d1681e
         dict_t                  *dict = NULL;
d1681e
         dict_t                  *output = NULL;
d1681e
-        char                    *volname = NULL;
d1681e
         char                    *xname = NULL;
d1681e
         uint32_t                cmd = 0;
d1681e
         char                    *msg = NULL;
d1681e
+        char                    *brickname = NULL;
d1681e
 
d1681e
         GF_ASSERT (req);
d1681e
         this = THIS;
d1681e
@@ -1146,32 +1146,26 @@ glusterfs_handle_brick_status (rpcsvc_request_t *req)
d1681e
                 goto out;
d1681e
         }
d1681e
 
d1681e
-        ret = dict_get_str (dict, "volname", &volname);
d1681e
+        ret = dict_get_str (dict, "brick-name", &brickname);
d1681e
         if (ret) {
d1681e
-                gf_log (this->name, GF_LOG_ERROR, "Couldn't get volname");
d1681e
+                gf_log (this->name, GF_LOG_ERROR, "Couldn't get brickname from"
d1681e
+                        " dict");
d1681e
                 goto out;
d1681e
         }
d1681e
 
d1681e
         ctx = glusterfsd_ctx;
d1681e
         GF_ASSERT (ctx);
d1681e
         active = ctx->active;
d1681e
-        any = active->first;
d1681e
+        server_xl = active->first;
d1681e
 
d1681e
-        ret = gf_asprintf (&xname, "%s-server", volname);
d1681e
-        if (-1 == ret) {
d1681e
-                gf_log (this->name, GF_LOG_ERROR, "Out of memory");
d1681e
-                goto out;
d1681e
-        }
d1681e
-
d1681e
-        xlator = xlator_search_by_name (any, xname);
d1681e
-        if (!xlator) {
d1681e
+        brick_xl = get_xlator_by_name (server_xl, brickname);
d1681e
+        if (!brick_xl) {
d1681e
                 gf_log (this->name, GF_LOG_ERROR, "xlator %s is not loaded",
d1681e
                         xname);
d1681e
                 ret = -1;
d1681e
                 goto out;
d1681e
         }
d1681e
 
d1681e
-
d1681e
         output = dict_new ();
d1681e
         switch (cmd & GF_CLI_STATUS_MASK) {
d1681e
                 case GF_CLI_STATUS_MEM:
d1681e
@@ -1181,15 +1175,17 @@ glusterfs_handle_brick_status (rpcsvc_request_t *req)
d1681e
                         break;
d1681e
 
d1681e
                 case GF_CLI_STATUS_CLIENTS:
d1681e
-                        ret = xlator->dumpops->priv_to_dict (xlator, output);
d1681e
+                        ret = server_xl->dumpops->priv_to_dict (server_xl,
d1681e
+                                        output, brickname);
d1681e
                         break;
d1681e
 
d1681e
                 case GF_CLI_STATUS_INODE:
d1681e
-                        ret = xlator->dumpops->inode_to_dict (xlator, output);
d1681e
+                        ret = server_xl->dumpops->inode_to_dict (brick_xl,
d1681e
+                                                                 output);
d1681e
                         break;
d1681e
 
d1681e
                 case GF_CLI_STATUS_FD:
d1681e
-                        ret = xlator->dumpops->fd_to_dict (xlator, output);
d1681e
+                        ret = server_xl->dumpops->fd_to_dict (brick_xl, output);
d1681e
                         break;
d1681e
 
d1681e
                 case GF_CLI_STATUS_CALLPOOL:
d1681e
@@ -1365,7 +1361,7 @@ glusterfs_handle_node_status (rpcsvc_request_t *req)
d1681e
                                         "Error setting volname to dict");
d1681e
                                 goto out;
d1681e
                         }
d1681e
-                        ret = node->dumpops->priv_to_dict (node, output);
d1681e
+                        ret = node->dumpops->priv_to_dict (node, output, NULL);
d1681e
                         break;
d1681e
 
d1681e
                 case GF_CLI_STATUS_INODE:
d1681e
diff --git a/libglusterfs/src/client_t.c b/libglusterfs/src/client_t.c
d1681e
index 55d891f..dc153cc 100644
d1681e
--- a/libglusterfs/src/client_t.c
d1681e
+++ b/libglusterfs/src/client_t.c
d1681e
@@ -743,10 +743,13 @@ gf_client_dump_fdtables_to_dict (xlator_t *this, dict_t *dict)
d1681e
                             clienttable->cliententries[count].next_free)
d1681e
                                 continue;
d1681e
                         client = clienttable->cliententries[count].client;
d1681e
-                        memset(key, 0, sizeof key);
d1681e
-                        snprintf (key, sizeof key, "conn%d", count++);
d1681e
-                        fdtable_dump_to_dict (client->server_ctx.fdtable,
d1681e
-                                              key, dict);
d1681e
+                        if (!strcmp (client->bound_xl->name, this->name)) {
d1681e
+                                memset(key, 0, sizeof (key));
d1681e
+                                snprintf (key, sizeof (key), "conn%d", count++);
d1681e
+                                fdtable_dump_to_dict (client->server_ctx.
d1681e
+                                                      fdtable,
d1681e
+                                                      key, dict);
d1681e
+                        }
d1681e
                 }
d1681e
         }
d1681e
         UNLOCK(&clienttable->lock);
d1681e
@@ -859,25 +862,30 @@ gf_client_dump_inodes_to_dict (xlator_t *this, dict_t *dict)
d1681e
                             clienttable->cliententries[count].next_free)
d1681e
                                 continue;
d1681e
                         client = clienttable->cliententries[count].client;
d1681e
-                        memset(key, 0, sizeof key);
d1681e
-                        if (client->bound_xl && client->bound_xl->itable) {
d1681e
-                                /* Presently every brick contains only
d1681e
-                                 * one bound_xl for all connections.
d1681e
-                                 * This will lead to duplicating of
d1681e
-                                 *  the inode lists, if listing is
d1681e
-                                 * done for every connection. This
d1681e
-                                 * simple check prevents duplication
d1681e
-                                 * in the present case. If need arises
d1681e
-                                 * the check can be improved.
d1681e
-                                 */
d1681e
-                                if (client->bound_xl == prev_bound_xl)
d1681e
-                                        continue;
d1681e
-                                prev_bound_xl = client->bound_xl;
d1681e
-
d1681e
-                                memset (key, 0, sizeof (key));
d1681e
-                                snprintf (key, sizeof (key), "conn%d", count);
d1681e
-                                inode_table_dump_to_dict (client->bound_xl->itable,
d1681e
-                                                          key, dict);
d1681e
+                        if (!strcmp (client->bound_xl->name, this->name)) {
d1681e
+                                memset(key, 0, sizeof (key));
d1681e
+                                if (client->bound_xl && client->bound_xl->
d1681e
+                                                itable) {
d1681e
+                                        /* Presently every brick contains only
d1681e
+                                         * one bound_xl for all connections.
d1681e
+                                         * This will lead to duplicating of
d1681e
+                                         *  the inode lists, if listing is
d1681e
+                                         * done for every connection. This
d1681e
+                                         * simple check prevents duplication
d1681e
+                                         * in the present case. If need arises
d1681e
+                                         * the check can be improved.
d1681e
+                                         */
d1681e
+                                        if (client->bound_xl == prev_bound_xl)
d1681e
+                                                continue;
d1681e
+                                        prev_bound_xl = client->bound_xl;
d1681e
+
d1681e
+                                        memset (key, 0, sizeof (key));
d1681e
+                                        snprintf (key, sizeof (key), "conn%d",
d1681e
+                                                        count);
d1681e
+                                        inode_table_dump_to_dict (client->
d1681e
+                                                        bound_xl->itable,
d1681e
+                                                        key, dict);
d1681e
+                                }
d1681e
                         }
d1681e
                 }
d1681e
         }
d1681e
diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h
d1681e
index 5ed8646..7434da8 100644
d1681e
--- a/libglusterfs/src/xlator.h
d1681e
+++ b/libglusterfs/src/xlator.h
d1681e
@@ -873,7 +873,8 @@ typedef int32_t (*dumpop_inodectx_t) (xlator_t *this, inode_t *ino);
d1681e
 
d1681e
 typedef int32_t (*dumpop_fdctx_t) (xlator_t *this, fd_t *fd);
d1681e
 
d1681e
-typedef int32_t (*dumpop_priv_to_dict_t) (xlator_t *this, dict_t *dict);
d1681e
+typedef int32_t (*dumpop_priv_to_dict_t) (xlator_t *this, dict_t *dict,
d1681e
+                 char *brickname);
d1681e
 
d1681e
 typedef int32_t (*dumpop_inode_to_dict_t) (xlator_t *this, dict_t *dict);
d1681e
 
d1681e
diff --git a/tests/basic/volume-status.t b/tests/basic/volume-status.t
d1681e
index f87b0a9..d3a79c9 100644
d1681e
--- a/tests/basic/volume-status.t
d1681e
+++ b/tests/basic/volume-status.t
d1681e
@@ -6,6 +6,14 @@
d1681e
 
d1681e
 cleanup;
d1681e
 
d1681e
+function gluster_fd_status () {
d1681e
+        gluster volume status $V0 fd | sed -n '/Brick :/ p' | wc -l
d1681e
+}
d1681e
+
d1681e
+function gluster_inode_status () {
d1681e
+        gluster volume status $V0 inode | sed -n '/Connection / p' | wc -l
d1681e
+}
d1681e
+
d1681e
 TEST glusterd
d1681e
 TEST pidof glusterd
d1681e
 TEST $CLI volume info;
d1681e
@@ -21,6 +29,10 @@ EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" nfs_up_status
d1681e
 ## Mount FUSE
d1681e
 TEST $GFS -s $H0 --volfile-id $V0 $M0;
d1681e
 
d1681e
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "8" gluster_fd_status
d1681e
+
d1681e
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1024" gluster_inode_status
d1681e
+
d1681e
 ##Wait for connection establishment between nfs server and brick process
d1681e
 EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available;
d1681e
 
d1681e
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
d1681e
index cb19321..30adb99 100644
d1681e
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
d1681e
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
d1681e
@@ -5304,6 +5304,10 @@ glusterd_print_client_details (FILE *fp, dict_t *dict,
d1681e
         brick_req->op = GLUSTERD_BRICK_STATUS;
d1681e
         brick_req->name = "";
d1681e
 
d1681e
+        ret = dict_set_str (dict, "brick-name", brickinfo->path);
d1681e
+        if (ret)
d1681e
+                goto out;
d1681e
+
d1681e
         ret = dict_set_int32 (dict, "cmd", GF_CLI_STATUS_CLIENTS);
d1681e
         if (ret)
d1681e
                 goto out;
d1681e
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
d1681e
index d479ed4..7107a46 100644
d1681e
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
d1681e
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
d1681e
@@ -612,6 +612,9 @@ glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickin
d1681e
                         goto out;
d1681e
                 brick_req->op = GLUSTERD_BRICK_STATUS;
d1681e
                 brick_req->name = "";
d1681e
+                ret = dict_set_str (dict, "brick-name", brickinfo->path);
d1681e
+                if (ret)
d1681e
+                        goto out;
d1681e
         }
d1681e
                 break;
d1681e
         case GD_OP_REBALANCE:
d1681e
diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c
d1681e
index c2c3c86..10502c2 100644
d1681e
--- a/xlators/nfs/server/src/nfs.c
d1681e
+++ b/xlators/nfs/server/src/nfs.c
d1681e
@@ -1604,7 +1604,7 @@ _nfs_export_is_for_vol (char *exname, char *volname)
d1681e
 }
d1681e
 
d1681e
 int
d1681e
-nfs_priv_to_dict (xlator_t *this, dict_t *dict)
d1681e
+nfs_priv_to_dict (xlator_t *this, dict_t *dict, char *brickname)
d1681e
 {
d1681e
         int                     ret = -1;
d1681e
         struct nfs_state        *priv = NULL;
d1681e
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
d1681e
index 792dfb3..eed4295 100644
d1681e
--- a/xlators/protocol/server/src/server.c
d1681e
+++ b/xlators/protocol/server/src/server.c
d1681e
@@ -225,7 +225,7 @@ ret:
d1681e
 
d1681e
 
d1681e
 int
d1681e
-server_priv_to_dict (xlator_t *this, dict_t *dict)
d1681e
+server_priv_to_dict (xlator_t *this, dict_t *dict, char *brickname)
d1681e
 {
d1681e
         server_conf_t   *conf = NULL;
d1681e
         rpc_transport_t *xprt = NULL;
d1681e
@@ -245,39 +245,48 @@ server_priv_to_dict (xlator_t *this, dict_t *dict)
d1681e
         pthread_mutex_lock (&conf->mutex);
d1681e
         {
d1681e
                 list_for_each_entry (xprt, &conf->xprt_list, list) {
d1681e
-                        peerinfo = &xprt->peerinfo;
d1681e
-                        memset (key, 0, sizeof (key));
d1681e
-                        snprintf (key, sizeof (key), "client%d.hostname",
d1681e
-                                  count);
d1681e
-                        ret = dict_set_str (dict, key, peerinfo->identifier);
d1681e
-                        if (ret)
d1681e
-                                goto unlock;
d1681e
-
d1681e
-                        memset (key, 0, sizeof (key));
d1681e
-                        snprintf (key, sizeof (key), "client%d.bytesread",
d1681e
-                                  count);
d1681e
-                        ret = dict_set_uint64 (dict, key,
d1681e
-                                               xprt->total_bytes_read);
d1681e
-                        if (ret)
d1681e
-                                goto unlock;
d1681e
-
d1681e
-                        memset (key, 0, sizeof (key));
d1681e
-                        snprintf (key, sizeof (key), "client%d.byteswrite",
d1681e
-                                  count);
d1681e
-                        ret = dict_set_uint64 (dict, key,
d1681e
-                                               xprt->total_bytes_write);
d1681e
-                        if (ret)
d1681e
-                                goto unlock;
d1681e
-
d1681e
-                        memset (key, 0, sizeof (key));
d1681e
-                        snprintf (key, sizeof (key), "client%d.opversion",
d1681e
-                                  count);
d1681e
-                        ret = dict_set_uint32 (dict, key,
d1681e
-                                               peerinfo->max_op_version);
d1681e
-                        if (ret)
d1681e
-                                goto unlock;
d1681e
-
d1681e
-                        count++;
d1681e
+                        if (!strcmp (brickname,
d1681e
+                                     xprt->xl_private->bound_xl->name)) {
d1681e
+                                peerinfo = &xprt->peerinfo;
d1681e
+                                memset (key, 0, sizeof (key));
d1681e
+                                snprintf (key, sizeof (key),
d1681e
+                                          "client%d.hostname",
d1681e
+                                          count);
d1681e
+                                ret = dict_set_str (dict, key,
d1681e
+                                                    peerinfo->identifier);
d1681e
+                                if (ret)
d1681e
+                                        goto unlock;
d1681e
+
d1681e
+                                memset (key, 0, sizeof (key));
d1681e
+                                snprintf (key, sizeof (key),
d1681e
+                                          "client%d.bytesread",
d1681e
+                                          count);
d1681e
+                                ret = dict_set_uint64 (dict, key,
d1681e
+                                                xprt->total_bytes_read);
d1681e
+                                if (ret)
d1681e
+                                        goto unlock;
d1681e
+
d1681e
+                                memset (key, 0, sizeof (key));
d1681e
+                                snprintf (key, sizeof (key),
d1681e
+                                          "client%d.byteswrite",
d1681e
+                                          count);
d1681e
+                                ret = dict_set_uint64 (dict, key,
d1681e
+                                                xprt->total_bytes_write);
d1681e
+                                if (ret)
d1681e
+                                        goto unlock;
d1681e
+
d1681e
+                                memset (key, 0, sizeof (key));
d1681e
+                                snprintf (key, sizeof (key),
d1681e
+                                          "client%d.opversion",
d1681e
+                                          count);
d1681e
+                                ret = dict_set_uint32 (dict, key,
d1681e
+                                                peerinfo->max_op_version);
d1681e
+                                if (ret)
d1681e
+                                        goto unlock;
d1681e
+
d1681e
+
d1681e
+                                count++;
d1681e
+                        }
d1681e
                 }
d1681e
         }
d1681e
 unlock:
d1681e
-- 
d1681e
1.8.3.1
d1681e