diff options
-rw-r--r-- | libglusterfs/src/dict.c | 77 | ||||
-rw-r--r-- | libglusterfs/src/dict.h | 8 | ||||
-rw-r--r-- | libglusterfs/src/mem-pool.c | 4 | ||||
-rwxr-xr-x | tests/bugs/bug-834465.t | 6 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-locks.c | 12 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.c | 223 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 30 | ||||
-rw-r--r-- | xlators/protocol/client/src/client-rpc-fops.c | 2 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-rpc-fops.c | 2 |
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; |