diff options
| author | Krutika Dhananjay <kdhananj@redhat.com> | 2014-02-07 11:02:10 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2014-04-30 23:52:28 -0700 | 
| commit | 630d46d714a233919664c035f2c5c48c028777e8 (patch) | |
| tree | e7e79b240e23fde447989a4e1adc625b1858d17d /glusterfsd | |
| parent | f63fbca7540a4c9ce090e1ed5941ed8777ff6316 (diff) | |
logging: Introduce suppression of repetitive log messages
Change-Id: I8efa08cc9832ad509fba65a88bb0cddbaf056404
BUG: 1075611
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-on: http://review.gluster.org/7475
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'glusterfsd')
| -rw-r--r-- | glusterfsd/src/glusterfsd.c | 74 | ||||
| -rw-r--r-- | glusterfsd/src/glusterfsd.h | 4 | 
2 files changed, 78 insertions, 0 deletions
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c index 219088025a0..e971426da93 100644 --- a/glusterfsd/src/glusterfsd.c +++ b/glusterfsd/src/glusterfsd.c @@ -115,6 +115,10 @@ static struct argp_option gf_options[] = {          "[default: \"gluster-log\"]"},          {"log-format", ARGP_LOG_FORMAT, "LOG-FORMAT", 0, "Set log format, valid"           " options are: no-msg-id and with-msg-id, [default: \"with-msg-id\"]"}, +        {"log-buf-size", ARGP_LOG_BUF_SIZE, "LOG-BUF-SIZE", 0, "Set logging " +         "buffer size, [default: 5]"}, +        {"log-flush-timeout", ARGP_LOG_FLUSH_TIMEOUT, "LOG-FLUSH-TIMEOUT", 0, +         "Set log flush timeout, [default: 2 minutes]"},          {0, 0, 0, 0, "Advanced Options:"},          {"volfile-server-port", ARGP_VOLFILE_SERVER_PORT_KEY, "PORT", 0, @@ -1110,6 +1114,37 @@ parse_opts (int key, char *arg, struct argp_state *state)                  break; +        case ARGP_LOG_BUF_SIZE: +                if (gf_string2uint32 (arg, &cmd_args->log_buf_size)) { +                        argp_failure (state, -1, 0, +                                      "unknown log buf size option %s", arg); +                } else if ((cmd_args->log_buf_size < GF_LOG_LRU_BUFSIZE_MIN) || +                          (cmd_args->log_buf_size > GF_LOG_LRU_BUFSIZE_MAX)) { +                            argp_failure (state, -1, 0, +                                          "Invalid log buf size %s. " +                                          "Valid range: [" +                                          GF_LOG_LRU_BUFSIZE_MIN_STR"," +                                          GF_LOG_LRU_BUFSIZE_MAX_STR"]", arg); +                } + +                break; + +        case ARGP_LOG_FLUSH_TIMEOUT: +                if (gf_string2uint32 (arg, &cmd_args->log_flush_timeout)) { +                        argp_failure (state, -1, 0, +                                "unknown log flush timeout option %s", arg); +                } else if ((cmd_args->log_flush_timeout < +                            GF_LOG_FLUSH_TIMEOUT_MIN) || +                           (cmd_args->log_flush_timeout > +                            GF_LOG_FLUSH_TIMEOUT_MAX)) { +                            argp_failure (state, -1, 0, +                                          "Invalid log flush timeout %s. " +                                          "Valid range: [" +                                          GF_LOG_FLUSH_TIMEOUT_MIN_STR"," +                                          GF_LOG_FLUSH_TIMEOUT_MAX_STR"]", arg); +                } + +                break;  	}          return 0; @@ -1127,6 +1162,23 @@ cleanup_and_exit (int signum)          if (!ctx)                  return; +        /* To take or not to take the mutex here and in the other +         * signal handler - gf_print_trace() - is the big question here. +         * +         * Taking mutex in signal handler would mean that if the process +         * receives a fatal signal while another thread is holding +         * ctx->log.log_buf_lock to perhaps log a message in _gf_msg_internal(), +         * the offending thread hangs on the mutex lock forever without letting +         * the process exit. +         * +         * On the other hand. not taking the mutex in signal handler would cause +         * it to modify the lru_list of buffered log messages in a racy manner, +         * corrupt the list and potentially give rise to an unending +         * cascade of SIGSEGVs and other re-entrancy issues. +         */ + +        gf_log_disable_suppression_before_exit (ctx); +          gf_msg_callingfn ("", GF_LOG_WARNING, 0, glusterfsd_msg_32, signum);          if (ctx->cleanup_started) @@ -1313,6 +1365,11 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)          if (!ctx->dict_data_pool)                  goto out; +        ctx->logbuf_pool = mem_pool_new (log_buf_t, +                                         GF_MEMPOOL_COUNT_OF_LRU_BUF_T); +        if (!ctx->logbuf_pool) +                goto out; +          pthread_mutex_init (&(ctx->lock), NULL);          ctx->clienttable = gf_clienttable_alloc(); @@ -1325,6 +1382,8 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)          cmd_args->log_level = DEFAULT_LOG_LEVEL;          cmd_args->logger    = gf_logger_glusterlog;          cmd_args->log_format = gf_logformat_withmsgid; +        cmd_args->log_buf_size = GF_LOG_LRU_BUFSIZE_DEFAULT; +        cmd_args->log_flush_timeout = GF_LOG_FLUSH_TIMEOUT_DEFAULT;          cmd_args->mac_compat = GF_OPTION_DISABLE;  #ifdef GF_DARWIN_HOST_OS @@ -1359,6 +1418,7 @@ out:                  mem_pool_destroy (ctx->dict_pool);                  mem_pool_destroy (ctx->dict_data_pool);                  mem_pool_destroy (ctx->dict_pair_pool); +                mem_pool_destroy (ctx->logbuf_pool);          }          return ret; @@ -1397,12 +1457,24 @@ logging_init (glusterfs_ctx_t *ctx, const char *progpath)          gf_log_set_logformat (cmd_args->log_format); +        gf_log_set_log_buf_size (cmd_args->log_buf_size); + +        gf_log_set_log_flush_timeout (cmd_args->log_flush_timeout); +          if (gf_log_init (ctx, cmd_args->log_file, cmd_args->log_ident) == -1) {                  fprintf (stderr, "ERROR: failed to open logfile %s\n",                           cmd_args->log_file);                  return -1;          } +        /* At this point, all the logging related parameters are initialised +         * except for the log flush timer, which will be injected post fork(2) +         * in daemonize() . During this time, any log message that is logged +         * will be kept buffered. And if the list that holds these messages +         * overflows, then the same lru policy is used to drive out the least +         * recently used message and displace it with the message just logged. +         */ +          return 0;  } @@ -1792,6 +1864,8 @@ postfork:          if (ret)                  goto out; +        ret = gf_log_inject_timer_event (ctx); +          glusterfs_signals_setup (ctx);  out:          return ret; diff --git a/glusterfsd/src/glusterfsd.h b/glusterfsd/src/glusterfsd.h index 24487b4d461..a75369a24f5 100644 --- a/glusterfsd/src/glusterfsd.h +++ b/glusterfsd/src/glusterfsd.h @@ -39,6 +39,8 @@  #define GF_MEMPOOL_COUNT_OF_DATA_T        (GF_MEMPOOL_COUNT_OF_DICT_T * 4)  #define GF_MEMPOOL_COUNT_OF_DATA_PAIR_T   (GF_MEMPOOL_COUNT_OF_DICT_T * 4) +#define GF_MEMPOOL_COUNT_OF_LRU_BUF_T     256 +  enum argp_option_keys {          ARGP_VOLFILE_SERVER_KEY           = 's',          ARGP_VOLUME_FILE_KEY              = 'f', @@ -87,6 +89,8 @@ enum argp_option_keys {          ARGP_FUSE_NO_ROOT_SQUASH_KEY      = 167,          ARGP_LOGGER                       = 168,          ARGP_LOG_FORMAT                   = 169, +        ARGP_LOG_BUF_SIZE                 = 170, +        ARGP_LOG_FLUSH_TIMEOUT            = 171,  };  struct _gfd_vol_top_priv_t {  | 
