diff options
author | Poornima G <pgurusid@redhat.com> | 2016-01-22 11:44:21 -0500 |
---|---|---|
committer | Kaleb KEITHLEY <kkeithle@redhat.com> | 2017-01-23 19:13:15 -0500 |
commit | f2e7b6800b812e8bbc9bdbcea4c400a1784e31dc (patch) | |
tree | 2809f95a28204a4769e4dac07db8fe7b79a980f9 /xlators/mgmt | |
parent | 4008a48080b9910b9948c35892e762e91198d134 (diff) |
glusterd: add a cli command to trigger a statedump on a client
With this, we will be able to trigger statedumps on remote Gluster
clients, mainly targetted for applications using libgfapi.
Design:
SIGUSR signal is the most comman way of taking a statedump in Gluster.
But it cannot be used for libgfapi based processes, as the process
loading the library might have already consumed SIGUSR signal. Hence
going by the command way.
One has to issue a Gluster command to initiate a statedump on the
libgfapi based client. The command takes hostname and PID as an
argument. All the glusterds in the cluster, check if they are connected
to the specified hostname, and send an RPC request to all the connected
clients from that hostname (via the mgmt connection).
URL: http://review.gluster.org/16357
Change-Id: Icbe4d2f026b32a2c7d5535e1bfb2cdaaff042e91
BUG: 1169302
Signed-off-by: Poornima G <pgurusid@redhat.com>
[ndevos: minor fixes and split patch in smaller pieces]
Reviewed-on: https://review.gluster.org/9228
Reviewed-by: Niels de Vos <ndevos@redhat.com>
Tested-by: Niels de Vos <ndevos@redhat.com>
Smoke: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: Samikshan Bairagya <samikshan@gmail.com>
Diffstat (limited to 'xlators/mgmt')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 43 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 4 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 7 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.c | 67 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 4 |
5 files changed, 125 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 21482752c53..a77cc674e63 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -7044,6 +7044,49 @@ out: } int +glusterd_client_statedump (char *volname, char *options, int option_cnt, + char **op_errstr) +{ + int ret = 0; + char *dup_options = NULL; + char *option = NULL; + char *tmpptr = NULL; + char msg[256] = {0,}; + char *target_ip = NULL; + char *pid = NULL; + + dup_options = gf_strdup (options); + option = strtok_r (dup_options, " ", &tmpptr); + if (strcmp (option, "client")) { + snprintf (msg, sizeof (msg), "for gluster client statedump, options " + "should be after the key 'client'"); + *op_errstr = gf_strdup (msg); + ret = -1; + goto out; + } + target_ip = strtok_r (NULL, " ", &tmpptr); + if (target_ip == NULL) { + snprintf (msg, sizeof (msg), "ip address not specified"); + *op_errstr = gf_strdup (msg); + ret = -1; + goto out; + } + + pid = strtok_r (NULL, " ", &tmpptr); + if (pid == NULL) { + snprintf (msg, sizeof (msg), "pid not specified"); + *op_errstr = gf_strdup (msg); + ret = -1; + goto out; + } + + ret = glusterd_client_statedump_submit_req (volname, target_ip, pid); +out: + GF_FREE (dup_options); + return ret; +} + +int glusterd_quotad_statedump (char *options, int option_cnt, char **op_errstr) { int ret = -1; diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 5f490534ef5..e801c1a03a3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -390,6 +390,10 @@ int glusterd_nfs_statedump (char *options, int option_cnt, char **op_errstr); int +glusterd_client_statedump (char *volname, char *options, int option_cnt, + char **op_errstr); + +int glusterd_quotad_statedump (char *options, int option_cnt, char **op_errstr); gf_boolean_t diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 0c3ac5816e7..ecc4f9609c1 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -2867,6 +2867,13 @@ glusterd_op_statedump_volume (dict_t *dict, char **op_errstr) op_errstr); if (ret) goto out; + + } else if (strstr (options, "client")) { + ret = glusterd_client_statedump (volname, options, option_cnt, + op_errstr); + if (ret) + goto out; + } else { cds_list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index 18dcf10f2a3..d6f8baff4f2 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -47,6 +47,7 @@ #include "glusterd-geo-rep.h" #include "run.h" #include "rpc-clnt-ping.h" +#include "rpc-common-xdr.h" #include "syncop.h" @@ -233,6 +234,72 @@ out: } int +glusterd_client_statedump_submit_req (char *volname, char *target_ip, + char *pid) +{ + gf_statedump statedump_req = {0, }; + glusterd_conf_t *conf = NULL; + int ret = 0; + char *end_ptr = NULL; + rpc_transport_t *trans = NULL; + char *ip_addr = NULL; + xlator_t *this = NULL; + char tmp[UNIX_PATH_MAX] = {0, }; + + this = THIS; + GF_ASSERT (this); + conf = this->private; + GF_ASSERT (conf); + + if (target_ip == NULL || pid == NULL) { + ret = -1; + goto out; + } + + statedump_req.pid = strtol (pid, &end_ptr, 10); + + gf_msg_debug (this->name, 0, "Performing statedump on volume %s " + "client with pid:%d host:%s", volname, statedump_req.pid, + target_ip); + + pthread_mutex_lock (&conf->xprt_lock); + { + list_for_each_entry (trans, &conf->xprt_list, list) { + /* check if this connection matches "all" or the + * volname */ + if (strncmp (volname, "all", NAME_MAX) && + strncmp (trans->peerinfo.volname, volname, + NAME_MAX)) { + /* no match, try next trans */ + continue; + } + + strcpy (tmp, trans->peerinfo.identifier); + ip_addr = strtok (tmp, ":"); + if (gf_is_same_address (ip_addr, target_ip)) { + /* Every gluster client would have + * connected to glusterd(volfile server). This + * connection is used to send the statedump + * request rpc to the application. + */ + gf_msg_trace (this->name, 0, "Submitting " + "statedump rpc request for %s", + trans->peerinfo.identifier); + rpcsvc_request_submit (conf->rpc, trans, + &glusterd_cbk_prog, + GF_CBK_STATEDUMP, + &statedump_req, this->ctx, + (xdrproc_t)xdr_gf_statedump); + } + } + } + pthread_mutex_unlock (&conf->xprt_lock); +out: + return ret; + +} + +int glusterd_fetchspec_notify (xlator_t *this) { int ret = -1; diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 32f29526fb4..d00e4e20811 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -1000,6 +1000,10 @@ glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret, char *hostname, dict_t *dict); int +glusterd_client_statedump_submit_req (char *volname, char *target_ip, + char *pid); + +int glusterd_fetchspec_notify (xlator_t *this); int |