diff options
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/globals.c | 2 | ||||
| -rw-r--r-- | libglusterfs/src/logging.c | 173 | ||||
| -rw-r--r-- | libglusterfs/src/logging.h | 39 | ||||
| -rw-r--r-- | libglusterfs/src/mem-pool.c | 23 | ||||
| -rw-r--r-- | libglusterfs/src/mem-pool.h | 64 | 
5 files changed, 235 insertions, 66 deletions
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c index 3121a1f1415..9e9870e0bf0 100644 --- a/libglusterfs/src/globals.c +++ b/libglusterfs/src/globals.c @@ -349,6 +349,8 @@ glusterfs_globals_init ()          gf_op_list_init (); +        gf_log_globals_init (); +          ret = glusterfs_ctx_init ();          if (ret)                  goto out; diff --git a/libglusterfs/src/logging.c b/libglusterfs/src/logging.c index ed024840aa4..4c6bc2ed73e 100644 --- a/libglusterfs/src/logging.c +++ b/libglusterfs/src/logging.c @@ -48,8 +48,8 @@ static pthread_mutex_t  logfile_mutex;  static char            *filename = NULL;  static uint8_t          logrotate = 0;  static FILE            *logfile = NULL; -static gf_loglevel_t    loglevel = GF_LOG_MAX; -static int              gf_log_syslog = 0; +static gf_loglevel_t    loglevel = GF_LOG_INFO; +static int              gf_log_syslog = 1;  char                    gf_log_xl_log_set;  gf_loglevel_t           gf_log_loglevel; /* extern'd */ @@ -115,6 +115,18 @@ gf_log_fini (void)  } +void +gf_log_globals_init (void) +{ +        pthread_mutex_init (&logfile_mutex, NULL); + +#ifdef GF_LINUX_HOST_OS +        /* For the 'syslog' output. one can grep 'GlusterFS' in syslog +           for serious logs */ +        openlog ("GlusterFS", LOG_PID, LOG_DAEMON); +#endif +} +  int  gf_log_init (const char *file)  { @@ -123,8 +135,6 @@ gf_log_init (const char *file)                  return -1;          } -        pthread_mutex_init (&logfile_mutex, NULL); -          filename = gf_strdup (file);          if (!filename) {                  fprintf (stderr, "gf_log_init: strdup error\n"); @@ -140,12 +150,6 @@ gf_log_init (const char *file)                  return -1;          } -#ifdef GF_LINUX_HOST_OS -        /* For the 'syslog' output. one can grep 'GlusterFS' in syslog -           for serious logs */ -        openlog ("GlusterFS", LOG_PID, LOG_DAEMON); -#endif -          gf_log_logfile = logfile;          return 0; @@ -170,8 +174,6 @@ struct _log_msg {  }; - -  void  gf_log_lock (void)  { @@ -193,6 +195,123 @@ gf_log_cleanup (void)  }  int +_gf_log_nomem (const char *domain, const char *file, +               const char *function, int line, gf_loglevel_t level, +               size_t size) +{ +        const char     *basename        = NULL; +        struct tm      *tm              = NULL; +        xlator_t       *this            = NULL; +        struct timeval  tv              = {0,}; +        int             ret             = 0; +        gf_loglevel_t   xlator_loglevel = 0; +        char            msg[8092]; +        char            timestr[256]; +        char            callstr[4096]; + +        this = THIS; + +        xlator_loglevel = this->loglevel; +        if (xlator_loglevel == 0) +                xlator_loglevel = loglevel; + +        if (level > xlator_loglevel) +                goto out; + +        static char *level_strings[] = {"",  /* NONE */ +                                        "M", /* EMERGENCY */ +                                        "A", /* ALERT */ +                                        "C", /* CRITICAL */ +                                        "E", /* ERROR */ +                                        "W", /* WARNING */ +                                        "N", /* NOTICE */ +                                        "I", /* INFO/NORMAL */ +                                        "D", /* DEBUG */ +                                        "T", /* TRACE */ +                                        ""}; + +        if (!domain || !file || !function) { +                fprintf (stderr, +                         "logging: %s:%s():%d: invalid argument\n", +                         __FILE__, __PRETTY_FUNCTION__, __LINE__); +                return -1; +        } + +#if HAVE_BACKTRACE +        /* Print 'calling function' */ +        do { +                void *array[5]; +                char **callingfn = NULL; +                size_t bt_size = 0; + +                bt_size = backtrace (array, 5); +                if (bt_size) +                        callingfn = backtrace_symbols (&array[2], bt_size-2); +                if (!callingfn) +                        break; + +                if (bt_size == 5) +                        snprintf (callstr, 4096, "(-->%s (-->%s (-->%s)))", +                                  callingfn[2], callingfn[1], callingfn[0]); +                if (bt_size == 4) +                        snprintf (callstr, 4096, "(-->%s (-->%s))", +                                  callingfn[1], callingfn[0]); +                if (bt_size == 3) +                        snprintf (callstr, 4096, "(-->%s)", callingfn[0]); + +                free (callingfn); +        } while (0); +#endif /* HAVE_BACKTRACE */ + +        ret = gettimeofday (&tv, NULL); +        if (-1 == ret) +                goto out; + +        tm    = localtime (&tv.tv_sec); + +        pthread_mutex_lock (&logfile_mutex); +        { +                strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm); +                snprintf (timestr + strlen (timestr), 256 - strlen (timestr), +                          ".%"GF_PRI_SUSECONDS, tv.tv_usec); + +                basename = strrchr (file, '/'); +                if (basename) +                        basename++; +                else +                        basename = file; + +                ret = sprintf (msg, "[%s] %s [%s:%d:%s] %s %s: no memory " +                               "available for size (%"GF_PRI_SIZET")", +                               timestr, level_strings[level], +                               basename, line, function, callstr, +                               domain, size); +                if (-1 == ret) { +                        goto unlock; +                } + +                if (logfile) { +                        fprintf (logfile, "%s\n", msg); +                        fflush (logfile); +                } else { +                        fprintf (stderr, "%s\n", msg); +                } + +#ifdef GF_LINUX_HOST_OS +                /* We want only serious log in 'syslog', not our debug +                   and trace logs */ +                if (gf_log_syslog && level && (level <= GF_LOG_ERROR)) +                        syslog ((level-1), "%s\n", msg); +#endif +        } + +unlock: +        pthread_mutex_unlock (&logfile_mutex); +out: +        return ret; + } + +int  _gf_log_callingfn (const char *domain, const char *file, const char *function,                     int line, gf_loglevel_t level, const char *fmt, ...)  { @@ -210,9 +329,6 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,          gf_loglevel_t   xlator_loglevel = 0;          va_list         ap; -        if (!logfile) -                return -1; -          this = THIS;          xlator_loglevel = this->loglevel; @@ -308,13 +424,17 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,                  strcpy (msg, str1);                  strcpy (msg + len, str2); -                fprintf (logfile, "%s\n", msg); -                fflush (logfile); +                if (logfile) { +                        fprintf (logfile, "%s\n", msg); +                        fflush (logfile); +                } else { +                        fprintf (stderr, "%s\n", msg); +                }  #ifdef GF_LINUX_HOST_OS                  /* We want only serious log in 'syslog', not our debug                     and trace logs */ -                if (gf_log_syslog && level && (level <= GF_LOG_ERROR)) +                if (gf_log_syslog && level && (level <= GF_LOG_CRITICAL))                          syslog ((level-1), "%s\n", msg);  #endif          } @@ -355,9 +475,6 @@ _gf_log (const char *domain, const char *file, const char *function, int line,          xlator_t    *this = NULL;          gf_loglevel_t xlator_loglevel = 0; -        if (!logfile) -                return -1; -          this = THIS;          xlator_loglevel = this->loglevel; @@ -398,7 +515,9 @@ _gf_log (const char *domain, const char *file, const char *function, int line,                          goto log;                  } -                fclose (logfile); +                if (logfile) +                        fclose (logfile); +                  gf_log_logfile = logfile = new_logfile;          } @@ -444,13 +563,17 @@ log:                  strcpy (msg, str1);                  strcpy (msg + len, str2); -                fprintf (logfile, "%s\n", msg); -                fflush (logfile); +                if (logfile) { +                        fprintf (logfile, "%s\n", msg); +                        fflush (logfile); +                } else { +                        fprintf (stderr, "%s\n", msg); +                }  #ifdef GF_LINUX_HOST_OS                  /* We want only serious log in 'syslog', not our debug                     and trace logs */ -                if (gf_log_syslog && level && (level <= GF_LOG_ERROR)) +                if (gf_log_syslog && level && (level <= GF_LOG_CRITICAL))                          syslog ((level-1), "%s\n", msg);  #endif          } diff --git a/libglusterfs/src/logging.h b/libglusterfs/src/logging.h index aa6e00edb70..0664b2efae0 100644 --- a/libglusterfs/src/logging.h +++ b/libglusterfs/src/logging.h @@ -69,8 +69,6 @@ typedef enum {          GF_LOG_TRACE,      /* full trace of operation */  } gf_loglevel_t; -#define GF_LOG_MAX GF_LOG_DEBUG -  extern gf_loglevel_t gf_log_loglevel;  extern char gf_log_xl_log_set; @@ -94,27 +92,38 @@ extern char gf_log_xl_log_set;                                     levl, ##fmt);                        \          } while (0) + +/* No malloc or calloc should be called in this function */ +#define gf_log_nomem(dom, levl, size) do {                              \ +                if ((levl > gf_log_loglevel) && !gf_log_xl_log_set)     \ +                        break;                                          \ +                _gf_log_nomem (dom, __FILE__, __FUNCTION__, __LINE__,   \ +                               levl, size);                             \ +        } while (0) + +  /* Log once in GF_UNIVERSAL_ANSWER times */  #define GF_LOG_OCCASIONALLY(var, args...) if (!(var++%GF_UNIVERSAL_ANSWER)) { \                  gf_log (args);                                          \          } -void -gf_log_logrotate (int signum); +void gf_log_logrotate (int signum); +void gf_log_globals_init (void);  int gf_log_init (const char *filename);  void gf_log_cleanup (void); -int -_gf_log (const char *domain, const char *file, const char *function, -         int32_t line, gf_loglevel_t level, const char *fmt, ...); -int -_gf_log_callingfn (const char *domain, const char *file, const char *function, -                   int32_t line, gf_loglevel_t level, const char *fmt, ...); +int _gf_log (const char *domain, const char *file, const char *function, +             int32_t line, gf_loglevel_t level, const char *fmt, ...); +int _gf_log_callingfn (const char *domain, const char *file, const char *function, +                       int32_t line, gf_loglevel_t level, const char *fmt, ...); + +int _gf_log_nomem (const char *domain, const char *file, +                   const char *function, int line, gf_loglevel_t level, +                   size_t size); -int -gf_log_from_client (const char *msg, char *identifier); +int gf_log_from_client (const char *msg, char *identifier);  void gf_log_lock (void);  void gf_log_unlock (void); @@ -135,9 +144,7 @@ void gf_log_set_xl_loglevel (void *xl, gf_loglevel_t level);  #define GF_ERROR(xl, format, args...)                           \          gf_log ((xl)->name, GF_LOG_ERROR, format, ##args) -int -gf_cmd_log (const char *domain, const char *fmt, ...); +int gf_cmd_log (const char *domain, const char *fmt, ...); -int -gf_cmd_log_init (const char *filename); +int gf_cmd_log_init (const char *filename);  #endif /* __LOGGING_H__ */ diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c index 9acebad4153..0d555020bbe 100644 --- a/libglusterfs/src/mem-pool.c +++ b/libglusterfs/src/mem-pool.c @@ -141,9 +141,10 @@ __gf_calloc (size_t nmemb, size_t size, uint32_t type)          ptr = calloc (1, tot_size); -        if (!ptr) +        if (!ptr) { +                gf_log_nomem ("", GF_LOG_ALERT, tot_size);                  return NULL; - +        }          gf_mem_set_acct_info (xl, &ptr, req_size, type);          return (void *)ptr; @@ -164,9 +165,10 @@ __gf_malloc (size_t size, uint32_t type)          tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;          ptr = malloc (tot_size); -        if (!ptr) +        if (!ptr) { +                gf_log_nomem ("", GF_LOG_ALERT, tot_size);                  return NULL; - +        }          gf_mem_set_acct_info (xl, &ptr, size, type);          return (void *)ptr; @@ -181,7 +183,7 @@ __gf_realloc (void *ptr, size_t size)          uint32_t        type = 0;          if (!gf_mem_acct_enable) -                return realloc (ptr, size); +                return REALLOC (ptr, size);          tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE; @@ -196,8 +198,10 @@ __gf_realloc (void *ptr, size_t size)          type = *(uint32_t *)orig_ptr;          ptr = realloc (orig_ptr, tot_size); -        if (!ptr) +        if (!ptr) { +                gf_log_nomem ("", GF_LOG_ALERT, tot_size);                  return NULL; +        }          gf_mem_set_acct_info (xl, (char **)&ptr, size, type); @@ -221,12 +225,7 @@ gf_vasprintf (char **string_ptr, const char *format, va_list arg)          size++;          str = GF_MALLOC (size, gf_common_mt_asprintf);          if (str == NULL) { -                /* -                 * Strictly speaking, GNU asprintf doesn't do this, -                 * but the caller isn't checking the return value. -                 */ -                gf_log ("libglusterfs", GF_LOG_CRITICAL, -                        "failed to allocate memory"); +                /* log is done in GF_MALLOC itself */                  return -1;          }          rv = vsnprintf (str, size, format, arg_save); diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h index 0cda62fb85b..85ceeb87e06 100644 --- a/libglusterfs/src/mem-pool.h +++ b/libglusterfs/src/mem-pool.h @@ -22,6 +22,7 @@  #include "list.h"  #include "locking.h" +#include "logging.h"  #include "mem-types.h"  #include <stdlib.h>  #include <inttypes.h> @@ -29,15 +30,6 @@  #include <stdarg.h> -#define MALLOC(size) malloc(size) -#define CALLOC(cnt,size) calloc(cnt,size) - -#define FREE(ptr)                               \ -        if (ptr != NULL) {                      \ -                free ((void *)ptr);             \ -                ptr = (void *)0xeeeeeeee;       \ -        } -  struct mem_acct {          uint32_t            num_types;          struct mem_acct_rec     *rec; @@ -67,16 +59,62 @@ gf_vasprintf (char **string_ptr, const char *format, va_list arg);  int  gf_asprintf (char **string_ptr, const char *format, ...); +void +__gf_free (void *ptr); + + +static inline +void* __gf_default_malloc (size_t size) +{ +        void *ptr = NULL; + +        ptr = malloc (size); +        if (!ptr) +                gf_log_nomem ("", GF_LOG_ALERT, size); + +        return ptr; +} + +static inline +void* __gf_default_calloc (int cnt, size_t size) +{ +        void *ptr = NULL; + +        ptr = calloc (cnt, size); +        if (!ptr) +                gf_log_nomem ("", GF_LOG_ALERT, (cnt * size)); + +        return ptr; +} + +static inline +void* __gf_default_realloc (void *oldptr, size_t size) +{ +        void *ptr = NULL; + +        ptr = realloc (oldptr, size); +        if (!ptr) +                gf_log_nomem ("", GF_LOG_ALERT, size); + +        return ptr; +} + +#define MALLOC(size)       __gf_default_malloc(size) +#define CALLOC(cnt,size)   __gf_default_calloc(cnt,size) +#define REALLOC(ptr,size)  __gf_default_realloc(ptr,size) + +#define FREE(ptr)                               \ +        if (ptr != NULL) {                      \ +                free ((void *)ptr);             \ +                ptr = (void *)0xeeeeeeee;       \ +        } +  #define GF_CALLOC(nmemb, size, type) __gf_calloc (nmemb, size, type)  #define GF_MALLOC(size, type)  __gf_malloc (size, type)  #define GF_REALLOC(ptr, size)  __gf_realloc (ptr, size) -void -__gf_free (void *ptr); - -  #define GF_FREE(free_ptr) __gf_free (free_ptr);  static inline  | 
