From 675d330897aa6923d667cc318ee466cb0cb84f9b Mon Sep 17 00:00:00 2001 From: Vijay Bellur Date: Thu, 13 May 2010 03:46:38 +0000 Subject: libglusterfs: Provide ability to filter output of state dump Output of statedump can be controlled by having file /tmp/glusterdump.input. /tmp/glusterdump.input needs to have a = in each line. key can be one of 'priv', 'fd', 'inode', 'mem', 'callpool' and 'iobuf'. value has to be one of 'yes' or 'no'. If /tmp/glusterdump.input is not available, no filtering happens in statedump. Else statedump would contain only those sections which correspond to a having value 'yes'. Signed-off-by: Vijay Bellur Signed-off-by: Anand V. Avati BUG: 828 (glusterdump filled up the /) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=828 --- libglusterfs/src/iobuf.c | 26 ++-- libglusterfs/src/statedump.c | 300 +++++++++++++++++++++++++++++++------------ libglusterfs/src/statedump.h | 34 +++-- 3 files changed, 258 insertions(+), 102 deletions(-) (limited to 'libglusterfs') diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c index 4d458b4ba71..b16409fbf81 100644 --- a/libglusterfs/src/iobuf.c +++ b/libglusterfs/src/iobuf.c @@ -695,40 +695,40 @@ iobuf_stats_dump (struct iobuf_pool *iobuf_pool) { char msg[1024]; - struct iobuf_arena *trav; + struct iobuf_arena *trav = NULL; int i = 1; int ret = -1; if (!iobuf_pool) return; - memset(msg, 0, sizeof(msg)); + memset (msg, 0, sizeof(msg)); - ret = pthread_mutex_trylock(&iobuf_pool->mutex); + ret = pthread_mutex_trylock (&iobuf_pool->mutex); if (ret) { - gf_log("", GF_LOG_WARNING, "Unable to dump iobuf pool" + gf_log ("", GF_LOG_WARNING, "Unable to dump iobuf pool" " errno: %d", errno); return; } - gf_proc_dump_add_section("iobuf.global"); - gf_proc_dump_write("iobuf.global.iobuf_pool","%p", iobuf_pool); - gf_proc_dump_write("iobuf.global.iobuf_pool.page_size", "%d", + gf_proc_dump_add_section ("iobuf.global"); + gf_proc_dump_write ("iobuf.global.iobuf_pool","%p", iobuf_pool); + gf_proc_dump_write ("iobuf.global.iobuf_pool.page_size", "%d", iobuf_pool->page_size); - gf_proc_dump_write("iobuf.global.iobuf_pool.arena_size", "%d", + gf_proc_dump_write( "iobuf.global.iobuf_pool.arena_size", "%d", iobuf_pool->arena_size); - gf_proc_dump_write("iobuf.global.iobuf_pool.arena_cnt", "%d", + gf_proc_dump_write ("iobuf.global.iobuf_pool.arena_cnt", "%d", iobuf_pool->arena_cnt); list_for_each_entry (trav, &iobuf_pool->arenas.list, list) { - snprintf(msg, sizeof(msg), "iobuf.global.iobuf_pool.arena.%d", + snprintf (msg, sizeof(msg), "iobuf.global.iobuf_pool.arena.%d", i); - gf_proc_dump_add_section(msg); - iobuf_arena_info_dump(trav,msg); + gf_proc_dump_add_section (msg); + iobuf_arena_info_dump (trav,msg); i++; } - pthread_mutex_unlock(&iobuf_pool->mutex); + pthread_mutex_unlock (&iobuf_pool->mutex); return; } diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c index 7f1e3e24196..1d77db87afd 100644 --- a/libglusterfs/src/statedump.c +++ b/libglusterfs/src/statedump.c @@ -28,20 +28,28 @@ #include #endif /* MALLOC_H */ + +#define GF_PROC_DUMP_IS_OPTION_ENABLED(opt) \ + (dump_options.dump_##opt == _gf_true) + +#define GF_PROC_DUMP_IS_XL_OPTION_ENABLED(opt)\ + (dump_options.xl_options.dump_##opt == _gf_true) + static pthread_mutex_t gf_proc_dump_mutex; static int gf_dump_fd = -1; +static gf_dump_options_t dump_options; -static void +static void gf_proc_dump_lock (void) { - pthread_mutex_lock(&gf_proc_dump_mutex); + pthread_mutex_lock (&gf_proc_dump_mutex); } -static void +static void gf_proc_dump_unlock (void) { - pthread_mutex_unlock(&gf_proc_dump_mutex); -} + pthread_mutex_unlock (&gf_proc_dump_mutex); +} static int gf_proc_dump_open (void) @@ -49,12 +57,13 @@ gf_proc_dump_open (void) char path[256]; int dump_fd = -1; - memset(path, 0, sizeof(path)); - snprintf(path, sizeof(path), "%s.%d",GF_DUMP_LOGFILE_ROOT, getpid()); + memset (path, 0, sizeof(path)); + snprintf (path, sizeof (path), "%s.%d",GF_DUMP_LOGFILE_ROOT, + getpid ()); - dump_fd = open(path, O_CREAT|O_RDWR|O_TRUNC|O_APPEND, 0600); + dump_fd = open (path, O_CREAT|O_RDWR|O_TRUNC|O_APPEND, 0600); if (dump_fd < 0) { - gf_log("", GF_LOG_ERROR, "Unable to open file: %s" + gf_log ("", GF_LOG_ERROR, "Unable to open file: %s" " errno: %d", path, errno); return -1; } @@ -63,56 +72,169 @@ gf_proc_dump_open (void) return 0; } +static int +gf_proc_dump_parse_set_option (char *key, char *value) +{ + gf_boolean_t *opt_key = NULL; + gf_boolean_t opt_value = _gf_false; + + + if (!strncasecmp (key, "mem", 3)) { + opt_key = &dump_options.dump_mem; + } else if (!strncasecmp (key, "iobuf", 5)) { + opt_key = &dump_options.dump_iobuf; + } else if (!strncasecmp (key, "callpool", 8)) { + opt_key = &dump_options.dump_callpool; + } else if (!strncasecmp (key, "priv", 4)) { + opt_key = &dump_options.xl_options.dump_priv; + } else if (!strncasecmp (key, "fd", 2)) { + opt_key = &dump_options.xl_options.dump_fd; + } else if (!strncasecmp (key, "inode", 5)) { + opt_key = &dump_options.xl_options.dump_inode; + } + + if (!opt_key) { + //None of dump options match the key, return back + gf_log ("", GF_LOG_WARNING, "None of the options matched key" + ": %s", key); + return -1; + } + + opt_value = (strncasecmp (value, "yes", 3) ? + _gf_false: _gf_true); + + GF_PROC_DUMP_SET_OPTION (*opt_key, opt_value); + + return 0; +} + + +static int +gf_proc_dump_enable_all_options () +{ + + GF_PROC_DUMP_SET_OPTION (dump_options.dump_mem, _gf_true); + GF_PROC_DUMP_SET_OPTION (dump_options.dump_iobuf, _gf_true); + GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_true); + 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); + + return 0; +} + +static int +gf_proc_dump_disable_all_options () +{ + + GF_PROC_DUMP_SET_OPTION (dump_options.dump_mem, _gf_false); + GF_PROC_DUMP_SET_OPTION (dump_options.dump_iobuf, _gf_false); + GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_false); + GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_priv, _gf_false); + 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); + + return 0; +} + +static int +gf_proc_dump_options_init () +{ + int ret = -1; + FILE *fp = NULL; + char buf[256]; + char *key = NULL, *value = NULL; + char *saveptr = NULL; + + fp = fopen (GF_DUMP_OPTIONFILE, "r"); + + if (!fp) { + //ENOENT, return success + (void) gf_proc_dump_enable_all_options (); + return 0; + } + + (void) gf_proc_dump_disable_all_options (); + + ret = fscanf (fp, "%s", buf); + + while (ret != EOF) { + + key = strtok_r (buf, "=", &saveptr); + if (!key) { + ret = fscanf (fp, "%s", buf); + continue; + } + + value = strtok_r (NULL, "=", &saveptr); + + if (!value) { + ret = fscanf (fp, "%s", buf); + continue; + } + + gf_log ("", GF_LOG_DEBUG, "key = %s, value = %s", + key, value); + + gf_proc_dump_parse_set_option (key, value); + + } + + return 0; +} + static void gf_proc_dump_close (void) { - close(gf_dump_fd); + close (gf_dump_fd); gf_dump_fd = -1; } void -gf_proc_dump_add_section (char *key, ...) +gf_proc_dump_add_section (char *key, ...) { - - char buf[GF_DUMP_MAX_BUF_LEN]; - va_list ap; - int ret; - assert(key); - - memset(buf, 0, sizeof(buf)); - snprintf(buf, GF_DUMP_MAX_BUF_LEN, "\n["); - va_start(ap, key); - vsnprintf(buf + strlen(buf), - GF_DUMP_MAX_BUF_LEN - strlen(buf), key, ap); - va_end(ap); - snprintf(buf + strlen(buf), - GF_DUMP_MAX_BUF_LEN - strlen(buf), "]\n"); - ret = write(gf_dump_fd, buf, strlen(buf)); + char buf[GF_DUMP_MAX_BUF_LEN]; + va_list ap; + int ret = -1; + + assert (key); + memset (buf, 0, sizeof(buf)); + snprintf (buf, GF_DUMP_MAX_BUF_LEN, "\n["); + va_start (ap, key); + vsnprintf (buf + strlen (buf), + GF_DUMP_MAX_BUF_LEN - strlen (buf), key, ap); + va_end (ap); + snprintf (buf + strlen (buf), + GF_DUMP_MAX_BUF_LEN - strlen (buf), "]\n"); + ret = write (gf_dump_fd, buf, strlen (buf)); } void -gf_proc_dump_write (char *key, char *value,...) -{ - - char buf[GF_DUMP_MAX_BUF_LEN]; - int offset = 0; - va_list ap; - int ret; - - offset = strlen(key); - - memset(buf, 0, GF_DUMP_MAX_BUF_LEN); - snprintf(buf, GF_DUMP_MAX_BUF_LEN, "%s",key); - snprintf(buf + offset, GF_DUMP_MAX_BUF_LEN - offset, "="); +gf_proc_dump_write (char *key, char *value,...) +{ + + char buf[GF_DUMP_MAX_BUF_LEN]; + int offset = 0; + va_list ap; + int ret = -1; + + assert (key); + + offset = strlen (key); + + memset (buf, 0, GF_DUMP_MAX_BUF_LEN); + snprintf (buf, GF_DUMP_MAX_BUF_LEN, "%s",key); + snprintf (buf + offset, GF_DUMP_MAX_BUF_LEN - offset, "="); offset += 1; - va_start(ap, value); - vsnprintf(buf + offset, GF_DUMP_MAX_BUF_LEN - offset, value, ap); - va_end(ap); + va_start (ap, value); + vsnprintf (buf + offset, GF_DUMP_MAX_BUF_LEN - offset, value, ap); + va_end (ap); - offset = strlen(buf); - snprintf(buf + offset, GF_DUMP_MAX_BUF_LEN - offset, "\n"); - ret = write(gf_dump_fd, buf, strlen(buf)); + offset = strlen (buf); + snprintf (buf + offset, GF_DUMP_MAX_BUF_LEN - offset, "\n"); + ret = write (gf_dump_fd, buf, strlen (buf)); } @@ -123,20 +245,20 @@ gf_proc_dump_mem_info () #ifdef HAVE_MALLOC_STATS struct mallinfo info; - memset(&info, 0, sizeof(struct mallinfo)); - info = mallinfo(); - - gf_proc_dump_add_section("mallinfo"); - gf_proc_dump_write("mallinfo_arena", "%d", info.arena); - gf_proc_dump_write("mallinfo_ordblks", "%d", info.ordblks); - gf_proc_dump_write("mallinfo_smblks","%d", info.smblks); - gf_proc_dump_write("mallinfo_hblks","%d", info.hblks); - gf_proc_dump_write("mallinfo_hblkhd", "%d", info.hblkhd); - gf_proc_dump_write("mallinfo_usmblks","%d", info.usmblks); - gf_proc_dump_write("mallinfo_fsmblks","%d", info.fsmblks); - gf_proc_dump_write("mallinfo_uordblks","%d", info.uordblks); - gf_proc_dump_write("mallinfo_fordblks", "%d", info.fordblks); - gf_proc_dump_write("mallinfo_keepcost", "%d", info.keepcost); + memset (&info, 0, sizeof (struct mallinfo)); + info = mallinfo (); + + gf_proc_dump_add_section ("mallinfo"); + gf_proc_dump_write ("mallinfo_arena", "%d", info.arena); + gf_proc_dump_write ("mallinfo_ordblks", "%d", info.ordblks); + gf_proc_dump_write ("mallinfo_smblks","%d", info.smblks); + gf_proc_dump_write ("mallinfo_hblks","%d", info.hblks); + gf_proc_dump_write ("mallinfo_hblkhd", "%d", info.hblkhd); + gf_proc_dump_write ("mallinfo_usmblks","%d", info.usmblks); + gf_proc_dump_write ("mallinfo_fsmblks","%d", info.fsmblks); + gf_proc_dump_write ("mallinfo_uordblks","%d", info.uordblks); + gf_proc_dump_write ("mallinfo_fordblks", "%d", info.fordblks); + gf_proc_dump_write ("mallinfo_keepcost", "%d", info.keepcost); #endif } @@ -154,12 +276,18 @@ gf_proc_dump_xlator_info (xlator_t *this_xl) this_xl = this_xl->next; continue; } - if (this_xl->dumpops->priv) - this_xl->dumpops->priv(this_xl); - if (this_xl->dumpops->inode) - this_xl->dumpops->inode(this_xl); - if (this_xl->dumpops->fd) - this_xl->dumpops->fd(this_xl); + if (this_xl->dumpops->priv && + GF_PROC_DUMP_IS_XL_OPTION_ENABLED (priv)) + this_xl->dumpops->priv (this_xl); + + if (this_xl->dumpops->inode && + GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode)) + this_xl->dumpops->inode (this_xl); + + if (this_xl->dumpops->fd && + GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd)) + this_xl->dumpops->fd (this_xl); + this_xl = this_xl->next; } @@ -172,44 +300,54 @@ gf_proc_dump_info (int signum) { int ret = -1; glusterfs_ctx_t *ctx = NULL; - - gf_proc_dump_lock(); - ret = gf_proc_dump_open(); + + gf_proc_dump_lock (); + + ret = gf_proc_dump_open (); if (ret < 0) goto out; - gf_proc_dump_mem_info(); - ctx = get_global_ctx_ptr(); + + ret = gf_proc_dump_options_init (); + if (ret < 0) + goto out; + + if (GF_PROC_DUMP_IS_OPTION_ENABLED (mem)) + gf_proc_dump_mem_info (); + + ctx = get_global_ctx_ptr(); if (ctx) { - iobuf_stats_dump(ctx->iobuf_pool); - gf_proc_dump_pending_frames(ctx->pool); - gf_proc_dump_xlator_info(ctx->graph); + if (GF_PROC_DUMP_IS_OPTION_ENABLED (iobuf)) + iobuf_stats_dump (ctx->iobuf_pool); + if (GF_PROC_DUMP_IS_OPTION_ENABLED (callpool)) + gf_proc_dump_pending_frames (ctx->pool); + gf_proc_dump_xlator_info (ctx->graph); } - - gf_proc_dump_close(); + + gf_proc_dump_close (); out: - gf_proc_dump_unlock(); + gf_proc_dump_unlock (); return; } -void +void gf_proc_dump_fini (void) { - pthread_mutex_destroy(&gf_proc_dump_mutex); + pthread_mutex_destroy (&gf_proc_dump_mutex); } void gf_proc_dump_init () { - pthread_mutex_init(&gf_proc_dump_mutex, NULL); + pthread_mutex_init (&gf_proc_dump_mutex, NULL); - return; + return; } void gf_proc_dump_cleanup (void) { - pthread_mutex_destroy(&gf_proc_dump_mutex); + pthread_mutex_destroy (&gf_proc_dump_mutex); } diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h index 1261ebbef1b..21b15b245ed 100644 --- a/libglusterfs/src/statedump.h +++ b/libglusterfs/src/statedump.h @@ -19,7 +19,7 @@ #ifndef STATEDUMP_H -#define STATEDUMP_H +#define STATEDUMP_H #include #include "inode.h" @@ -29,28 +29,46 @@ #define GF_DUMP_LOGFILE_ROOT "/tmp/glusterdump" #define GF_DUMP_LOGFILE_ROOT_LEN 256 +#define GF_DUMP_OPTIONFILE "/tmp/glusterdump.input" + +typedef struct gf_dump_xl_options_ { + gf_boolean_t dump_priv; + gf_boolean_t dump_inode; + gf_boolean_t dump_fd; +} gf_dump_xl_options_t; + +typedef struct gf_dump_options_ { + gf_boolean_t dump_mem; + gf_boolean_t dump_iobuf; + gf_boolean_t dump_callpool; + gf_dump_xl_options_t xl_options; //options for all xlators +} gf_dump_options_t; + static inline void _gf_proc_dump_build_key (char *key, const char *prefix, char *fmt,...) { char buf[GF_DUMP_MAX_BUF_LEN]; va_list ap; - memset(buf, 0, sizeof(buf)); - va_start(ap, fmt); - vsnprintf(buf, GF_DUMP_MAX_BUF_LEN, fmt, ap); - va_end(ap); - snprintf(key, GF_DUMP_MAX_BUF_LEN, "%s.%s", prefix, buf); + memset (buf, 0, sizeof(buf)); + va_start (ap, fmt); + vsnprintf (buf, GF_DUMP_MAX_BUF_LEN, fmt, ap); + va_end (ap); + snprintf (key, GF_DUMP_MAX_BUF_LEN, "%s.%s", prefix, buf); } #define gf_proc_dump_build_key(key, key_prefix, fmt...) \ {\ - _gf_proc_dump_build_key(key, key_prefix, ##fmt);\ + _gf_proc_dump_build_key (key, key_prefix, ##fmt);\ } + +#define GF_PROC_DUMP_SET_OPTION(opt,val) opt = val + void gf_proc_dump_init(); -void +void gf_proc_dump_fini(void); void -- cgit