21ab4e
From 66b1bb65618f8205e8aa7a0229b0f003f82c5c81 Mon Sep 17 00:00:00 2001
21ab4e
From: Poornima G <pgurusid@redhat.com>
21ab4e
Date: Fri, 22 Jan 2016 11:44:21 -0500
21ab4e
Subject: [PATCH 315/361] glusterd: add a cli command to trigger a statedump on
21ab4e
 a client
21ab4e
21ab4e
With this, we will be able to trigger statedumps on remote Gluster
21ab4e
clients, mainly targetted for applications using libgfapi.
21ab4e
21ab4e
Design:
21ab4e
SIGUSR signal is the most comman way of taking a statedump in Gluster.
21ab4e
But it cannot be used for libgfapi based processes, as the process
21ab4e
loading the library might have already consumed SIGUSR signal. Hence
21ab4e
going by the command way.
21ab4e
21ab4e
One has to issue a Gluster command to initiate a statedump on the
21ab4e
libgfapi based client. The command takes hostname and PID as an
21ab4e
argument. All the glusterds in the cluster, check if they are connected
21ab4e
to the specified hostname, and send an RPC request to all the connected
21ab4e
clients from that hostname (via the mgmt connection).
21ab4e
21ab4e
[ndevos: minor fixes and split patch in smaller pieces]
21ab4e
21ab4e
mainline:
21ab4e
> BUG: 1169302
21ab4e
> Reviewed-on: http://review.gluster.org/16357
21ab4e
> Reviewed-on: https://review.gluster.org/9228
21ab4e
> Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
21ab4e
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> Reviewed-by: Niels de Vos <ndevos@redhat.com>
21ab4e
> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
21ab4e
> Reviewed-by: Samikshan Bairagya <samikshan@gmail.com>
21ab4e
> Tested-by: Niels de Vos <ndevos@redhat.com>
21ab4e
(cherry picked from commit 1f1f1eee47c4aad678bd52971b96c1debfce4805)
21ab4e
21ab4e
BUG: 1378085
21ab4e
Change-Id: Icbe4d2f026b32a2c7d5535e1bfb2cdaaff042e91
21ab4e
Signed-off-by: Poornima G <pgurusid@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/101296
21ab4e
Tested-by: Milind Changire <mchangir@redhat.com>
21ab4e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
---
21ab4e
 cli/src/cli-cmd-parser.c                        | 46 +++++++++++++----
21ab4e
 cli/src/cli-cmd-volume.c                        |  4 +-
21ab4e
 doc/debugging/statedump.md                      | 13 +++++
21ab4e
 glusterfsd/src/glusterfsd-mgmt.c                |  1 +
21ab4e
 libglusterfs/src/common-utils.c                 | 21 ++++++++
21ab4e
 libglusterfs/src/common-utils.h                 |  2 +
21ab4e
 rpc/rpc-lib/src/protocol-common.h               |  1 +
21ab4e
 rpc/rpc-lib/src/rpc-transport.h                 |  2 +-
21ab4e
 rpc/xdr/src/rpc-common-xdr.x                    |  3 ++
21ab4e
 tests/bugs/cli/bug-1169302.t                    | 34 +++++++++++++
21ab4e
 xlators/mgmt/glusterd/src/glusterd-utils.c      | 43 ++++++++++++++++
21ab4e
 xlators/mgmt/glusterd/src/glusterd-utils.h      |  4 ++
21ab4e
 xlators/mgmt/glusterd/src/glusterd-volume-ops.c |  7 +++
21ab4e
 xlators/mgmt/glusterd/src/glusterd.c            | 67 +++++++++++++++++++++++++
21ab4e
 xlators/mgmt/glusterd/src/glusterd.h            |  4 ++
21ab4e
 15 files changed, 239 insertions(+), 13 deletions(-)
21ab4e
 create mode 100755 tests/bugs/cli/bug-1169302.t
