diff options
author | Kaushal M <kaushal@redhat.com> | 2012-01-01 15:59:28 +0530 |
---|---|---|
committer | Vijay Bellur <vijay@gluster.com> | 2012-01-27 04:20:04 -0800 |
commit | 623919a78a7faac30d1f0df5793681da2c449e32 (patch) | |
tree | ee213fa96ebf5feb938babf36c34cb7c8d5f6a24 /libglusterfs | |
parent | a078235dbede380ca695251e86a1502ca131d816 (diff) |
cli: Extend "volume status" with statedump info
This patch enhances and extends the "volume status" command with information
obtained from the statedump of the bricks of volumes.
Adds new status types : clients, inode, fd, mem, callpool
The new syntax of "volume status" is,
#gluster volume status [all|{<volname> [<brickname>]
[misc-details|clients|inode|fd|mem|callpool]}]
Change-Id: I8d019718465bbc3de727653a839de7238f45da5c
BUG: 765495
Signed-off-by: Kaushal M <kaushal@redhat.com>
Reviewed-on: http://review.gluster.com/2637
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Krishnan Parthasarathi <kp@gluster.com>
Diffstat (limited to 'libglusterfs')
-rw-r--r-- | libglusterfs/src/fd.c | 92 | ||||
-rw-r--r-- | libglusterfs/src/inode.c | 96 | ||||
-rw-r--r-- | libglusterfs/src/stack.c | 188 | ||||
-rw-r--r-- | libglusterfs/src/stack.h | 3 | ||||
-rw-r--r-- | libglusterfs/src/statedump.c | 110 | ||||
-rw-r--r-- | libglusterfs/src/statedump.h | 8 | ||||
-rw-r--r-- | libglusterfs/src/xlator.h | 27 |
7 files changed, 518 insertions, 6 deletions
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c index 50a564ee6df..62a70c457e7 100644 --- a/libglusterfs/src/fd.c +++ b/libglusterfs/src/fd.c @@ -905,3 +905,95 @@ out: return; } + +void +fdentry_dump_to_dict (fdentry_t *fdentry, char *prefix, dict_t *dict, + int *openfds) +{ + char key[GF_DUMP_MAX_BUF_LEN] = {0,}; + int ret = -1; + + if (!fdentry) + return; + if (!dict) + return; + + if (GF_FDENTRY_ALLOCATED != fdentry->next_free) + return; + + if (fdentry->fd) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.pid", prefix); + ret = dict_set_int32 (dict, key, fdentry->fd->pid); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.refcount", prefix); + ret = dict_set_int32 (dict, key, fdentry->fd->refcount); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.flags", prefix); + ret = dict_set_int32 (dict, key, fdentry->fd->flags); + + (*openfds)++; + } + return; +} + +void +fdtable_dump_to_dict (fdtable_t *fdtable, char *prefix, dict_t *dict) +{ + char key[GF_DUMP_MAX_BUF_LEN] = {0,}; + int i = 0; + int openfds = 0; + int ret = -1; + + if (!fdtable) + return; + if (!dict) + return; + + ret = pthread_mutex_trylock (&fdtable->lock); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.fdtable.refcount", prefix); + ret = dict_set_int32 (dict, key, fdtable->refcount); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.fdtable.maxfds", prefix); + ret = dict_set_uint32 (dict, key, fdtable->max_fds); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.fdtable.firstfree", prefix); + ret = dict_set_int32 (dict, key, fdtable->first_free); + if (ret) + goto out; + + for (i = 0; i < fdtable->max_fds; i++) { + if (GF_FDENTRY_ALLOCATED == + fdtable->fdentries[i].next_free) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.fdtable.fdentry%d", + prefix, i); + fdentry_dump_to_dict (&fdtable->fdentries[i], key, + dict, &openfds); + } + } + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.fdtable.openfds", prefix); + ret = dict_set_int32 (dict, key, openfds); + +out: + pthread_mutex_unlock (&fdtable->lock); + return; +} diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index c23f0f0e545..4685ec8d255 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -1637,3 +1637,99 @@ inode_table_dump (inode_table_t *itable, char *prefix) pthread_mutex_unlock(&itable->lock); } + +void +inode_dump_to_dict (inode_t *inode, char *prefix, dict_t *dict) +{ + int ret = -1; + char key[GF_DUMP_MAX_BUF_LEN] = {0,}; + + ret = TRY_LOCK (&inode->lock); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.gfid", prefix); + ret = dict_set_str (dict, key, gf_strdup (uuid_utoa (inode->gfid))); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.nlookup", prefix); + ret = dict_set_uint64 (dict, key, inode->nlookup); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.ref", prefix); + ret = dict_set_uint32 (dict, key, inode->ref); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.ia_type", prefix); + ret = dict_set_int32 (dict, key, inode->ia_type); + +out: + UNLOCK (&inode->lock); + return; +} + +void +inode_table_dump_to_dict (inode_table_t *itable, char *prefix, dict_t *dict) +{ + char key[GF_DUMP_MAX_BUF_LEN] = {0,}; + int ret = 0; + inode_t *inode = NULL; + int count = 0; + + ret = pthread_mutex_trylock (&itable->lock); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.itable.active_size", prefix); + ret = dict_set_uint32 (dict, key, itable->active_size); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.itable.lru_size", prefix); + ret = dict_set_uint32 (dict, key, itable->lru_size); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.itable.purge_size", prefix); + ret = dict_set_uint32 (dict, key, itable->purge_size); + if (ret) + goto out; + + list_for_each_entry (inode, &itable->active, list) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.itable.active%d", prefix, + count++); + inode_dump_to_dict (inode, key, dict); + } + count = 0; + + list_for_each_entry (inode, &itable->lru, list) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.itable.lru%d", prefix, + count++); + inode_dump_to_dict (inode, key, dict); + } + count = 0; + + list_for_each_entry (inode, &itable->purge, list) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.itable.purge%d", prefix, + count++); + inode_dump_to_dict (inode, key, dict); + } + +out: + pthread_mutex_unlock (&itable->lock); + + return; +} diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c index 0f65faa6fb7..29b44aedfac 100644 --- a/libglusterfs/src/stack.c +++ b/libglusterfs/src/stack.c @@ -161,6 +161,194 @@ gf_proc_dump_pending_frames (call_pool_t *call_pool) UNLOCK (&(call_pool->lock)); } +void +gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame, + char *prefix, dict_t *dict) +{ + int ret = -1; + char key[GF_DUMP_MAX_BUF_LEN] = {0,}; + call_frame_t tmp_frame = {0,}; + + if (!call_frame || !dict) + return; + + ret = TRY_LOCK (&call_frame->lock); + if (ret) + return; + memcpy (&tmp_frame, call_frame, sizeof (tmp_frame)); + UNLOCK (&call_frame->lock); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.refcount", prefix); + ret = dict_set_int32 (dict, key, tmp_frame.ref_count); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.translator", prefix); + ret = dict_set_str (dict, key, gf_strdup (tmp_frame.this->name)); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.complete", prefix); + ret = dict_set_int32 (dict, key, tmp_frame.complete); + if (ret) + return; + + if (tmp_frame.parent) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.parent", prefix); + ret = dict_set_str (dict, key, + gf_strdup (tmp_frame.parent->this->name)); + if (ret) + return; + } + + if (tmp_frame.wind_from) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.windfrom", prefix); + ret = dict_set_str (dict, key, gf_strdup (tmp_frame.wind_from)); + if (ret) + return; + } + + if (tmp_frame.wind_to) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.windto", prefix); + ret = dict_set_str (dict, key, gf_strdup (tmp_frame.wind_to)); + if (ret) + return; + } + + if (tmp_frame.unwind_from) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.unwindfrom", prefix); + ret = dict_set_str (dict, key, gf_strdup (tmp_frame.unwind_from)); + if (ret) + return; + } + + if (tmp_frame.unwind_to) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.unwind_to", prefix); + ret = dict_set_str (dict, key, gf_strdup (tmp_frame.unwind_to)); + } + + return; +} + +void +gf_proc_dump_call_stack_to_dict (call_stack_t *call_stack, + char *prefix, dict_t *dict) +{ + int ret = -1; + char key[GF_DUMP_MAX_BUF_LEN] = {0,}; + call_frame_t *trav = NULL; + int count = 0; + int i = 0; + + if (!call_stack || !dict) + return; + + count = call_frames_count (&call_stack->frames); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.uid", prefix); + ret = dict_set_int32 (dict, key, call_stack->uid); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.gid", prefix); + ret = dict_set_int32 (dict, key, call_stack->gid); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.pid", prefix); + ret = dict_set_int32 (dict, key, call_stack->pid); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.unique", prefix); + ret = dict_set_uint64 (dict, key, call_stack->unique); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.op", prefix); + if (call_stack->type == GF_OP_TYPE_FOP) + ret = dict_set_str (dict, key, + gf_fop_list[call_stack->op]); + else if (call_stack->type == GF_OP_TYPE_MGMT) + ret = dict_set_str (dict, key, + gf_mgmt_list[call_stack->op]); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.type", prefix); + ret = dict_set_int32 (dict, key, call_stack->type); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.count", prefix); + ret = dict_set_int32 (dict, key, count); + if (ret) + return; + + trav = &call_stack->frames; + for (i = 0; i < count; i++) { + if (trav) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.frame%d", + prefix, i); + gf_proc_dump_call_frame_to_dict (trav, key, dict); + trav = trav->next; + } + } + + return; +} + +void +gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool, dict_t *dict) +{ + int ret = -1; + call_stack_t *trav = NULL; + char key[GF_DUMP_MAX_BUF_LEN] = {0,}; + int i = 0; + + if (!call_pool || !dict) + return; + + ret = TRY_LOCK (&call_pool->lock); + if (ret) { + gf_log (THIS->name, GF_LOG_WARNING, "Unable to dump call pool" + " to dict. errno: %d", errno); + return; + } + + ret = dict_set_int32 (dict, "callpool.count", call_pool->cnt); + if (ret) + goto out; + + list_for_each_entry (trav, &call_pool->all_frames, all_frames) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "callpool.stack%d", i); + gf_proc_dump_call_stack_to_dict (trav, key, dict); + i++; + } + +out: + UNLOCK (&call_pool->lock); + + return; +} + gf_boolean_t __is_fuse_call (call_frame_t *frame) { diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h index a5689e0966f..c8404057610 100644 --- a/libglusterfs/src/stack.h +++ b/libglusterfs/src/stack.h @@ -414,6 +414,7 @@ create_frame (xlator_t *xl, call_pool_t *pool) } void gf_proc_dump_pending_frames(call_pool_t *call_pool); - +void gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool, + dict_t *dict); gf_boolean_t __is_fuse_call (call_frame_t *frame); #endif /* _STACK_H */ diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c index c744c6c5ff8..8c6fe92158d 100644 --- a/libglusterfs/src/statedump.c +++ b/libglusterfs/src/statedump.c @@ -235,6 +235,61 @@ gf_proc_dump_mem_info () } void +gf_proc_dump_mem_info_to_dict (dict_t *dict) +{ + if (!dict) + return; +#ifdef HAVE_MALLOC_STATS + struct mallinfo info; + int ret = -1; + + memset (&info, 0, sizeof(struct mallinfo)); + info = mallinfo (); + + ret = dict_set_int32 (dict, "mallinfo.arena", info.arena); + if (ret) + return; + + ret = dict_set_int32 (dict, "mallinfo.ordblks", info.ordblks); + if (ret) + return; + + ret = dict_set_int32 (dict, "mallinfo.smblks", info.smblks); + if (ret) + return; + + ret = dict_set_int32 (dict, "mallinfo.hblks", info.hblks); + if (ret) + return; + + ret = dict_set_int32 (dict, "mallinfo.hblkhd", info.hblkhd); + if (ret) + return; + + ret = dict_set_int32 (dict, "mallinfo.usmblks", info.usmblks); + if (ret) + return; + + ret = dict_set_int32 (dict, "mallinfo.fsmblks", info.fsmblks); + if (ret) + return; + + ret = dict_set_int32 (dict, "mallinfo.uordblks", info.uordblks); + if (ret) + return; + + ret = dict_set_int32 (dict, "mallinfo.fordblks", info.fordblks); + if (ret) + return; + + ret = dict_set_int32 (dict, "mallinfo.keepcost", info.keepcost); + if (ret) + return; +#endif + return; +} + +void gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx) { struct mem_pool *pool = NULL; @@ -253,6 +308,61 @@ gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx) } } +void +gf_proc_dump_mempool_info_to_dict (glusterfs_ctx_t *ctx, dict_t *dict) +{ + struct mem_pool *pool = NULL; + char key[GF_DUMP_MAX_BUF_LEN] = {0,}; + int count = 0; + int ret = -1; + + if (!ctx || !dict) + return; + + list_for_each_entry (pool, &ctx->mempool_list, global_list) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "pool%d.name", count); + ret = dict_set_str (dict, key, pool->name); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "pool%d.hotcount", count); + ret = dict_set_int32 (dict, key, pool->hot_count); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "pool%d.coldcount", count); + ret = dict_set_int32 (dict, key, pool->cold_count); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "pool%d.paddedsizeof", count); + ret = dict_set_uint64 (dict, key, pool->padded_sizeof_type); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "pool%d.alloccount", count); + ret = dict_set_uint64 (dict, key, pool->alloc_count); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "pool%d.max_alloc", count); + ret = dict_set_int32 (dict, key, pool->max_alloc); + if (ret) + return; + + count++; + } + ret = dict_set_int32 (dict, "mempool-count", count); + + return; +} + void gf_proc_dump_latency_info (xlator_t *xl); void diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h index 1c56d6cfa8a..cdeb5b7fc0c 100644 --- a/libglusterfs/src/statedump.h +++ b/libglusterfs/src/statedump.h @@ -77,9 +77,17 @@ int gf_proc_dump_write(char *key, char *value,...); void inode_table_dump(inode_table_t *itable, char *prefix); +void inode_table_dump_to_dict (inode_table_t *itable, char *prefix, dict_t *dict); + void fdtable_dump(fdtable_t *fdtable, char *prefix); +void fdtable_dump_to_dict (fdtable_t *fdtable, char *prefix, dict_t *dict); + void inode_dump(inode_t *inode, char *prefix); +void gf_proc_dump_mem_info_to_dict (dict_t *dict); + +void gf_proc_dump_mempool_info_to_dict (glusterfs_ctx_t *ctx, dict_t *dict); + void glusterd_init (int sig); #endif /* STATEDUMP_H */ diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index bc3d7a6dcf6..cca2505ab18 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -756,12 +756,29 @@ typedef int32_t (*dumpop_inodectx_t) (xlator_t *this, inode_t *ino); typedef int32_t (*dumpop_fdctx_t) (xlator_t *this, fd_t *fd); +typedef int32_t (*dumpop_priv_to_dict_t) (xlator_t *this, dict_t *dict); + +typedef int32_t (*dumpop_inode_to_dict_t) (xlator_t *this, dict_t *dict); + +typedef int32_t (*dumpop_fd_to_dict_t) (xlator_t *this, dict_t *dict); + +typedef int32_t (*dumpop_inodectx_to_dict_t) (xlator_t *this, inode_t *ino, + dict_t *dict); + +typedef int32_t (*dumpop_fdctx_to_dict_t) (xlator_t *this, fd_t *fd, + dict_t *dict); + struct xlator_dumpops { - dumpop_priv_t priv; - dumpop_inode_t inode; - dumpop_fd_t fd; - dumpop_inodectx_t inodectx; - dumpop_fdctx_t fdctx; + dumpop_priv_t priv; + dumpop_inode_t inode; + dumpop_fd_t fd; + dumpop_inodectx_t inodectx; + dumpop_fdctx_t fdctx; + dumpop_priv_to_dict_t priv_to_dict; + dumpop_inode_to_dict_t inode_to_dict; + dumpop_fd_to_dict_t fd_to_dict; + dumpop_inodectx_to_dict_t inodectx_to_dict; + dumpop_fdctx_to_dict_t fdctx_to_dict; }; typedef struct xlator_list { |