summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/dict.c77
-rw-r--r--libglusterfs/src/dict.h8
-rw-r--r--libglusterfs/src/mem-pool.c4
-rwxr-xr-xtests/bugs/bug-834465.t6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-locks.c12
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c223
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h30
-rw-r--r--xlators/protocol/client/src/client-rpc-fops.c2
-rw-r--r--xlators/protocol/server/src/server-rpc-fops.c2
9 files changed, 332 insertions, 32 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index 5062f509940..d55495c1ad2 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -29,6 +29,7 @@
#include "compat.h"
#include "byte-order.h"
#include "globals.h"
+#include "statedump.h"
data_t *
get_new_data ()
@@ -2807,39 +2808,67 @@ out:
return ret;
}
+int
+dict_dump_to_str (dict_t *dict, char *dump, int dumpsize, char *format)
+{
+ int ret = 0;
+ int dumplen = 0;
+ data_pair_t *trav = NULL;
+
+ for (trav = dict->members_list; trav; trav = trav->next) {
+ ret = snprintf (&dump[dumplen], dumpsize - dumplen,
+ format, trav->key, trav->value->data);
+ if ((ret == -1) || !ret)
+ return ret;
+
+ dumplen += ret;
+ }
+ return 0;
+}
+
void
-dict_dump (dict_t *this)
+dict_dump_to_log (dict_t *dict)
{
- int ret = 0;
- int dumplen = 0;
- data_pair_t *trav = NULL;
- char dump[64*1024]; /* This is debug only, hence
- performance should not matter */
+ int ret = -1;
+ char dump[64*1024] = {0,};
+ char *format = "(%s:%s)";
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict NULL");
- goto out;
+ if (!dict) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
+ return;
}
- dump[0] = '\0'; /* the array is not initialized to '\0' */
+ ret = dict_dump_to_str (dict, dump, sizeof(dump), format);
+ if (ret) {
+ gf_log ("dict", GF_LOG_WARNING, "Failed to log dictionary");
+ return;
+ }
+ gf_log_callingfn ("dict", GF_LOG_INFO, "dict=%p (%s)", dict, dump);
- /* There is a possibility of issues if data is binary, ignore it
- for now as debugging is more important */
- for (trav = this->members_list; trav; trav = trav->next) {
- ret = snprintf (&dump[dumplen], ((64*1024) - dumplen - 1),
- "(%s:%s)", trav->key, trav->value->data);
- if ((ret == -1) || !ret)
- break;
+ return;
+}
- dumplen += ret;
- /* snprintf doesn't append a trailing '\0', add it here */
- dump[dumplen] = '\0';
+void
+dict_dump_to_statedump (dict_t *dict, char *dict_name, char *domain)
+{
+ int ret = -1;
+ char dump[64*1024] = {0,};
+ char key[4096] = {0,};
+ char *format = "\n\t%s:%s";
+
+ if (!dict) {
+ gf_log_callingfn (domain, GF_LOG_WARNING, "dict is NULL");
+ return;
}
- if (dumplen)
- gf_log_callingfn ("dict", GF_LOG_INFO,
- "dict=%p (%s)", this, dump);
+ ret = dict_dump_to_str (dict, dump, sizeof(dump), format);
+ if (ret) {
+ gf_log (domain, GF_LOG_WARNING, "Failed to log dictionary %s",
+ dict_name);
+ return;
+ }
+ gf_proc_dump_build_key (key, domain, dict_name);
+ gf_proc_dump_write (key, "%s", dump);
-out:
return;
}
diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h
index 7fd45e1cf34..148eb0ef7ea 100644
--- a/libglusterfs/src/dict.h
+++ b/libglusterfs/src/dict.h
@@ -234,6 +234,12 @@ GF_MUST_CHECK int dict_get_str (dict_t *this, char *key, char **str);
GF_MUST_CHECK int dict_get_str_boolean (dict_t *this, char *key, int default_val);
GF_MUST_CHECK int dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len,
char delimiter);
+void
+dict_dump_to_statedump (dict_t *dict, char *dict_name, char *domain);
-void dict_dump (dict_t *dict);
+void
+dict_dump_to_log (dict_t *dict);
+
+int
+dict_dump_to_str (dict_t *dict, char *dump, int dumpsize, char *format);
#endif
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index 093592ec056..019be95e37e 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -279,6 +279,10 @@ __gf_free (void *free_ptr)
{
xl->mem_acct.rec[type].size -= req_size;
xl->mem_acct.rec[type].num_allocs--;
+ /* If all the instaces are freed up then ensure typestr is
+ * set to NULL */
+ if (!xl->mem_acct.rec[type].num_allocs)
+ xl->mem_acct.rec[type].typestr = NULL;
}
UNLOCK (&xl->mem_acct.rec[type].lock);
free:
diff --git a/tests/bugs/bug-834465.t b/tests/bugs/bug-834465.t
index 7bbf1a32aa2..70027911498 100755
--- a/tests/bugs/bug-834465.t
+++ b/tests/bugs/bug-834465.t
@@ -31,8 +31,12 @@ build_tester $(dirname $0)/bug-834465.c
TEST $(dirname $0)/bug-834465 $M0/testfile
sdump2=$(generate_mount_statedump $V0);
-nalloc2=`grep -A3 "fuse - usage-type gf_common_mt_fd_lk_ctx_node_t" $sdump2 | grep num_allocs | cut -d '=' -f2`
+# With _gf_free now setting typestr to NULL when num_allocs become 0, it is
+# expected that there wouldn't be any entry for gf_common_mt_fd_lk_ctx_node_t
+# in the statedump file now
+
+nalloc2=`grep -A3 "fuse - usage-type gf_common_mt_fd_lk_ctx_node_t" $sdump2 | wc -l`
TEST [ $nalloc1 -eq $nalloc2 ];
TEST rm -rf $MOUNTDIR/*
diff --git a/xlators/mgmt/glusterd/src/glusterd-locks.c b/xlators/mgmt/glusterd/src/glusterd-locks.c
index b2629fd87b8..1f1de2ae4f0 100644
--- a/xlators/mgmt/glusterd/src/glusterd-locks.c
+++ b/xlators/mgmt/glusterd/src/glusterd-locks.c
@@ -661,6 +661,18 @@ glusterd_mgmt_v3_unlock (const char *name, uuid_t uuid, char *type)
/* Removing the mgmt_v3 lock from the global list */
dict_del (priv->mgmt_v3_lock, key);
+ /* Remove the backtrace key as well */
+ ret = snprintf (key, sizeof(key), "debug.last-success-bt-%s-%s", name,
+ type);
+ if (ret != strlen ("debug.last-success-bt-") + strlen (name) +
+ strlen (type) + 1) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to create backtrace "
+ "key");
+ ret = -1;
+ goto out;
+ }
+ dict_del (priv->mgmt_v3_lock, key);
+
gf_log (this->name, GF_LOG_DEBUG,
"Lock for %s %s successfully released",
type, name);
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index b9a43cd32ce..df1ff41f4ef 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -277,13 +277,227 @@ glusterd_fetchsnap_notify (xlator_t *this)
return ret;
}
-int
-glusterd_priv (xlator_t *this)
+void
+glusterd_dump_peer (glusterd_peerinfo_t *peerinfo, char *input_key, int index,
+ gf_boolean_t xpeers)
{
- return 0;
+ char subkey[50] = {0,};
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+
+ strcpy (key, input_key);
+
+ snprintf (subkey, sizeof (subkey), "%s%d", key, index);
+
+ gf_proc_dump_build_key (key, subkey, "uuid");
+ gf_proc_dump_write (key, "%s",
+ uuid_utoa (peerinfo->uuid));
+
+ gf_proc_dump_build_key (key, subkey, "hostname");
+ gf_proc_dump_write (key, "%d", peerinfo->hostname);
+
+ gf_proc_dump_build_key (key, subkey, "port");
+ gf_proc_dump_write (key, "%d", peerinfo->port);
+
+ gf_proc_dump_build_key (key, subkey, "state");
+ gf_proc_dump_write (key, "%d", peerinfo->state.state);
+
+ gf_proc_dump_build_key (key, subkey, "quorum-action");
+ gf_proc_dump_write (key, "%d", peerinfo->quorum_action);
+
+ gf_proc_dump_build_key (key, subkey, "quorum-contrib");
+ gf_proc_dump_write (key, "%d",
+ peerinfo->quorum_contrib);
+
+ gf_proc_dump_build_key (key, subkey, "detaching");
+ gf_proc_dump_write (key, "%d", peerinfo->detaching);
+
+ gf_proc_dump_build_key (key, subkey, "locked");
+ gf_proc_dump_write (key, "%d", peerinfo->locked);
+
+}
+
+void
+glusterd_dump_peer_rpcstat (glusterd_peerinfo_t *peerinfo, char *input_key,
+ int index)
+{
+ rpc_clnt_connection_t *conn = NULL;
+ int ret = -1;
+ rpc_clnt_t *rpc = NULL;
+ char rpcsvc_peername[RPCSVC_PEER_STRLEN] = {0,};
+ char subkey[50] = {0,};
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+
+ strcpy (key, input_key);
+
+ /* Dump the rpc connection statistics */
+ rpc = peerinfo->rpc;
+ if (rpc) {
+ conn = &rpc->conn;
+ snprintf (subkey, sizeof (subkey), "%s%d", key, index);
+ ret = rpcsvc_transport_peername (conn->trans,
+ (char *)&rpcsvc_peername,
+ sizeof (rpcsvc_peername));
+ if (!ret) {
+ gf_proc_dump_build_key (key, subkey, "rpc.peername");
+ gf_proc_dump_write (key, "%s", rpcsvc_peername);
+ }
+ gf_proc_dump_build_key (key, subkey, "rpc.connected");
+ gf_proc_dump_write (key, "%d", conn->connected);
+
+ gf_proc_dump_build_key (key, subkey, "rpc.total-bytes-read");
+ gf_proc_dump_write (key, "%"PRIu64,
+ conn->trans->total_bytes_read);
+
+ gf_proc_dump_build_key (key, subkey, "rpc.total-bytes-written");
+ gf_proc_dump_write (key, "%"PRIu64,
+ conn->trans->total_bytes_write);
+
+ gf_proc_dump_build_key (key, subkey, "rpc.ping_msgs_sent");
+ gf_proc_dump_write (key, "%"PRIu64, conn->pingcnt);
+
+ gf_proc_dump_build_key (key, subkey, "rpc.msgs_sent");
+ gf_proc_dump_write (key, "%"PRIu64, conn->msgcnt);
+ }
+
+}
+
+static void
+glusterd_dump_client_details (glusterd_conf_t *conf)
+{
+ rpc_transport_t *xprt = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ char subkey[50] = {0,};
+ int index = 1;
+
+ pthread_mutex_lock (&conf->xprt_lock);
+ {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ snprintf (subkey, sizeof (subkey), "glusterd.client%d",
+ index);
+
+ gf_proc_dump_build_key (key, subkey, "identifier");
+ gf_proc_dump_write (key, "%s",
+ xprt->peerinfo.identifier);
+
+ gf_proc_dump_build_key (key, subkey, "volname");
+ gf_proc_dump_write (key, "%s",
+ xprt->peerinfo.volname);
+
+ gf_proc_dump_build_key (key, subkey, "max-op-version");
+ gf_proc_dump_write (key, "%u",
+ xprt->peerinfo.max_op_version);
+
+ gf_proc_dump_build_key (key, subkey, "min-op-version");
+ gf_proc_dump_write (key, "%u",
+ xprt->peerinfo.min_op_version);
+ index++;
+ }
+ }
+ pthread_mutex_unlock (&conf->xprt_lock);
}
+/* The following function is just for dumping mgmt_v3_lock dictionary, any other
+ * dict passed to this API will not work */
+
+static void
+glusterd_dict_mgmt_v3_lock_statedump (dict_t *dict)
+{
+ int ret = 0;
+ int dumplen = 0;
+ data_pair_t *trav = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ char dump[64*1024] = {0,};
+
+ if (!dict) {
+ gf_log_callingfn ("glusterd", GF_LOG_WARNING, "dict NULL");
+ goto out;
+ }
+ for (trav = dict->members_list; trav; trav = trav->next) {
+ if (strstr (trav->key, "debug.last-success-bt") != NULL) {
+ ret = snprintf (&dump[dumplen], sizeof(dump) - dumplen,
+ "\n\t%s:%s", trav->key,
+ trav->value->data);
+ } else {
+ ret = snprintf (&dump[dumplen], sizeof(dump) - dumplen,
+ "\n\t%s:%s", trav->key,
+ uuid_utoa (((glusterd_mgmt_v3_lock_obj *)
+ (trav->value->data))->lock_owner));
+ }
+ if ((ret == -1) || !ret)
+ return;
+ dumplen += ret;
+ }
+
+ if (dumplen) {
+ gf_proc_dump_build_key (key, "glusterd", "mgmt_v3_lock");
+ gf_proc_dump_write (key, "%s", dump);
+ }
+
+out:
+ return;
+}
+
+int
+glusterd_dump_priv (xlator_t *this)
+{
+ int index = 1;
+ glusterd_conf_t *priv = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ char subkey[50] = {0,};
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+
+ GF_VALIDATE_OR_GOTO ("glusterd", this, out);
+
+ priv = this->private;
+ if (!priv)
+ return 0;
+
+ gf_proc_dump_build_key (key, "xlator.glusterd", "priv");
+ gf_proc_dump_add_section (key);
+
+ pthread_mutex_lock (&priv->mutex);
+ {
+ gf_proc_dump_build_key (key, "glusterd", "my-uuid");
+ gf_proc_dump_write (key, "%s", uuid_utoa (priv->uuid));
+
+ gf_proc_dump_build_key (key, "glusterd", "working-directory");
+ gf_proc_dump_write (key, "%s", priv->workdir);
+
+ gf_proc_dump_build_key (key, "glusterd", "max-op-version");
+ gf_proc_dump_write (key, "%d", GD_OP_VERSION_MAX);
+
+ gf_proc_dump_build_key (key, "glusterd", "min-op-version");
+ gf_proc_dump_write (key, "%d", GD_OP_VERSION_MIN);
+
+ gf_proc_dump_build_key (key, "glusterd", "current-op-version");
+ gf_proc_dump_write (key, "%d", priv->op_version);
+
+ gf_proc_dump_build_key (key, "glusterd", "ping-timeout");
+ gf_proc_dump_write (key, "%d", priv->ping_timeout);
+
+ gf_proc_dump_build_key (key, "glusterd", "shd.online");
+ gf_proc_dump_write (key, "%d", priv->shd->online);
+
+ gf_proc_dump_build_key (key, "glusterd", "nfs.online");
+ gf_proc_dump_write (key, "%d", priv->nfs->online);
+
+ gf_proc_dump_build_key (key, "glusterd", "quotad.online");
+ gf_proc_dump_write (key, "%d", priv->quotad->online);
+
+ GLUSTERD_DUMP_PEERS (&priv->peers, uuid_list, _gf_false);
+ GLUSTERD_DUMP_PEERS (&priv->xaction_peers, op_peers_list,
+ _gf_true);
+ glusterd_dump_client_details (priv);
+ glusterd_dict_mgmt_v3_lock_statedump(priv->mgmt_v3_lock);
+ dict_dump_to_statedump (priv->opts, "options", "glusterd");
+ }
+ pthread_mutex_unlock (&priv->mutex);
+
+out:
+ return 0;
+}
int32_t
mem_acct_init (xlator_t *this)
@@ -1446,6 +1660,7 @@ init (xlator_t *this)
GF_VALIDATE_OR_GOTO(this->name, conf->quotad, out);
INIT_LIST_HEAD (&conf->peers);
+ INIT_LIST_HEAD (&conf->xaction_peers);
INIT_LIST_HEAD (&conf->volumes);
INIT_LIST_HEAD (&conf->snapshots);
INIT_LIST_HEAD (&conf->missed_snaps_list);
@@ -1630,7 +1845,7 @@ struct xlator_fops fops;
struct xlator_cbks cbks;
struct xlator_dumpops dumpops = {
- .priv = glusterd_priv,
+ .priv = glusterd_dump_priv,
};
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 846603585b1..64fe63933a5 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -624,6 +624,28 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);
*snap_volname_ptr = '\0'; \
} while (0)
+#define GLUSTERD_DUMP_PEERS(head, member, xpeers) do { \
+ glusterd_peerinfo_t *_peerinfo = NULL; \
+ char subkey[50] = {0,}; \
+ int index = 1; \
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,}; \
+ \
+ if (!xpeers) \
+ snprintf (key, sizeof (key), "glusterd.peer"); \
+ else \
+ snprintf (key, sizeof (key), \
+ "glusterd.xaction_peer"); \
+ \
+ list_for_each_entry (_peerinfo, head, member) { \
+ glusterd_dump_peer (_peerinfo, key, index, xpeers); \
+ if (!xpeers) \
+ glusterd_dump_peer_rpcstat (_peerinfo, key, \
+ index); \
+ index++; \
+ } \
+ \
+ } while (0)
+
int glusterd_uuid_init();
int glusterd_uuid_generate_save ();
@@ -1057,4 +1079,12 @@ glusterd_add_brick_status_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo,
int32_t
glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict);
+void
+glusterd_dump_peer (glusterd_peerinfo_t *peerinfo, char *key, int index,
+ gf_boolean_t xpeers);
+
+void
+glusterd_dump_peer_rpcstat (glusterd_peerinfo_t *peerinfo, char *key,
+ int index);
+
#endif
diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c
index 47e49502595..d02206b3ed9 100644
--- a/xlators/protocol/client/src/client-rpc-fops.c
+++ b/xlators/protocol/client/src/client-rpc-fops.c
@@ -2832,7 +2832,7 @@ client3_3_readv_cbk (struct rpc_req *req, struct iovec *iov, int count,
rsp.op_errno, out);
#ifdef GF_TESTING_IO_XDATA
- dict_dump (xdata);
+ dict_dump_to_log (xdata);
#endif
out:
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
index 0438fb971c3..2337deb6dc1 100644
--- a/xlators/protocol/server/src/server-rpc-fops.c
+++ b/xlators/protocol/server/src/server-rpc-fops.c
@@ -3787,7 +3787,7 @@ server3_3_writev (rpcsvc_request_t *req)
op_errno, out);
#ifdef GF_TESTING_IO_XDATA
- dict_dump (state->xdata);
+ dict_dump_to_log (state->xdata);
#endif
ret = 0;