summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2010-09-16 04:04:58 +0000
committerVijay Bellur <vijay@dev.gluster.com>2010-09-16 06:38:38 -0700
commit279fbb6f71f36b90480f19e5a98d0b1d27215733 (patch)
tree86801a1c9c37bd303433991595064a2e24ec4a55
parent27d45ce245376cb012b0dd80dee6ccb26cc12645 (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.c53
-rw-r--r--libglusterfs/src/fd.h5
-rw-r--r--libglusterfs/src/inode.c116
-rw-r--r--libglusterfs/src/statedump.c12
-rw-r--r--libglusterfs/src/statedump.h4
-rw-r--r--libglusterfs/src/xlator.h2
-rw-r--r--xlators/performance/write-behind/src/write-behind.c162
-rw-r--r--xlators/protocol/server/src/server-helpers.c2
8 files changed, 319 insertions, 37 deletions
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c
index 870c85e3..9e91cdb8 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 e01ef753..4ea7fc16 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 45d151ef..989c2521 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 230e7c2e..55832d2c 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 02cba5ba..ba23ca55 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 c71aa7bb..2aa9b372 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 4437afce..c9fc25a5 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 3415eb35..85d157f5 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);