diff options
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 2 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 2 | ||||
| -rw-r--r-- | libglusterfs/src/Makefile.am | 4 | ||||
| -rw-r--r-- | libglusterfs/src/circ-buff.c | 180 | ||||
| -rw-r--r-- | libglusterfs/src/circ-buff.h | 72 | ||||
| -rw-r--r-- | libglusterfs/src/event-history.c | 90 | ||||
| -rw-r--r-- | libglusterfs/src/event-history.h | 52 | ||||
| -rw-r--r-- | libglusterfs/src/logging.c | 9 | ||||
| -rw-r--r-- | libglusterfs/src/logging.h | 3 | ||||
| -rw-r--r-- | libglusterfs/src/mem-types.h | 5 | ||||
| -rw-r--r-- | libglusterfs/src/statedump.c | 23 | ||||
| -rw-r--r-- | libglusterfs/src/statedump.h | 1 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.h | 6 | 
13 files changed, 437 insertions, 12 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index e483a1bd477..703a06e84a3 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1991,7 +1991,7 @@ gf_boolean_t  cli_cmd_validate_dumpoption (const char *arg, char **option)  {          char    *opwords[] = {"all", "nfs", "mem", "iobuf", "callpool", "priv", -                              "fd", "inode", NULL}; +                              "fd", "inode", "history", NULL};          char    *w = NULL;          w = str_getunamb (arg, opwords); diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 6ab1515e302..37b41c81e80 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1831,7 +1831,7 @@ struct cli_cmd volume_cmds[] = {            "Start healing of volume specified by <VOLNAME>"},          {"volume statedump <VOLNAME> [nfs] [all|mem|iobuf|callpool|priv|fd|" -         "inode]...", +         "inode|history]...",           cli_cmd_volume_statedump_cbk,           "perform statedump on bricks"}, diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index bbe7a2cd739..c7f3d9ba70b 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -23,7 +23,7 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.c \  	$(CONTRIBDIR)/uuid/parse.c $(CONTRIBDIR)/uuid/unparse.c \  	$(CONTRIBDIR)/uuid/uuid_time.c $(CONTRIBDIR)/uuid/compare.c \  	$(CONTRIBDIR)/uuid/isnull.c $(CONTRIBDIR)/uuid/unpack.c syncop.c \ -	graph-print.c trie.c run.c options.c fd-lk.c +	graph-print.c trie.c run.c options.c fd-lk.c circ-buff.c event-history.c  nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c @@ -37,7 +37,7 @@ noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h \  	rbthash.h iatt.h latency.h mem-types.h $(CONTRIBDIR)/uuid/uuidd.h \  	$(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h \  	$(CONTRIB_BUILDDIR)/uuid/uuid_types.h syncop.h graph-utils.h trie.h run.h \ -	options.h lkowner.h fd-lk.h +	options.h lkowner.h fd-lk.h circ-buff.h event-history.h  EXTRA_DIST = graph.l graph.y diff --git a/libglusterfs/src/circ-buff.c b/libglusterfs/src/circ-buff.c new file mode 100644 index 00000000000..36f8eeb7b9a --- /dev/null +++ b/libglusterfs/src/circ-buff.c @@ -0,0 +1,180 @@ +/* +  Copyright (c) 2012 Gluster, Inc. <http://www.gluster.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 "circ-buff.h" + +/* hold lock while calling this function */ +int +__cb_add_entry_buffer (buffer_t *buffer, void *item) +{ +        circular_buffer_t   *ptr  = NULL; +        int    ret   = -1; +        //DO we really need the assert here? +        GF_ASSERT (buffer->used_len <= buffer->size_buffer); + +        if (buffer->use_once == _gf_true && +            buffer->used_len == buffer->size_buffer) { +                gf_log  ("", GF_LOG_WARNING, "buffer %p is use once buffer", +                         buffer); +                return -1; +        } else { +                if (buffer->used_len == buffer->size_buffer) { +                        if (buffer->cb[buffer->w_index]) { +                                ptr = buffer->cb[buffer->w_index]; +                                if (ptr->data) { +                                        GF_FREE (ptr->data); +                                        ptr->data = NULL; +                                        GF_FREE (ptr); +                                } +                                buffer->cb[buffer->w_index] = NULL; +                                ptr = NULL; +                        } +                } + +                buffer->cb[buffer->w_index] = +                        GF_CALLOC (1, sizeof (circular_buffer_t), +                                   gf_common_mt_circular_buffer_t); +                if (!buffer->cb[buffer->w_index]) +                        return -1; + +                buffer->cb[buffer->w_index]->data = item; +                ret = gettimeofday (&buffer->cb[buffer->w_index]->tv, NULL); +                if (ret == -1) +                        gf_log_callingfn ("", GF_LOG_WARNING, "getting time of" +                                          "the day failed"); + +                buffer->w_index++; +                buffer->w_index %= buffer->size_buffer - 1; +                //used_buffer size cannot be greater than the total buffer size + +                if (buffer->used_len < buffer->size_buffer) +                        buffer->used_len++; +                return buffer->w_index; +        } +} + +int +cb_add_entry_buffer (buffer_t *buffer, void *item) +{ +        int write_index = -1; + +        pthread_mutex_lock (&buffer->lock); +        { +                write_index = __cb_add_entry_buffer (buffer, item); +        } +        pthread_mutex_unlock (&buffer->lock); + +        return write_index; +} + +void +cb_buffer_show (buffer_t *buffer) +{ +        pthread_mutex_lock (&buffer->lock); +        { +                gf_log ("", GF_LOG_DEBUG, "w_index: %d, size: %"GF_PRI_SIZET +                        " used_buffer: %d", buffer->w_index, +                        buffer->size_buffer, +                        buffer->used_len); +        } +        pthread_mutex_unlock (&buffer->lock); +} + +void +cb_buffer_dump (buffer_t *buffer, void *data, +                int (fn) (circular_buffer_t *buffer, void *data)) +{ +        int i = 0; +        circular_buffer_t *entry = NULL; +        int  entries = 0; + +        pthread_mutex_lock (&buffer->lock); +        { +                if (buffer->use_once == _gf_false) { +                        for (i = (buffer->w_index - 1) ; entries < +                                     buffer->used_len ; entries++) { +                                entry = buffer->cb[i]; +                                if (entry) +                                        fn (entry, data); +                                if (0 == i) +                                        i = buffer->used_len - 1; +                                else +                                        i = (i - 1) % (buffer->used_len - 1); +                        } +                } else { +                        for (i = 0; i < buffer->used_len ; i++) { +                                entry = buffer->cb[i]; +                                fn (entry, data); +                        } +                } +        } +        pthread_mutex_unlock (&buffer->lock); +} + +buffer_t * +cb_buffer_new (size_t buffer_size, gf_boolean_t use_once) +{ +        buffer_t    *buffer = NULL; + +        buffer = GF_CALLOC (1, sizeof (*buffer), gf_common_mt_buffer_t); +        if (!buffer) { +                gf_log ("", GF_LOG_ERROR, "could not allocate the " +                        "buffer"); +                goto out; +        } + +        buffer->cb = GF_CALLOC (buffer_size, +                                sizeof (circular_buffer_t *), +                                gf_common_mt_circular_buffer_t); +        if (!buffer->cb) { +                gf_log ("", GF_LOG_ERROR, "could not allocate the " +                        "memory for the circular buffer"); +                GF_FREE (buffer); +                buffer = NULL; +                goto out; +        } + +        buffer->w_index = 0; +        buffer->size_buffer = buffer_size; +        buffer->use_once = use_once; +        buffer->used_len = 0; +        pthread_mutex_init (&buffer->lock, NULL); + +out: +        return buffer; +} + +void +cb_buffer_destroy (buffer_t *buffer) +{ +        int i = 0; + +        if (buffer) { +                if (buffer->cb) { +                        for (i = 0; i < buffer->used_len ; i++) { +                                if (buffer->cb[i]) +                                        GF_FREE (buffer->cb[i]); +                        } +                        GF_FREE (buffer->cb); +                } +                pthread_mutex_destroy (&buffer->lock); +                GF_FREE (buffer); +        } +} + diff --git a/libglusterfs/src/circ-buff.h b/libglusterfs/src/circ-buff.h new file mode 100644 index 00000000000..d5172500e78 --- /dev/null +++ b/libglusterfs/src/circ-buff.h @@ -0,0 +1,72 @@ +/* +  Copyright (c) 2012 Gluster, Inc. <http://www.gluster.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/>. +*/ + +#ifndef _CB_H +#define _CB_H + +#include "common-utils.h" +#include "logging.h" +#include "mem-types.h" + +#define BUFFER_SIZE 10 +#define TOTAL_SIZE BUFFER_SIZE + 1 + + +struct _circular_buffer { +        struct timeval tv; +        void *data; +}; + +typedef struct _circular_buffer circular_buffer_t; + +struct _buffer { +        unsigned int w_index; +        size_t  size_buffer; +        gf_boolean_t use_once; +        /* This variable is assigned the proper value at the time of initing */ +        /* the buffer. It indicates, whether the buffer should be used once */ +        /*  it becomes full. */ + +        int  used_len; +        /* indicates the amount of circular buffer used. */ + +        circular_buffer_t **cb; + +        pthread_mutex_t   lock; +}; + +typedef struct _buffer buffer_t; + +int +cb_add_entry_buffer (buffer_t *buffer, void *item); + +void +cb_buffer_show (buffer_t *buffer); + +buffer_t * +cb_buffer_new (size_t buffer_size,gf_boolean_t use_buffer_once); + +void +cb_buffer_destroy (buffer_t *buffer); + +void +cb_buffer_dump (buffer_t *buffer, void *data, +                int (fn) (circular_buffer_t *buffer, void *data)); + +#endif /* _CB_H */ diff --git a/libglusterfs/src/event-history.c b/libglusterfs/src/event-history.c new file mode 100644 index 00000000000..812267b7c0b --- /dev/null +++ b/libglusterfs/src/event-history.c @@ -0,0 +1,90 @@ +/* +  Copyright (c) 2012 Gluster, Inc. <http://www.gluster.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 "event-history.h" + +eh_t * +eh_new (size_t buffer_size, gf_boolean_t use_buffer_once) +{ +        eh_t *history = NULL; +        buffer_t *buffer = NULL; + +        history = GF_CALLOC (1, sizeof (eh_t), gf_common_mt_eh_t); +        if (!history) { +                gf_log ("", GF_LOG_ERROR, "allocating history failed."); +                goto out; +        } + +        buffer = cb_buffer_new (buffer_size, use_buffer_once); +        if (!buffer) { +                gf_log ("", GF_LOG_ERROR, "allocating circular buffer failed"); +                GF_FREE (history); +                history = NULL; +        } + +        history->buffer = buffer; + +        pthread_mutex_init (&history->lock, NULL); +out: +        return history; +} + +void +eh_dump (eh_t *history, void *data, +         int (dump_fn) (circular_buffer_t *buffer, void *data)) +{ +        if (!history) { +                gf_log ("", GF_LOG_DEBUG, "history is NULL"); +                goto out; +        } + +        cb_buffer_dump (history->buffer, data, dump_fn); + +out: +        return; +} + +int +eh_save_history (eh_t *history, void *data) +{ +        int   ret = -1; + +        ret = cb_add_entry_buffer (history->buffer, data); + +        return ret; +} + +int +eh_destroy (eh_t *history) +{ +        if (!history) { +                gf_log ("", GF_LOG_INFO, "history for the xlator is " +                        "NULL"); +                return -1; +        } + +        cb_buffer_destroy (history->buffer); +        history->buffer = NULL; + +        pthread_mutex_destroy (&history->lock); + +        GF_FREE (history); + +        return 0; +} diff --git a/libglusterfs/src/event-history.h b/libglusterfs/src/event-history.h new file mode 100644 index 00000000000..c6e8fb4fa86 --- /dev/null +++ b/libglusterfs/src/event-history.h @@ -0,0 +1,52 @@ +/* +  Copyright (c) 2012 Gluster, Inc. <http://www.gluster.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/>. +*/ + +#ifndef _EH_H +#define _EH_H + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "mem-types.h" +#include "circ-buff.h" + +struct event_hist +{ +        buffer_t *buffer; +        pthread_mutex_t lock; +}; + +typedef struct event_hist eh_t; + +void +eh_dump (eh_t *event , void *data, +         int (fn) (circular_buffer_t *buffer, void *data)); + +eh_t * +eh_new (size_t buffer_size, gf_boolean_t use_buffer_once); + +int +eh_save_history (eh_t *history, void *string); + +int +eh_destroy (eh_t *history); + +#endif /* _EH_H */ diff --git a/libglusterfs/src/logging.c b/libglusterfs/src/logging.c index 55ef087a868..3698b4e7356 100644 --- a/libglusterfs/src/logging.c +++ b/libglusterfs/src/logging.c @@ -616,6 +616,15 @@ out:          return (0);  } +int +gf_log_eh (void *data) +{ +        int    ret = -1; + +        ret = eh_save_history (THIS->history, data); + +        return ret; +}  int  gf_cmd_log_init (const char *filename) diff --git a/libglusterfs/src/logging.h b/libglusterfs/src/logging.h index cb23cb54f06..a06a063aae7 100644 --- a/libglusterfs/src/logging.h +++ b/libglusterfs/src/logging.h @@ -108,7 +108,8 @@ extern char gf_log_xl_log_set;  void gf_log_logrotate (int signum); - +int +gf_log_eh (void *data);  void gf_log_globals_init (void);  int gf_log_init (const char *filename);  void gf_log_cleanup (void); diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h index 1ebf4d36008..27d47276906 100644 --- a/libglusterfs/src/mem-types.h +++ b/libglusterfs/src/mem-types.h @@ -108,6 +108,9 @@ enum gf_common_mem_types_ {          gf_common_mt_run_logbuf           = 83,          gf_common_mt_fd_lk_ctx_t          = 84,          gf_common_mt_fd_lk_ctx_node_t     = 85, -        gf_common_mt_end                  = 86, +        gf_common_mt_buffer_t             = 86, +        gf_common_mt_circular_buffer_t    = 87, +        gf_common_mt_eh_t                 = 88, +        gf_common_mt_end                  = 89  };  #endif diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c index 3811ef69234..dbbccdb44c3 100644 --- a/libglusterfs/src/statedump.c +++ b/libglusterfs/src/statedump.c @@ -410,6 +410,10 @@ gf_proc_dump_xlator_info (xlator_t *top)                      GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd))                          trav->dumpops->fd (trav); +                if (trav->dumpops->history && +                    GF_PROC_DUMP_IS_XL_OPTION_ENABLED (history)) +                        trav->dumpops->history (trav); +                  trav = trav->next;          } @@ -472,6 +476,8 @@ gf_proc_dump_enable_all_options ()          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); +        GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_history, +                                 _gf_true);          return 0;  } @@ -490,7 +496,8 @@ gf_proc_dump_disable_all_options ()          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); - +        GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_history, +                                 _gf_false);          return 0;  } @@ -521,6 +528,8 @@ gf_proc_dump_parse_set_option (char *key, char *value)                  opt_key = &dump_options.xl_options.dump_inodectx;          } else if (!strncasecmp (key, "fdctx", strlen ("fdctx"))) {                  opt_key = &dump_options.xl_options.dump_fdctx; +        } else if (!strncasecmp (key, "history", strlen ("history"))) { +                opt_key = &dump_options.xl_options.dump_history;          }          if (!opt_key) { @@ -529,8 +538,12 @@ gf_proc_dump_parse_set_option (char *key, char *value)                            "matched key : %s\n", key);                  ret = write (gf_dump_fd, buf, strlen (buf)); -                ret = -1; -                goto out; +                /* warning suppression */ +                if (ret >= 0) { +                        ret = -1; +                        goto out; +                } +          }          opt_value = (strncasecmp (value, "yes", 3) ? @@ -614,11 +627,11 @@ gf_proc_dump_info (int signum)          } else                  strncpy (brick_name, "glusterdump", sizeof (brick_name)); -        ret = gf_proc_dump_open (ctx->statedump_path, brick_name); +        ret = gf_proc_dump_options_init (brick_name);          if (ret < 0)                  goto out; -        ret = gf_proc_dump_options_init (brick_name); +        ret = gf_proc_dump_open (ctx->statedump_path, brick_name);          if (ret < 0)                  goto out; diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h index cdeb5b7fc0c..595802117d5 100644 --- a/libglusterfs/src/statedump.h +++ b/libglusterfs/src/statedump.h @@ -32,6 +32,7 @@ typedef struct gf_dump_xl_options_ {          gf_boolean_t    dump_fd;          gf_boolean_t    dump_inodectx;          gf_boolean_t    dump_fdctx; +        gf_boolean_t    dump_history;  } gf_dump_xl_options_t;  typedef struct gf_dump_options_ { diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index c8eff335329..7604f8c21e9 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -29,7 +29,7 @@  #include <stdint.h>  #include <inttypes.h> - +#include "event-history.h"  #include "logging.h"  #include "common-utils.h"  #include "dict.h" @@ -770,6 +770,8 @@ typedef int32_t (*dumpop_inodectx_to_dict_t) (xlator_t *this, inode_t *ino,  typedef int32_t (*dumpop_fdctx_to_dict_t) (xlator_t *this, fd_t *fd,                                             dict_t *dict); +typedef int32_t (*dumpop_eh_t) (xlator_t *this); +  struct xlator_dumpops {          dumpop_priv_t                   priv;          dumpop_inode_t                  inode; @@ -781,6 +783,7 @@ struct xlator_dumpops {          dumpop_fd_to_dict_t             fd_to_dict;          dumpop_inodectx_to_dict_t       inodectx_to_dict;          dumpop_fdctx_to_dict_t          fdctx_to_dict; +        dumpop_eh_t                     history;  };  typedef struct xlator_list { @@ -818,6 +821,7 @@ struct _xlator {          fop_latency_t latencies[GF_FOP_MAXVALUE];          /* Misc */ +        eh_t               *history; /* event history context */          glusterfs_ctx_t    *ctx;          glusterfs_graph_t  *graph; /* not set for fuse */          inode_table_t      *itable;  | 
