diff options
author | Raghavendra G <raghavendra@gluster.com> | 2010-09-16 04:04:58 +0000 |
---|---|---|
committer | Vijay Bellur <vijay@dev.gluster.com> | 2010-09-16 06:38:38 -0700 |
commit | 279fbb6f71f36b90480f19e5a98d0b1d27215733 (patch) | |
tree | 86801a1c9c37bd303433991595064a2e24ec4a55 | |
parent | 27d45ce245376cb012b0dd80dee6ccb26cc12645 (diff) |
performance/write-behind: dump contents of wb-file
Signed-off-by: Raghavendra G <raghavendra@gluster.com>
Signed-off-by: Vijay Bellur <vijay@dev.gluster.com>
BUG: 1059 (enhancements for getting statistics from performance translators)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1059
-rw-r--r-- | libglusterfs/src/fd.c | 53 | ||||
-rw-r--r-- | libglusterfs/src/fd.h | 5 | ||||
-rw-r--r-- | libglusterfs/src/inode.c | 116 | ||||
-rw-r--r-- | libglusterfs/src/statedump.c | 12 | ||||
-rw-r--r-- | libglusterfs/src/statedump.h | 4 | ||||
-rw-r--r-- | libglusterfs/src/xlator.h | 2 | ||||
-rw-r--r-- | xlators/performance/write-behind/src/write-behind.c | 162 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 2 |
8 files changed, 319 insertions, 37 deletions
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c index 870c85e3f32..9e91cdb8341 100644 --- a/libglusterfs/src/fd.c +++ b/libglusterfs/src/fd.c @@ -806,3 +806,56 @@ fdtable_dump (fdtable_t *fdtable, char *prefix) pthread_mutex_unlock(&fdtable->lock); } + + +void +fd_ctx_dump (fd_t *fd, char *prefix) +{ + struct _fd_ctx *fd_ctx = NULL; + xlator_t *xl = NULL; + int i = 0; + + + if ((fd == NULL) || (fd->_ctx == NULL)) { + goto out; + } + + LOCK (&fd->lock); + { + if (fd->_ctx != NULL) { + fd_ctx = GF_CALLOC (fd->inode->table->xl->graph->xl_count, + sizeof (*fd_ctx), + gf_common_mt_fd_ctx); + if (fd_ctx == NULL) { + gf_log ("fd", GF_LOG_ERROR, "out of memory"); + goto unlock; + } + + for (i = 0; i < fd->inode->table->xl->graph->xl_count; + i++) { + fd_ctx[i] = fd->_ctx[i]; + } + } + } +unlock: + UNLOCK (&fd->lock); + + if (fd_ctx == NULL) { + goto out; + } + + for (i = 0; i < fd->inode->table->xl->graph->xl_count; i++) { + if (fd_ctx[i].xl_key) { + xl = (xlator_t *)(long)fd_ctx[i].xl_key; + if (xl->dumpops && xl->dumpops->fdctx) + xl->dumpops->fdctx (xl, fd); + } + } + +out: + if (fd_ctx != NULL) { + GF_FREE (fd_ctx); + } + + return; +} diff --git a/libglusterfs/src/fd.h b/libglusterfs/src/fd.h index e01ef753e28..4ea7fc165e3 100644 --- a/libglusterfs/src/fd.h +++ b/libglusterfs/src/fd.h @@ -164,5 +164,10 @@ __fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value); int __fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value); +fd_t * +_fd_ref (fd_t *fd); + +void +fd_ctx_dump (fd_t *fd, char *prefix); #endif /* _FD_H */ diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index 45d151ef04b..989c25217b7 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -23,6 +23,7 @@ #endif #include "inode.h" +#include "fd.h" #include "common-utils.h" #include "statedump.h" #include <pthread.h> @@ -36,7 +37,7 @@ move latest accessed dentry to list_head of inode */ -#define INODE_DUMP_LIST(head, key_buf, key_prefix, list_type) \ +#define INODE_DUMP_LIST(head, key_buf, key_prefix, list_type) \ { \ int i = 1; \ inode_t *inode = NULL; \ @@ -54,6 +55,9 @@ __inode_unref (inode_t *inode); static int inode_table_prune (inode_table_t *table); +void +fd_dump (struct list_head *head, char *prefix); + static int hash_dentry (inode_t *parent, const char *name, int mod) { @@ -1351,47 +1355,105 @@ inode_ctx_del (inode_t *inode, xlator_t *key, uint64_t *value) void inode_dump (inode_t *inode, char *prefix) { - char key[GF_DUMP_MAX_BUF_LEN]; - int ret = -1; - xlator_t *xl = NULL; - int i = 0; - char uuidbuf[256]; + char key[GF_DUMP_MAX_BUF_LEN]; + int ret = -1; + xlator_t *xl = NULL; + int i = 0; + char uuidbuf[256]; + fd_t *fd = NULL; + struct _inode_ctx *inode_ctx = NULL; + struct fd_wrapper { + fd_t *fd; + struct list_head next; + } *fd_wrapper, *tmp; + struct list_head fd_list; if (!inode) return; + INIT_LIST_HEAD (&fd_list); + ret = TRY_LOCK(&inode->lock); if (ret != 0) { - gf_log("", GF_LOG_WARNING, "Unable to dump inode" - " errno: %d", errno); + gf_log ("", GF_LOG_WARNING, "Unable to dump inode" + " errno: %d", errno); return; } - uuid_unparse (inode->gfid, uuidbuf); - gf_proc_dump_build_key(key, prefix, "gfid"); - gf_proc_dump_write(key, "%s", uuidbuf); - gf_proc_dump_build_key(key, prefix, "nlookup"); - gf_proc_dump_write(key, "%ld", inode->nlookup); - gf_proc_dump_build_key(key, prefix, "ref"); - gf_proc_dump_write(key, "%u", inode->ref); - gf_proc_dump_build_key(key, prefix, "ino"); - gf_proc_dump_write(key, "%ld", inode->ino); - gf_proc_dump_build_key(key, prefix, "ia_type"); - gf_proc_dump_write(key, "%d", inode->ia_type); + { + uuid_unparse (inode->gfid, uuidbuf); + gf_proc_dump_build_key(key, prefix, "gfid"); + gf_proc_dump_write(key, "%s", uuidbuf); + gf_proc_dump_build_key(key, prefix, "nlookup"); + gf_proc_dump_write(key, "%ld", inode->nlookup); + gf_proc_dump_build_key(key, prefix, "ref"); + gf_proc_dump_write(key, "%u", inode->ref); + gf_proc_dump_build_key(key, prefix, "ino"); + gf_proc_dump_write(key, "%ld", inode->ino); + gf_proc_dump_build_key(key, prefix, "ia_type"); + gf_proc_dump_write(key, "%d", inode->ia_type); + if (inode->_ctx) { + inode_ctx = GF_CALLOC (inode->table->xl->graph->xl_count, + sizeof (*inode_ctx), + gf_common_mt_inode_ctx); + if (inode_ctx == NULL) { + gf_log ("", GF_LOG_ERROR, "out of memory"); + goto unlock; + } + + for (i = 0; i < inode->table->xl->graph->xl_count; i++) { + inode_ctx[i] = inode->_ctx[i]; + } + } + + if (list_empty (&inode->fd_list)) { + goto unlock; + } + + list_for_each_entry (fd, &inode->fd_list, inode_list) { + fd_wrapper = GF_CALLOC (1, sizeof (*fd_wrapper), + gf_common_mt_char); + if (fd_wrapper == NULL) { + gf_log ("", GF_LOG_ERROR, "out of memory"); + goto unlock; + } + + INIT_LIST_HEAD (&fd_wrapper->next); + list_add_tail (&fd_wrapper->next, &fd_list); + + fd_wrapper->fd = _fd_ref (fd); + } + } +unlock: UNLOCK(&inode->lock); - if (!inode->_ctx) - goto out; - for (i = 0; i < inode->table->xl->graph->xl_count; i++) { - if (inode->_ctx[i].xl_key) { - xl = (xlator_t *)(long)inode->_ctx[i].xl_key; - if (xl->dumpops && xl->dumpops->inodectx) - xl->dumpops->inodectx (xl, inode); + if (inode_ctx && (dump_options.xl_options.dump_inodectx == _gf_true)) { + for (i = 0; i < inode->table->xl->graph->xl_count; i++) { + if (inode_ctx[i].xl_key) { + xl = (xlator_t *)(long)inode_ctx[i].xl_key; + if (xl->dumpops && xl->dumpops->inodectx) + xl->dumpops->inodectx (xl, inode); + } } } -out: + if (!list_empty (&fd_list) + && (dump_options.xl_options.dump_fdctx == _gf_true)) { + list_for_each_entry_safe (fd_wrapper, tmp, &fd_list, + next) { + list_del (&fd_wrapper->next); + fd_ctx_dump (fd_wrapper->fd, prefix); + + fd_unref (fd_wrapper->fd); + GF_FREE (fd_wrapper); + } + } + + if (inode_ctx != NULL) { + GF_FREE (inode_ctx); + } + return; } diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c index 230e7c2ef30..55832d2c802 100644 --- a/libglusterfs/src/statedump.c +++ b/libglusterfs/src/statedump.c @@ -39,7 +39,7 @@ extern xlator_t global_xlator; static pthread_mutex_t gf_proc_dump_mutex; static int gf_dump_fd = -1; -static gf_dump_options_t dump_options; +gf_dump_options_t dump_options; static void @@ -292,6 +292,10 @@ gf_proc_dump_parse_set_option (char *key, char *value) opt_key = &dump_options.xl_options.dump_fd; } else if (!strncasecmp (key, "inode", 5)) { opt_key = &dump_options.xl_options.dump_inode; + } else if (!strncasecmp (key, "inodectx", strlen ("inodectx"))) { + opt_key = &dump_options.xl_options.dump_inodectx; + } else if (!strncasecmp (key, "fdctx", strlen ("fdctx"))) { + opt_key = &dump_options.xl_options.dump_fdctx; } if (!opt_key) { @@ -322,6 +326,9 @@ gf_proc_dump_enable_all_options () GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_priv, _gf_true); GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inode, _gf_true); GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fd, _gf_true); + GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inodectx, + _gf_true); + GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fdctx, _gf_true); return 0; } @@ -337,6 +344,9 @@ gf_proc_dump_disable_all_options () GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inode, _gf_false); GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fd, _gf_false); + GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inodectx, + _gf_false); + GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fdctx, _gf_false); return 0; } diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h index 02cba5bac51..ba23ca559e9 100644 --- a/libglusterfs/src/statedump.h +++ b/libglusterfs/src/statedump.h @@ -35,6 +35,8 @@ typedef struct gf_dump_xl_options_ { gf_boolean_t dump_priv; gf_boolean_t dump_inode; gf_boolean_t dump_fd; + gf_boolean_t dump_inodectx; + gf_boolean_t dump_fdctx; } gf_dump_xl_options_t; typedef struct gf_dump_options_ { @@ -44,6 +46,8 @@ typedef struct gf_dump_options_ { gf_dump_xl_options_t xl_options; //options for all xlators } gf_dump_options_t; +extern gf_dump_options_t dump_options; + static inline void _gf_proc_dump_build_key (char *key, const char *prefix, char *fmt,...) { diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index c71aa7bb3cc..2aa9b372b8a 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -732,12 +732,14 @@ typedef int32_t (*dumpop_fd_t) (xlator_t *this); typedef int32_t (*dumpop_inodectx_t) (xlator_t *this, inode_t *ino); +typedef int32_t (*dumpop_fdctx_t) (xlator_t *this, fd_t *fd); struct xlator_dumpops { dumpop_priv_t priv; dumpop_inode_t inode; dumpop_fd_t fd; dumpop_inodectx_t inodectx; + dumpop_fdctx_t fdctx; }; typedef struct xlator_list { diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c index 4437afce0cf..c9fc25a5b57 100644 --- a/xlators/performance/write-behind/src/write-behind.c +++ b/xlators/performance/write-behind/src/write-behind.c @@ -66,14 +66,15 @@ typedef struct wb_file { typedef struct wb_request { - list_head_t list; - list_head_t winds; - list_head_t unwinds; - list_head_t other_requests; - call_stub_t *stub; - size_t write_size; - int32_t refcount; - wb_file_t *file; + list_head_t list; + list_head_t winds; + list_head_t unwinds; + list_head_t other_requests; + call_stub_t *stub; + size_t write_size; + int32_t refcount; + wb_file_t *file; + glusterfs_fop_t fop; union { struct { char write_behind; @@ -241,6 +242,7 @@ wb_enqueue (wb_file_t *file, call_stub_t *stub) request->stub = stub; request->file = file; + request->fop = stub->fop; frame = stub->frame; local = frame->local; @@ -2563,6 +2565,149 @@ wb_priv_dump (xlator_t *this) return 0; } + +void +__wb_dump_requests (struct list_head *head, char *prefix, char passive) +{ + char key[GF_DUMP_MAX_BUF_LEN]; + char key_prefix[GF_DUMP_MAX_BUF_LEN]; + wb_request_t *request = NULL; + + list_for_each_entry (request, head, list) { + gf_proc_dump_build_key (key, prefix, + passive ? "passive-request" + : "active-request"); + gf_proc_dump_build_key (key_prefix, key, + gf_fop_list[request->fop]); + + gf_proc_dump_add_section(key_prefix); + + gf_proc_dump_build_key (key, key_prefix, "request-ptr"); + gf_proc_dump_write (key, "%p", request); + + gf_proc_dump_build_key (key, key_prefix, "refcount"); + gf_proc_dump_write (key, "%d", request->refcount); + + if (request->fop == GF_FOP_WRITE) { + gf_proc_dump_build_key (key, key_prefix, "stack_wound"); + gf_proc_dump_write (key, "%d", + request->flags.write_request.stack_wound); + + gf_proc_dump_build_key (key, key_prefix, "size"); + gf_proc_dump_write (key, "%"GF_PRI_SIZET, + request->write_size); + + gf_proc_dump_build_key (key, key_prefix, "offset"); + gf_proc_dump_write (key, "%"PRId64, + request->stub->args.writev.off); + + gf_proc_dump_build_key (key, key_prefix, + "write_behind"); + gf_proc_dump_write (key, "%d", + request->flags.write_request.write_behind); + + gf_proc_dump_build_key (key, key_prefix, "got_reply"); + gf_proc_dump_write (key, "%d", + request->flags.write_request.got_reply); + + gf_proc_dump_build_key (key, key_prefix, "virgin"); + gf_proc_dump_write (key, "%d", + request->flags.write_request.virgin); + + gf_proc_dump_build_key (key, key_prefix, "flush_all"); + gf_proc_dump_write (key, "%d", + request->flags.write_request.flush_all); + } else { + gf_proc_dump_build_key (key, key_prefix, + "marked_for_resume"); + gf_proc_dump_write (key, "%d", + request->flags.other_requests.marked_for_resume); + } + } +} + + +int +wb_file_dump (xlator_t *this, fd_t *fd) +{ + wb_file_t *file = NULL; + uint64_t tmp_file = 0; + int32_t ret = -1; + char key[GF_DUMP_MAX_BUF_LEN]; + char key_prefix[GF_DUMP_MAX_BUF_LEN]; + + if ((fd == NULL) || (this == NULL)) { + ret = 0; + goto out; + } + + ret = fd_ctx_get (fd, this, &tmp_file); + if (ret == -1) { + ret = 0; + goto out; + } + + file = (wb_file_t *)(long)tmp_file; + if (file == NULL) { + ret = 0; + goto out; + } + + gf_proc_dump_build_key (key_prefix, + "xlator.performance.write-behind", + "file"); + + gf_proc_dump_add_section (key_prefix); + + gf_proc_dump_build_key (key, key_prefix, "fd"); + gf_proc_dump_write (key, "%p", fd); + + gf_proc_dump_build_key (key, key_prefix, "disabled"); + gf_proc_dump_write (key, "%d", file->disabled); + + gf_proc_dump_build_key (key, key_prefix, "disable_till"); + gf_proc_dump_write (key, "%lu", file->disable_till); + + gf_proc_dump_build_key (key, key_prefix, "window_conf"); + gf_proc_dump_write (key, "%"GF_PRI_SIZET, file->window_conf); + + gf_proc_dump_build_key (key, key_prefix, "window_current"); + gf_proc_dump_write (key, "%"GF_PRI_SIZET, file->window_current); + + gf_proc_dump_build_key (key, key_prefix, "flags"); + gf_proc_dump_write (key, "%s", (file->flags & O_APPEND) ? "O_APPEND" + : "!O_APPEND"); + + gf_proc_dump_build_key (key, key_prefix, "aggregate_current"); + gf_proc_dump_write (key, "%"GF_PRI_SIZET, file->aggregate_current); + + gf_proc_dump_build_key (key, key_prefix, "refcount"); + gf_proc_dump_write (key, "%d", file->refcount); + + gf_proc_dump_build_key (key, key_prefix, "op_ret"); + gf_proc_dump_write (key, "%d", file->op_ret); + + gf_proc_dump_build_key (key, key_prefix, "op_errno"); + gf_proc_dump_write (key, "%d", file->op_errno); + + LOCK (&file->lock); + { + if (!list_empty (&file->request)) { + __wb_dump_requests (&file->request, key_prefix, 0); + } + + if (!list_empty (&file->passive_requests)) { + __wb_dump_requests (&file->passive_requests, key_prefix, + 1); + } + } + UNLOCK (&file->lock); + +out: + return ret; +} + + int32_t mem_acct_init (xlator_t *this) { @@ -2750,6 +2895,7 @@ struct xlator_cbks cbks = { struct xlator_dumpops dumpops = { .priv = wb_priv_dump, + .fdctx = wb_file_dump, }; struct volume_options options[] = { diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index 3415eb35cc3..85d157f5f8a 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -803,7 +803,7 @@ get_frame_from_request (rpcsvc_request_t *req) frame->root->uid = req->uid; frame->root->gid = req->gid; frame->root->pid = req->pid; - frame->root->trans = req->trans; + frame->root->trans = req->trans->xl_private; frame->root->lk_owner = req->lk_owner; server_decode_groups (frame, req); |