summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/stack.c')
-rw-r--r--libglusterfs/src/stack.c144
1 files changed, 107 insertions, 37 deletions
diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c
index 29b44aedf..37b338f51 100644
--- a/libglusterfs/src/stack.c
+++ b/libglusterfs/src/stack.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#include "statedump.h"
@@ -35,6 +26,44 @@ int call_frames_count (call_frame_t *call_frame)
return count;
}
+call_frame_t *
+create_frame (xlator_t *xl, call_pool_t *pool)
+{
+ call_stack_t *stack = NULL;
+
+ if (!xl || !pool) {
+ return NULL;
+ }
+
+ stack = mem_get0 (pool->stack_mem_pool);
+ if (!stack)
+ return NULL;
+
+ stack->pool = pool;
+ stack->frames.root = stack;
+ stack->frames.this = xl;
+ stack->ctx = xl->ctx;
+
+ if (stack->ctx->measure_latency) {
+ if (gettimeofday (&stack->tv, NULL) == -1)
+ gf_log ("stack", GF_LOG_ERROR, "gettimeofday () failed."
+ " (%s)", strerror (errno));
+ memcpy (&stack->frames.begin, &stack->tv, sizeof (stack->tv));
+ }
+
+ LOCK (&pool->lock);
+ {
+ list_add (&stack->all_frames, &pool->all_frames);
+ pool->cnt++;
+ }
+ UNLOCK (&pool->lock);
+
+ LOCK_INIT (&stack->frames.lock);
+ LOCK_INIT (&stack->stack_lock);
+
+ return &stack->frames;
+}
+
void
gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
{
@@ -43,6 +72,7 @@ gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
va_list ap;
call_frame_t my_frame;
int ret = -1;
+ char timestr[256] = {0,};
if (!call_frame)
return;
@@ -56,15 +86,21 @@ gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
va_end(ap);
ret = TRY_LOCK(&call_frame->lock);
- if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump call frame"
- " errno: %s", strerror (errno));
- return;
- }
+ if (ret)
+ goto out;
memcpy(&my_frame, call_frame, sizeof(my_frame));
UNLOCK(&call_frame->lock);
+ if (my_frame.this->ctx->measure_latency) {
+ gf_time_fmt (timestr, sizeof timestr, my_frame.begin.tv_sec,
+ gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, my_frame.begin.tv_usec);
+ gf_proc_dump_write("frame-creation-time", "%s", timestr);
+ }
+
gf_proc_dump_write("ref_count", "%d", my_frame.ref_count);
gf_proc_dump_write("translator", "%s", my_frame.this->name);
gf_proc_dump_write("complete", "%d", my_frame.complete);
@@ -82,6 +118,14 @@ gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
if (my_frame.unwind_to)
gf_proc_dump_write("unwind_to", "%s", my_frame.unwind_to);
+
+ ret = 0;
+out:
+ if (ret) {
+ gf_proc_dump_write("Unable to dump the frame information",
+ "(Lock acquisition failed) %p", my_frame);
+ return;
+ }
}
@@ -92,6 +136,7 @@ gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
va_list ap;
call_frame_t *trav;
int32_t cnt, i;
+ char timestr[256] = {0,};
if (!call_stack)
return;
@@ -105,15 +150,26 @@ gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
va_end(ap);
+ if (call_stack->ctx->measure_latency) {
+ gf_time_fmt (timestr, sizeof timestr, call_stack->tv.tv_sec,
+ gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, call_stack->tv.tv_usec);
+ gf_proc_dump_write("callstack-creation-time", "%s", timestr);
+ }
+
gf_proc_dump_write("uid", "%d", call_stack->uid);
gf_proc_dump_write("gid", "%d", call_stack->gid);
gf_proc_dump_write("pid", "%d", call_stack->pid);
gf_proc_dump_write("unique", "%Ld", call_stack->unique);
+ gf_proc_dump_write("lk-owner", "%s", lkowner_utoa (&call_stack->lk_owner));
if (call_stack->type == GF_OP_TYPE_FOP)
- gf_proc_dump_write("op", "%s", gf_fop_list[call_stack->op]);
- else if (call_stack->type == GF_OP_TYPE_MGMT)
- gf_proc_dump_write("op", "%s", gf_mgmt_list[call_stack->op]);
+ gf_proc_dump_write("op", "%s",
+ (char *)gf_fop_list[call_stack->op]);
+ else
+ gf_proc_dump_write("op", "stack");
gf_proc_dump_write("type", "%d", call_stack->type);
gf_proc_dump_write("cnt", "%d", cnt);
@@ -136,19 +192,18 @@ gf_proc_dump_pending_frames (call_pool_t *call_pool)
call_stack_t *trav = NULL;
int i = 1;
int ret = -1;
+ gf_boolean_t section_added = _gf_true;
if (!call_pool)
return;
ret = TRY_LOCK (&(call_pool->lock));
- if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump call pool"
- " errno: %d", errno);
- return;
- }
+ if (ret)
+ goto out;
gf_proc_dump_add_section("global.callpool");
+ section_added = _gf_true;
gf_proc_dump_write("callpool_address","%p", call_pool);
gf_proc_dump_write("callpool.cnt","%d", call_pool->cnt);
@@ -159,6 +214,17 @@ gf_proc_dump_pending_frames (call_pool_t *call_pool)
i++;
}
UNLOCK (&(call_pool->lock));
+
+ ret = 0;
+out:
+ if (ret) {
+ if (_gf_false == section_added)
+ gf_proc_dump_add_section("global.callpool");
+ gf_proc_dump_write("Unable to dump the callpool",
+ "(Lock acquisition failed) %p",
+ call_pool);
+ }
+ return;
}
void
@@ -186,7 +252,7 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.translator", prefix);
- ret = dict_set_str (dict, key, gf_strdup (tmp_frame.this->name));
+ ret = dict_set_dynstr (dict, key, gf_strdup (tmp_frame.this->name));
if (ret)
return;
@@ -199,7 +265,7 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
if (tmp_frame.parent) {
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.parent", prefix);
- ret = dict_set_str (dict, key,
+ ret = dict_set_dynstr (dict, key,
gf_strdup (tmp_frame.parent->this->name));
if (ret)
return;
@@ -208,7 +274,8 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
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));
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.wind_from));
if (ret)
return;
}
@@ -216,7 +283,8 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
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));
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.wind_to));
if (ret)
return;
}
@@ -224,7 +292,8 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
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));
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.unwind_from));
if (ret)
return;
}
@@ -232,7 +301,8 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
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));
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.unwind_to));
}
return;
@@ -281,10 +351,10 @@ gf_proc_dump_call_stack_to_dict (call_stack_t *call_stack,
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]);
+ (char *)gf_fop_list[call_stack->op]);
+ else
+ ret = dict_set_str (dict, key, "other");
+
if (ret)
return;