From 99ce0d43fffa9b2094edcd4917df2ff9ca7afe5d Mon Sep 17 00:00:00 2001 From: Poornima G Date: Fri, 22 Jan 2016 11:44:21 -0500 Subject: 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 > BUG: 1169302 > Signed-off-by: Poornima G > [ndevos: minor fixes and split patch in smaller pieces] > Reviewed-on-master: https://review.gluster.org/9228 > Reviewed-by: Niels de Vos > Tested-by: Niels de Vos > Reviewed-by: Kaleb KEITHLEY > Reviewed-by: Samikshan Bairagya BUG: 1418981 Change-Id: Icbe4d2f026b32a2c7d5535e1bfb2cdaaff042e91 Signed-off-by: Shyam Reviewed-on: https://review.gluster.org/16601 Smoke: Gluster Build System Reviewed-by: Niels de Vos NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System --- xlators/mgmt/glusterd/src/glusterd-utils.c | 43 ++++++++++++++++ xlators/mgmt/glusterd/src/glusterd-utils.h | 4 ++ xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 7 +++ xlators/mgmt/glusterd/src/glusterd.c | 67 +++++++++++++++++++++++++ xlators/mgmt/glusterd/src/glusterd.h | 4 ++ 5 files changed, 125 insertions(+) (limited to 'xlators') diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 703ca49e326..f64b25cccd1 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -7583,6 +7583,49 @@ out: return ret; } +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) { diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 76c963443df..db13c4c8ad4 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -395,6 +395,10 @@ glusterd_brick_terminate (glusterd_volinfo_t *volinfo, 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); diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index d2f724be7c7..ad5fe909578 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" @@ -232,6 +233,72 @@ out: return 0; } +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) { diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 4f2c8f287df..f3c7e1d6891 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -999,6 +999,10 @@ glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret, int32_t op_errno, char *op_errstr, 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); -- cgit