diff options
Diffstat (limited to 'libglusterfs/src/statedump.c')
| -rw-r--r-- | libglusterfs/src/statedump.c | 213 | 
1 files changed, 213 insertions, 0 deletions
diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c new file mode 100644 index 00000000000..6839c28f6e9 --- /dev/null +++ b/libglusterfs/src/statedump.c @@ -0,0 +1,213 @@ +/* +  Copyright (c) 2009 Z RESEARCH, Inc. <http://www.zresearch.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/>. +*/ + +#include <stdarg.h> +#include <malloc.h> +#include "glusterfs.h" +#include "logging.h" +#include "iobuf.h" +#include "statedump.h" +#include "stack.h" + + +static pthread_mutex_t  gf_proc_dump_mutex; +static int gf_dump_fd = -1; + +static void  +gf_proc_dump_lock (void) +{ +	pthread_mutex_lock(&gf_proc_dump_mutex); +} + +static void  +gf_proc_dump_unlock (void) +{ +	pthread_mutex_unlock(&gf_proc_dump_mutex); +}  + +static int +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()); + +        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" +                " errno: %d", path, errno); +                return -1; +        } + +	gf_dump_fd = dump_fd; +        return 0; +} + +static void +gf_proc_dump_close (void) +{ +        close(gf_dump_fd); +        gf_dump_fd = -1; +} + +void +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)); +} + +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, "="); +        offset += 1; +        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)); +} + + +/* Currently this dumps only mallinfo. More can be built on here */ +void +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); +#endif + +} + + +void +gf_proc_dump_xlator_info (xlator_t *this_xl) +{ + +        if (!this_xl) +                return; + +        while (this_xl) { +                if (!this_xl->dumpops) { +                        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); +                this_xl = this_xl->next; +        } + +        return; +} + + +void +gf_proc_dump_info (int signum) +{ +        int               ret = -1; +        glusterfs_ctx_t   *ctx = NULL; +     +        gf_proc_dump_lock(); +        ret = gf_proc_dump_open(); +        if (ret < 0)  +                goto out; +        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); +        } +         +        gf_proc_dump_close(); +out: +        gf_proc_dump_unlock(); + +        return; +} + +void  +gf_proc_dump_fini (void) +{ +	pthread_mutex_destroy(&gf_proc_dump_mutex); +} + + +void +gf_proc_dump_init () +{ +	pthread_mutex_init(&gf_proc_dump_mutex, NULL); + +	return; +} + +void +gf_proc_dump_cleanup (void) +{ +	pthread_mutex_destroy(&gf_proc_dump_mutex); +} +  | 