21ab4e
21ab4e
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
21ab4e
index 2e61c3a..7637944 100644
21ab4e
--- a/cli/src/cli-cmd-parser.c
21ab4e
+++ b/cli/src/cli-cmd-parser.c
21ab4e
@@ -3530,19 +3530,44 @@ cli_cmd_volume_statedump_options_parse (const char **words, int wordcount,
21ab4e
         dict_t  *dict = NULL;
21ab4e
         int     option_cnt = 0;
21ab4e
         char    *option = NULL;
21ab4e
-        char    option_str[100] = {0,};
21ab4e
-
21ab4e
-        for (i = 3; i < wordcount; i++, option_cnt++) {
21ab4e
-                if (!cli_cmd_validate_dumpoption (words[i], &option)) {
21ab4e
+        char    option_str[_POSIX_HOST_NAME_MAX + 100] = {0,};
21ab4e
+        char    *tmp = NULL;
21ab4e
+        char    *ip_addr = NULL;
21ab4e
+        char    *pid = NULL;
21ab4e
+
21ab4e
+        if ((wordcount >= 5) && ((strcmp (words[3], "client")) == 0)) {
21ab4e
+                tmp = gf_strdup(words[4]);
21ab4e
+                if (!tmp) {
21ab4e
+                        ret = -1;
21ab4e
+                        goto out;
21ab4e
+                }
21ab4e
+                ip_addr = strtok(tmp, ":");
21ab4e
+                pid = strtok(NULL, ":");
21ab4e
+                if (valid_internet_address (ip_addr, _gf_true)
21ab4e
+                   && pid && gf_valid_pid (pid, strlen(pid))) {
21ab4e
+                        strncat (option_str, words[3], strlen (words[3]));
21ab4e
+                        strncat (option_str, " ", 1);
21ab4e
+                        strncat (option_str, ip_addr, strlen (ip_addr));
21ab4e
+                        strncat (option_str, " ", 1);
21ab4e
+                        strncat (option_str, pid, strlen (pid));
21ab4e
+                        option_cnt = 3;
21ab4e
+                } else {
21ab4e
+                        ret = -1;
21ab4e
+                        goto out;
21ab4e
+                }
21ab4e
+        } else {
21ab4e
+                for (i = 3; i < wordcount; i++, option_cnt++) {
21ab4e
+                        if (!cli_cmd_validate_dumpoption (words[i], &option)) {
21ab4e
+                                ret = -1;
21ab4e
+                                goto out;
21ab4e
+                        }
21ab4e
+                        strncat (option_str, option, strlen (option));
21ab4e
+                        strncat (option_str, " ", 1);
21ab4e
+                }
21ab4e
+                if ((strstr (option_str, "nfs")) && strstr (option_str, "quotad")) {
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
-                strncat (option_str, option, strlen (option));
21ab4e
-                strncat (option_str, " ", 1);
21ab4e
-        }
21ab4e
-        if((strstr (option_str, "nfs")) && strstr (option_str, "quotad")) {
21ab4e
-                ret = -1;
21ab4e
-                goto out;
21ab4e
         }
21ab4e
 
21ab4e
         dict = dict_new ();
21ab4e
@@ -3559,6 +3584,7 @@ cli_cmd_volume_statedump_options_parse (const char **words, int wordcount,
21ab4e
 
21ab4e
         *options = dict;
21ab4e
 out:
21ab4e
+        GF_FREE (tmp);
21ab4e
         if (ret && dict)
21ab4e
                 dict_destroy (dict);
21ab4e
         if (ret)
21ab4e
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
21ab4e
index 04fe432..6737ffd 100644
21ab4e
--- a/cli/src/cli-cmd-volume.c
21ab4e
+++ b/cli/src/cli-cmd-volume.c
21ab4e
@@ -3295,8 +3295,8 @@ struct cli_cmd volume_cmds[] = {
21ab4e
           cli_cmd_volume_heal_cbk,
21ab4e
           "self-heal commands on volume specified by <VOLNAME>"},
21ab4e
 
21ab4e
-        {"volume statedump <VOLNAME> [nfs|quotad] [all|mem|iobuf|callpool|priv|fd|"
21ab4e
-         "inode|history]...",
21ab4e
+        {"volume statedump <VOLNAME> [[nfs|quotad] [all|mem|iobuf|callpool|"
21ab4e
+         "priv|fd|inode|history]... | [client <hostname:process-id>]]",
21ab4e
          cli_cmd_volume_statedump_cbk,
21ab4e
          "perform statedump on bricks"},
21ab4e
 
21ab4e
diff --git a/doc/debugging/statedump.md b/doc/debugging/statedump.md
21ab4e
index f34a5c3..e4e02a9 100644
21ab4e
--- a/doc/debugging/statedump.md
21ab4e
+++ b/doc/debugging/statedump.md
21ab4e
@@ -19,6 +19,19 @@ For quotad:     `gluster volume statedump <volname> quotad`
21ab4e
 
21ab4e
 For brick-processes files will be created in `statedump-directory` with name of the file as `hyphenated-brick-path.<pid>.dump.timestamp`. For all other processes it will be `glusterdump.<pid>.dump.timestamp`.
21ab4e
 
21ab4e
+For applications using libgfapi, `SIGUSR1` cannot be used, eg: smbd/libvirtd
21ab4e
+processes could have used the `SIGUSR1` signal already for other purposes.
21ab4e
+To generate statedump for the processes, using libgfapi, below command can be
21ab4e
+executed from one of the nodes in the gluster cluster to which the libgfapi
21ab4e
+application is connected to.
21ab4e
+
21ab4e
+    gluster volume statedump <volname> client <hostname>:<process id>
21ab4e
+
21ab4e
+The statedumps can be found in the `statedump-directory`, the name of the
21ab4e
+statedumps being `glusterdump.<pid>.dump.timestamp`. For a process there can be
21ab4e
+multiple such files created depending on the number of times the volume is
21ab4e
+accessed by the process (related to the number of `glfs_init()` calls).
21ab4e
+
21ab4e
 ##How to read statedump
21ab4e
 We shall see snippets of each type of statedump.
21ab4e
 
21ab4e
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
21ab4e
index a12496e..bf7b4fc 100644
21ab4e
--- a/glusterfsd/src/glusterfsd-mgmt.c
21ab4e
+++ b/glusterfsd/src/glusterfsd-mgmt.c
21ab4e
@@ -1450,6 +1450,7 @@ rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = {
21ab4e
         [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, mgmt_cbk_spec },
21ab4e
         [GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_CBK_EVENT_NOTIFY,
21ab4e
                                  mgmt_cbk_event},
21ab4e
+        [GF_CBK_STATEDUMP] = {"STATEDUMP", GF_CBK_STATEDUMP, mgmt_cbk_event},
21ab4e
 };
21ab4e
 
21ab4e
 
21ab4e
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
21ab4e
index d36069f..9d9f1d5 100644
21ab4e
--- a/libglusterfs/src/common-utils.c
21ab4e
+++ b/libglusterfs/src/common-utils.c
21ab4e
@@ -3670,6 +3670,27 @@ out:
21ab4e
         return running;
21ab4e
 }
21ab4e
 
21ab4e
+/* Check if the pid is > 0 */
21ab4e
+gf_boolean_t
21ab4e
+gf_valid_pid (const char *pid, int length)
21ab4e
+{
21ab4e
+        gf_boolean_t    ret = _gf_true;
21ab4e
+        pid_t           value = 0;
21ab4e
+        char           *end_ptr = NULL;
21ab4e
+
21ab4e
+        if (length <= 0) {
21ab4e
+                ret = _gf_false;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        value = strtol (pid, &end_ptr, 10);
21ab4e
+        if (value <= 0) {
21ab4e
+                ret = _gf_false;
21ab4e
+        }
21ab4e
+out:
21ab4e
+        return ret;
21ab4e
+}
21ab4e
+
21ab4e
 static int
21ab4e
 dht_is_linkfile_key (dict_t *this, char *key, data_t *value, void *data)
21ab4e
 {
21ab4e
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
21ab4e
index 2a6d02c..ccda0d9 100644
21ab4e
--- a/libglusterfs/src/common-utils.h
21ab4e
+++ b/libglusterfs/src/common-utils.h
21ab4e
@@ -786,6 +786,8 @@ int gf_thread_create_detached (pthread_t *thread,
21ab4e
 
21ab4e
 gf_boolean_t
21ab4e
 gf_is_service_running (char *pidfile, int *pid);
21ab4e
+gf_boolean_t
21ab4e
+gf_valid_pid (const char *pid, int length);
21ab4e
 int
21ab4e
 gf_skip_header_section (int fd, int header_len);
21ab4e
 
21ab4e
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
21ab4e
index 0fe7d1f..ea680f9 100644
21ab4e
--- a/rpc/rpc-lib/src/protocol-common.h
21ab4e
+++ b/rpc/rpc-lib/src/protocol-common.h
21ab4e
@@ -141,6 +141,7 @@ enum gf_cbk_procnum {
21ab4e
         GF_CBK_CHILD_UP,
21ab4e
         GF_CBK_CHILD_DOWN,
21ab4e
         GF_CBK_RECALL_LEASE,
21ab4e
+        GF_CBK_STATEDUMP,
21ab4e
         GF_CBK_MAXVALUE,
21ab4e
 };
21ab4e
 
21ab4e
diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h
21ab4e
index 630729d..dbfa32a 100644
21ab4e
--- a/rpc/rpc-lib/src/rpc-transport.h
21ab4e
+++ b/rpc/rpc-lib/src/rpc-transport.h
21ab4e
@@ -70,7 +70,7 @@ struct peer_info {
21ab4e
         uint32_t max_op_version;
21ab4e
         uint32_t min_op_version;
21ab4e
         //Volume mounted by client
21ab4e
-        char volname[1024];
21ab4e
+        char volname[NAME_MAX];
21ab4e
 };
21ab4e
 typedef struct peer_info peer_info_t;
21ab4e
 
21ab4e
diff --git a/rpc/xdr/src/rpc-common-xdr.x b/rpc/xdr/src/rpc-common-xdr.x
21ab4e
index c2b2570..169b16d 100644
21ab4e
--- a/rpc/xdr/src/rpc-common-xdr.x
21ab4e
+++ b/rpc/xdr/src/rpc-common-xdr.x
21ab4e
@@ -24,6 +24,9 @@ struct gf_dump_req {
21ab4e
 	u_quad_t gfs_id;
21ab4e
 };
21ab4e
 
21ab4e
+struct gf_statedump {
21ab4e
+	unsigned int pid;
21ab4e
+};
21ab4e
 
21ab4e
 struct gf_prog_detail {
21ab4e
 	string progname<>;
21ab4e
diff --git a/tests/bugs/cli/bug-1169302.t b/tests/bugs/cli/bug-1169302.t
21ab4e
new file mode 100755
21ab4e
index 0000000..92252aa
21ab4e
--- /dev/null
21ab4e
+++ b/tests/bugs/cli/bug-1169302.t
21ab4e
@@ -0,0 +1,34 @@
21ab4e
+#!/bin/bash
21ab4e
+
21ab4e
+. $(dirname $0)/../../include.rc
21ab4e
+. $(dirname $0)/../../volume.rc
21ab4e
+. $(dirname $0)/../../cluster.rc
21ab4e
+
21ab4e
+function check_peers {
21ab4e
+    $CLI_1 peer status | grep 'Peer in Cluster (Connected)' | wc -l
21ab4e
+}
21ab4e
+cleanup;
21ab4e
+
21ab4e
+#setup cluster and test volume
21ab4e
+TEST launch_cluster 3; # start 3-node virtual cluster
21ab4e
+TEST $CLI_1 peer probe $H2; # peer probe server 2 from server 1 cli
21ab4e
+TEST $CLI_1 peer probe $H3; # peer probe server 3 from server 1 cli
21ab4e
+
21ab4e
+EXPECT_WITHIN $PROBE_TIMEOUT 2 check_peers;
21ab4e
+
21ab4e
+TEST $CLI_1 volume create $V0 $H1:$B1/$V0 $H2:$B2/$V0 $H3:$B3/$V0
21ab4e
+TEST $CLI_1 volume start $V0
21ab4e
+
21ab4e
+# there is no gfapi application to take statedumps yet, it will get added in
21ab4e
+# the next patch, this only tests the CLI for correctness
21ab4e
+
21ab4e
+cleanup_statedump
21ab4e
+
21ab4e
+TEST ! $CLI_1 volume statedump $V0 client $H2:0
21ab4e
+TEST ! $CLI_2 volume statedump $V0 client $H2:-1
21ab4e
+TEST $CLI_3 volume statedump $V0 client $H2:765
21ab4e
+TEST ! $CLI_1 volume statedump $V0 client $H2:
21ab4e
+TEST ! $CLI_2 volume statedump $V0 client
21ab4e
+
21ab4e
+cleanup_statedump
21ab4e
+cleanup;
21ab4e
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
21ab4e
index e976ba2..9e9d609 100644
21ab4e
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
21ab4e
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
21ab4e
@@ -7022,6 +7022,49 @@ out:
21ab4e
 }
21ab4e
 
21ab4e
 int
21ab4e
+glusterd_client_statedump (char *volname, char *options, int option_cnt,
21ab4e
+                           char **op_errstr)
21ab4e
+{
21ab4e
+        int                      ret                = 0;
21ab4e
+        char                    *dup_options        = NULL;
21ab4e
+        char                    *option             = NULL;
21ab4e
+        char                    *tmpptr             = NULL;
21ab4e
+        char                     msg[256]           = {0,};
21ab4e
+        char                    *target_ip          = NULL;
21ab4e
+        char                    *pid                = NULL;
21ab4e
+
21ab4e
+        dup_options = gf_strdup (options);
21ab4e
+        option = strtok_r (dup_options, " ", &tmpptr);
21ab4e
+        if (strcmp (option, "client")) {
21ab4e
+                snprintf (msg, sizeof (msg), "for gluster client statedump, options "
21ab4e
+                          "should be after the key 'client'");
21ab4e
+                *op_errstr = gf_strdup (msg);
21ab4e
+                ret = -1;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+        target_ip = strtok_r (NULL, " ", &tmpptr);
21ab4e
+        if (target_ip == NULL) {
21ab4e
+                snprintf (msg, sizeof (msg), "ip address not specified");
21ab4e
+                *op_errstr = gf_strdup (msg);
21ab4e
+                ret = -1;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        pid = strtok_r (NULL, " ", &tmpptr);
21ab4e
+        if (pid == NULL) {
21ab4e
+                snprintf (msg, sizeof (msg), "pid not specified");
21ab4e
+                *op_errstr = gf_strdup (msg);
21ab4e
+                ret = -1;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        ret = glusterd_client_statedump_submit_req (volname, target_ip, pid);
21ab4e
+out:
21ab4e
+        GF_FREE (dup_options);
21ab4e
+        return ret;
21ab4e
+}
21ab4e
+
21ab4e
+int
21ab4e
 glusterd_quotad_statedump (char *options, int option_cnt, char **op_errstr)
21ab4e
 {
21ab4e
         int                     ret = -1;
21ab4e
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
21ab4e
index 160b2ef..b1493df 100644
21ab4e
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
21ab4e
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
21ab4e
@@ -348,6 +348,10 @@ int
21ab4e
 glusterd_nfs_statedump (char *options, int option_cnt, char **op_errstr);
21ab4e
 
21ab4e
 int
21ab4e
+glusterd_client_statedump (char *volname, char *options, int option_cnt,
21ab4e
+                           char **op_errstr);
21ab4e
+
21ab4e
+int
21ab4e
 glusterd_quotad_statedump (char *options, int option_cnt, char **op_errstr);
21ab4e
 
21ab4e
 gf_boolean_t
21ab4e
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
21ab4e
index d157734..2eb7548 100644
21ab4e
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
21ab4e
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
21ab4e
@@ -2860,6 +2860,13 @@ glusterd_op_statedump_volume (dict_t *dict, char **op_errstr)
21ab4e
                                                  op_errstr);
21ab4e
                 if (ret)
21ab4e
                         goto out;
21ab4e
+
21ab4e
+        } else if (strstr (options, "client")) {
21ab4e
+                ret = glusterd_client_statedump (volname, options, option_cnt,
21ab4e
+                                                op_errstr);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+
21ab4e
         } else {
21ab4e
                 cds_list_for_each_entry (brickinfo, &volinfo->bricks,
21ab4e
                                          brick_list) {
21ab4e
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
21ab4e
index 6599c53..ae81de6 100644
21ab4e
--- a/xlators/mgmt/glusterd/src/glusterd.c
21ab4e
+++ b/xlators/mgmt/glusterd/src/glusterd.c
21ab4e
@@ -47,6 +47,7 @@
21ab4e
 #include "glusterd-geo-rep.h"
21ab4e
 #include "run.h"
21ab4e
 #include "rpc-clnt-ping.h"
21ab4e
+#include "rpc-common-xdr.h"
21ab4e
 
21ab4e
 #include "syncop.h"
21ab4e
 
21ab4e
@@ -232,6 +233,72 @@ out:
21ab4e
 }
21ab4e
 
21ab4e
 int
21ab4e
+glusterd_client_statedump_submit_req (char *volname, char *target_ip,
21ab4e
+                                      char *pid)
21ab4e
+{
21ab4e
+        gf_statedump             statedump_req      = {0, };
21ab4e
+        glusterd_conf_t         *conf               = NULL;
21ab4e
+        int                      ret                = 0;
21ab4e
+        char                    *end_ptr            = NULL;
21ab4e
+        rpc_transport_t         *trans              = NULL;
21ab4e
+        char                    *ip_addr            = NULL;
21ab4e
+        xlator_t                *this               = NULL;
21ab4e
+        char                     tmp[UNIX_PATH_MAX] = {0, };
21ab4e
+
21ab4e
+        this = THIS;
21ab4e
+        GF_ASSERT (this);
21ab4e
+        conf = this->private;
21ab4e
+        GF_ASSERT (conf);
21ab4e
+
21ab4e
+        if (target_ip == NULL || pid == NULL) {
21ab4e
+                ret = -1;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        statedump_req.pid = strtol (pid, &end_ptr, 10);
21ab4e
+
21ab4e
+        gf_msg_debug (this->name, 0, "Performing statedump on volume %s "
21ab4e
+                      "client with pid:%d host:%s", volname, statedump_req.pid,
21ab4e
+                      target_ip);
21ab4e
+
21ab4e
+        pthread_mutex_lock (&conf->xprt_lock);
21ab4e
+        {
21ab4e
+                list_for_each_entry (trans, &conf->xprt_list, list) {
21ab4e
+                        /* check if this connection matches "all" or the
21ab4e
+                         * volname */
21ab4e
+                        if (strncmp (volname, "all", NAME_MAX) &&
21ab4e
+                            strncmp (trans->peerinfo.volname, volname,
21ab4e
+                                     NAME_MAX)) {
21ab4e
+                                /* no match, try next trans */
21ab4e
+                                continue;
21ab4e
+                        }
21ab4e
+
21ab4e
+                        strcpy (tmp, trans->peerinfo.identifier);
21ab4e
+                        ip_addr = strtok (tmp, ":");
21ab4e
+                        if (gf_is_same_address (ip_addr, target_ip)) {
21ab4e
+                                /* Every gluster client would have
21ab4e
+                                 * connected to glusterd(volfile server). This
21ab4e
+                                 * connection is used to send the statedump
21ab4e
+                                 * request rpc to the application.
21ab4e
+                                 */
21ab4e
+                                gf_msg_trace (this->name, 0, "Submitting "
21ab4e
+                                        "statedump rpc request for %s",
21ab4e
+                                        trans->peerinfo.identifier);
21ab4e
+                                rpcsvc_request_submit (conf->rpc, trans,
21ab4e
+                                                       &glusterd_cbk_prog,
21ab4e
+                                                       GF_CBK_STATEDUMP,
21ab4e
+                                                       &statedump_req, this->ctx,
21ab4e
+                                                       (xdrproc_t)xdr_gf_statedump);
21ab4e
+                        }
21ab4e
+                }
21ab4e
+        }
21ab4e
+        pthread_mutex_unlock (&conf->xprt_lock);
21ab4e
+out:
21ab4e
+        return ret;
21ab4e
+
21ab4e
+}
21ab4e
+
21ab4e
+int
21ab4e
 glusterd_fetchspec_notify (xlator_t *this)
21ab4e
 {
21ab4e
         int              ret   = -1;
21ab4e
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
21ab4e
index c84f019..ab7c03e 100644
21ab4e
--- a/xlators/mgmt/glusterd/src/glusterd.h
21ab4e
+++ b/xlators/mgmt/glusterd/src/glusterd.h
21ab4e
@@ -963,6 +963,10 @@ glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret,
21ab4e
                                 char *hostname, dict_t *dict);
21ab4e
 
21ab4e
 int
21ab4e
+glusterd_client_statedump_submit_req (char *volname, char *target_ip,
21ab4e
+                                      char *pid);
21ab4e
+
21ab4e
+int
21ab4e
 glusterd_fetchspec_notify (xlator_t *this);
21ab4e
 
21ab4e
 int
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e