nfs-ganesha 1.4

log.h

Go to the documentation of this file.
00001 #ifndef _LOGS_H
00002 #define _LOGS_H
00003 
00004 #include <stdio.h>
00005 #include <stdarg.h>
00006 #include <sys/types.h>
00007 #include <sys/param.h>
00008 #include <syslog.h>
00009 #include <inttypes.h>
00010 
00011 #ifndef LIBLOG_NO_THREAD
00012 #include <errno.h>
00013 #include <pthread.h>
00014 #endif
00015 
00016 #ifdef _SNMP_ADM_ACTIVE
00017 #include "snmp_adm.h"
00018 #endif
00019 
00020 /* these macros gain a few percent of speed on gcc, especially with so many log entries */
00021 #if (__GNUC__ >= 3)
00022 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 as its first argument */
00023 #ifndef likely
00024 #define likely(x)   __builtin_expect(!!(x), 1)
00025 #endif
00026 #ifndef unlikely
00027 #define unlikely(x) __builtin_expect(!!(x), 0)
00028 #endif
00029 #else
00030 #ifndef likely
00031 #define likely(x) (x)
00032 #endif
00033 #ifndef unlikely
00034 #define unlikely(x) (x)
00035 #endif
00036 #endif
00037 
00038 /*
00039  * definition des codes d'error
00040  *
00041  *
00042  * Copyright CEA/DAM/DIF  (2008)
00043  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00044  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00045  *
00046  *
00047  * This program is free software; you can redistribute it and/or
00048  * modify it under the terms of the GNU Lesser General Public
00049  * License as published by the Free Software Foundation; either
00050  * version 3 of the License, or (at your option) any later version.
00051  * 
00052  * This program is distributed in the hope that it will be useful,
00053  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00054  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00055  * Lesser General Public License for more details.
00056  * 
00057  * You should have received a copy of the GNU Lesser General Public
00058  * License along with this library; if not, write to the Free Software
00059  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00060  * 
00061  * ---------------------------------------
00062  *
00063  *
00064  */
00065 
00066 #ifndef MAXPATHLEN
00067 #define MAXPATHLEN 1024
00068 #endif
00069 
00070 #define STR_LEN 256
00071 
00072 /*
00073  * 
00074  * Constantes qui definissent les niveaux de gravite des affichages de LOG 
00075  *
00076  */
00077 
00078 typedef enum log_levels
00079 {
00080   NIV_NULL,
00081   NIV_FATAL,
00082   NIV_MAJ,
00083   NIV_CRIT,
00084   NIV_WARN,
00085   NIV_EVENT,
00086   NIV_INFO,
00087   NIV_DEBUG,
00088   NIV_MID_DEBUG,        // new debug log level
00089   NIV_FULL_DEBUG,
00090   NB_LOG_LEVEL
00091 } log_levels_t;
00092 
00093 /*
00094  * Log components used throughout the code.
00095  *
00096  * Note: changing the order of these may confuse SNMP users since SNMP OIDs are numeric.
00097  */
00098 typedef enum log_components
00099 {
00100   COMPONENT_ALL = 0,               /* Used for changing logging for all components */
00101   COMPONENT_LOG,                   /* Keep this first, some code depends on it being the first component */
00102   COMPONENT_LOG_EMERG,             /* Component for logging emergency log messages - avoid infinite recursion */
00103   COMPONENT_MEMALLOC,
00104   COMPONENT_MEMLEAKS,
00105   COMPONENT_FSAL,
00106   COMPONENT_NFSPROTO,
00107   COMPONENT_NFS_V4,
00108   COMPONENT_NFS_V4_PSEUDO,
00109   COMPONENT_FILEHANDLE,
00110   COMPONENT_NFS_SHELL,
00111   COMPONENT_DISPATCH,
00112   COMPONENT_CACHE_CONTENT,
00113   COMPONENT_CACHE_INODE,
00114   COMPONENT_CACHE_INODE_GC,
00115   COMPONENT_CACHE_INODE_LRU,
00116   COMPONENT_HASHTABLE,
00117   COMPONENT_HASHTABLE_CACHE,
00118   COMPONENT_LRU,
00119   COMPONENT_DUPREQ,
00120   COMPONENT_RPCSEC_GSS,
00121   COMPONENT_INIT,
00122   COMPONENT_MAIN,
00123   COMPONENT_IDMAPPER,
00124   COMPONENT_NFS_READDIR,
00125   COMPONENT_NFS_V4_LOCK,
00126   COMPONENT_NFS_V4_XATTR,
00127   COMPONENT_NFS_V4_REFERRAL,
00128   COMPONENT_MEMCORRUPT,
00129   COMPONENT_CONFIG,
00130   COMPONENT_CLIENTID,
00131   COMPONENT_STDOUT,
00132   COMPONENT_SESSIONS,
00133   COMPONENT_PNFS,
00134   COMPONENT_RPC_CACHE,
00135   COMPONENT_RW_LOCK,
00136   COMPONENT_NLM,
00137   COMPONENT_RPC,
00138   COMPONENT_NFS_CB,
00139   COMPONENT_THREAD,
00140   COMPONENT_NFS_V4_ACL,
00141   COMPONENT_STATE,
00142   COMPONENT_9P,
00143   COMPONENT_9P_DISPATCH,
00144   COMPONENT_FSAL_UP,
00145   COMPONENT_DBUS,
00146   LOG_MESSAGE_VERBOSITY,
00147   COMPONENT_COUNT
00148 } log_components_t;
00149 
00150 typedef struct loglev
00151 {
00152   log_levels_t value;
00153   char *str;
00154   char *short_str;
00155   int syslog_level;
00156 } log_level_t;
00157 
00158 extern log_level_t tabLogLevel[NB_LOG_LEVEL];
00159 
00160 #define NIV_MAJOR NIV_MAJ
00161 
00162 /*
00163  *
00164  * La structure de definition des messages d'errors
00165  *
00166  */
00167 
00168 #define LOG_MAX_STRLEN 2048
00169 #define LOG_LABEL_LEN 50
00170 #define LOG_MSG_LEN   255
00171 
00172 typedef struct
00173 {
00174   int numero;
00175   char label[LOG_LABEL_LEN];
00176   char msg[LOG_MSG_LEN];
00177 } family_error_t;
00178 
00179 /* Le type family d'erreurs */
00180 typedef struct
00181 {
00182   int num_family;
00183   char name_family[STR_LEN];
00184   family_error_t *tab_err;
00185 } family_t;
00186 
00187 typedef family_error_t status_t;
00188 typedef family_error_t errctx_t;
00189 
00190 typedef struct
00191 {
00192   int err_family;
00193   int ctx_family;
00194   errctx_t contexte;
00195   status_t status;
00196 } log_error_t;
00197 
00198 #define ERR_NULL -1
00199 
00200 /* les code d'error */
00201 #define ERR_SYS 0
00202 #define SUCCES                    0
00203 #define ERR_FAILURE               1
00204 #define EVNT                      2
00205 #define ERR_EVNT                  2
00206 #define ERR_PTHREAD_KEY_CREATE    3
00207 #define ERR_MALLOC                4
00208 #define ERR_SIGACTION             5
00209 #define ERR_PTHREAD_ONCE          6
00210 #define ERR_FICHIER_LOG           7
00211 #define ERR_GETHOSTBYNAME         8
00212 #define ERR_MMAP                  9
00213 #define ERR_SOCKET               10
00214 #define ERR_BIND                 11
00215 #define ERR_CONNECT              12
00216 #define ERR_LISTEN               13
00217 #define ERR_ACCEPT               14
00218 #define ERR_RRESVPORT            15
00219 #define ERR_GETHOSTNAME          16
00220 #define ERR_GETSOCKNAME          17
00221 #define ERR_IOCTL                18
00222 #define ERR_UTIME                19
00223 #define ERR_XDR                  20
00224 #define ERR_CHMOD                21
00225 #define ERR_SEND                 22
00226 #define ERR_GETHOSTBYADDR        23
00227 #define ERR_PREAD                24
00228 #define ERR_PWRITE               25
00229 #define ERR_STAT                 26
00230 #define ERR_GETPEERNAME          27
00231 #define ERR_FORK                 28
00232 #define ERR_GETSERVBYNAME        29
00233 #define ERR_MUNMAP               30
00234 #define ERR_STATVFS              31
00235 #define ERR_OPENDIR              32
00236 #define ERR_READDIR              33
00237 #define ERR_CLOSEDIR             34
00238 #define ERR_LSTAT                35
00239 #define ERR_GETWD                36
00240 #define ERR_CHDIR                37
00241 #define ERR_CHOWN                38
00242 #define ERR_MKDIR                39
00243 #define ERR_OPEN                 40
00244 #define ERR_READ                 41
00245 #define ERR_WRITE                42
00246 #define ERR_UTIMES               43
00247 #define ERR_READLINK             44
00248 #define ERR_SYMLINK              45
00249 #define ERR_SYSTEM               46
00250 #define ERR_POPEN                47
00251 #define ERR_LSEEK                48
00252 #define ERR_PTHREAD_CREATE       49
00253 #define ERR_RECV                 50
00254 #define ERR_FOPEN                51
00255 #define ERR_GETCWD               52
00256 #define ERR_SETUID               53
00257 #define ERR_RENAME               54
00258 #define ERR_UNLINK               55
00259 #define ERR_SELECT               56
00260 #define ERR_WAIT                 57
00261 #define ERR_SETSID               58
00262 #define ERR_SETGID               59
00263 #define ERR_GETGROUPS            60
00264 #define ERR_SETGROUPS            61
00265 #define ERR_UMASK                62
00266 #define ERR_CREAT                63
00267 #define ERR_SETSOCKOPT           64
00268 #define ERR_DIRECTIO             65
00269 #define ERR_GETRLIMIT            66
00270 #define ERR_SETRLIMIT            67
00271 #define ERR_TRUNCATE             68
00272 #define ERR_PTHREAD_MUTEX_INIT   69
00273 #define ERR_PTHREAD_COND_INIT    70
00274 #define ERR_FCNTL                71
00275 
00276 #define ERR_POSIX 1
00277 
00278 static status_t __attribute__ ((__unused__)) tab_systeme_status[] =
00279 {
00280   {
00281   0, "NO_ERROR", "No errors"},
00282   {
00283   EPERM, "EPERM", "Reserved to root"},
00284   {
00285   ENOENT, "ENOENT", "No such file or directory"},
00286   {
00287   ESRCH, "ESRCH", "No such process"},
00288   {
00289   EINTR, "EINTR", "interrupted system call"},
00290   {
00291   EIO, "EIO", "I/O error"},
00292   {
00293   ENXIO, "ENXIO", "No such device or address"},
00294   {
00295   E2BIG, "E2BIG", "Arg list too long"},
00296   {
00297   ENOEXEC, "ENOEXEC", "Exec format error"},
00298   {
00299   EBADF, "EBADF", "Bad file number"},
00300   {
00301   ECHILD, "ECHILD", "No children"},
00302   {
00303   EAGAIN, "EAGAIN", "Resource temporarily unavailable"},
00304   {
00305   ENOMEM, "ENOMEM", "Not enough core"},
00306   {
00307   EACCES, "ENOMEM", "Permission denied"},
00308   {
00309   EFAULT, "EFAULT", "Bad address"},
00310   {
00311   ENOTBLK, "ENOTBLK", "Block device required"},
00312   {
00313   EBUSY, "EBUSY", "Mount device busy"},
00314   {
00315   EEXIST, "EEXIST", "File exists"},
00316   {
00317   EXDEV, "EXDEV", "Cross-device link"},
00318   {
00319   ENODEV, "ENODEV", "No such device"},
00320   {
00321   ENOTDIR, "ENOTDIR", "Not a directory"},
00322   {
00323   EISDIR, "EISDIR", "Is a directory"},
00324   {
00325   EINVAL, "EINVAL", "Invalid argument"},
00326   {
00327   ENFILE, "ENFILE", "File table overflow"},
00328   {
00329   EMFILE, "EMFILE", "Too many open files"},
00330   {
00331   ENOTTY, "ENOTTY", "Inappropriate ioctl for device"},
00332   {
00333   ETXTBSY, "ETXTBSY", "Text file busy"},
00334   {
00335   EFBIG, "EFBIG", "File too large"},
00336   {
00337   ENOSPC, "ENOSPC", "No space left on device"},
00338   {
00339   ESPIPE, "ESPIPE", "Illegal seek"},
00340   {
00341   EROFS, "EROFS", "Read only file system"},
00342   {
00343   EMLINK, "EMLINK", "Too many links"},
00344   {
00345   EPIPE, "EPIPE", "Broken pipe"},
00346   {
00347   EDOM, "EDOM", "Math arg out of domain of func"},
00348   {
00349   ERANGE, "ERANGE", "Math result not representable"},
00350   {
00351   ENOMSG, "ENOMSG", "No message of desired type"},
00352   {
00353   EIDRM, "EIDRM", "Identifier removed"},
00354   {
00355   ERR_NULL, "ERR_NULL", ""}
00356 };
00357 
00358 /* other codes families */
00359 #define ERR_LRU           10
00360 #define ERR_HASHTABLE     11
00361 #define ERR_FSAL          13
00362 #define ERR_GHOSTFS       15
00363 #define ERR_CACHE_INODE   16
00364 #define ERR_CACHE_CONTENT 17
00365 
00366 /* previously at log_macros.h */
00367 typedef void (*cleanup_function)(void);
00368 typedef struct cleanup_list_element
00369 {
00370   struct cleanup_list_element *next;
00371   cleanup_function             clean;
00372 } cleanup_list_element;
00373 
00374 /* les prototypes des fonctions de la lib */
00375 
00376 void SetNamePgm(char *nom);
00377 void SetNameHost(char *nom);
00378 void SetDefaultLogging(char *name);
00379 void SetNameFunction(char *nom); /* thread safe */
00380 void GetNameFunction(char *name, int len);
00381 
00382 /* AddFamilyError : not thread safe */
00383 int AddFamilyError(int num_family, char *nom_family, family_error_t * tab_err);
00384 
00385 char *ReturnNameFamilyError(int num_family);
00386 
00387 void InitLogging();        /* not thread safe */
00388 
00389 void SetLevelDebug(int level_to_set);    /* not thread safe */
00390 
00391 int ReturnLevelAscii(const char *LevelEnAscii);
00392 char *ReturnLevelInt(int level);
00393 
00394 int MakeLogError(char *buffer, int num_family, int num_error, int status,
00395                   int ma_ligne);
00396 
00397 int log_vsnprintf(char *out, size_t n, char *format, va_list arguments);
00398 int log_snprintf(char *out, size_t n, char *format, ...);
00399 int log_fprintf(FILE * file, char *format, ...);
00400 
00401 #ifdef _SNMP_ADM_ACTIVE
00402 int getComponentLogLevel(snmp_adm_type_union * param, void *opt);
00403 int setComponentLogLevel(const snmp_adm_type_union * param, void *opt);
00404 #endif
00405 
00406 /* previously at log_macros.h */
00407 void RegisterCleanup(cleanup_list_element *clean);
00408 void Cleanup(void);
00409 void Fatal(void);
00410 int SetComponentLogFile(log_components_t component, char *name);
00411 void SetComponentLogBuffer(log_components_t component, char *buffer);
00412 void SetComponentLogLevel(log_components_t component, int level_to_set);
00413 
00414 #define SetLogLevel(level_to_set) \
00415   SetComponentLogLevel(COMPONENT_ALL, level_to_set)
00416 
00417 int DisplayLogComponentLevel(log_components_t component,
00418                              char * function,
00419                              log_levels_t level,
00420                              char *format, ...)
00421 __attribute__((format(printf, 4, 5))); /* 4=format 5=params */ ;
00422 int DisplayErrorComponentLogLine(log_components_t component,
00423                                  char * function,
00424                                  int num_family,
00425                                  int num_error,
00426                                  int status,
00427                                  int ma_ligne);
00428 
00429 enum log_type
00430 {
00431   SYSLOG = 0,
00432   FILELOG,
00433   STDERRLOG,
00434   STDOUTLOG,
00435   TESTLOG,
00436   BUFFLOG
00437 };
00438 
00439 typedef struct log_component_info
00440 {
00441   int   comp_value;
00442   char *comp_name;
00443   char *comp_str;
00444   int   comp_log_level;
00445 
00446   int   comp_log_type;
00447   char  comp_log_file[MAXPATHLEN];
00448   char *comp_buffer;
00449 } log_component_info;
00450 
00451 #define ReturnLevelComponent(component) LogComponents[component].comp_log_level
00452 
00453 log_component_info __attribute__ ((__unused__)) LogComponents[COMPONENT_COUNT];
00454 
00455 #define LogAlways(component, format, args...) \
00456   do { \
00457     if (likely(LogComponents[component].comp_log_type != TESTLOG || \
00458                LogComponents[component].comp_log_level <= NIV_FULL_DEBUG)) \
00459       DisplayLogComponentLevel(component, (char *)__FUNCTION__,  NIV_NULL, \
00460                                "%s: " format, \
00461                                LogComponents[component].comp_str, ## args ); \
00462   } while (0)
00463 
00464 #define LogTest(format, args...) \
00465   do { \
00466     DisplayLogComponentLevel(COMPONENT_ALL,  (char *)__FUNCTION__, NIV_NULL, \
00467                              format, ## args ); \
00468   } while (0)
00469 
00470 #define LogFatal(component, format, args...) \
00471   do { \
00472     if (likely(LogComponents[component].comp_log_level >= NIV_FATAL)) \
00473       DisplayLogComponentLevel(component, (char *)__FUNCTION__, NIV_FATAL, \
00474                                "%s: FATAL ERROR: " format, \
00475                                LogComponents[component].comp_str, ## args ); \
00476   } while (0)
00477 
00478 #define LogMajor(component, format, args...) \
00479   do { \
00480     if (likely(LogComponents[component].comp_log_level >= NIV_MAJOR)) \
00481       DisplayLogComponentLevel(component,  (char *)__FUNCTION__, NIV_MAJ, \
00482                                "%s: MAJOR ERROR: " format, \
00483                                LogComponents[component].comp_str, ## args ); \
00484   } while (0)
00485 
00486 #define LogCrit(component, format, args...) \
00487   do { \
00488     if (likely(LogComponents[component].comp_log_level >= NIV_CRIT)) \
00489       DisplayLogComponentLevel(component,  (char *)__FUNCTION__, NIV_CRIT, \
00490                                "%s: CRITICAL ERROR: " format, \
00491                                LogComponents[component].comp_str, ## args ); \
00492    } while (0)
00493 
00494 #define LogWarn(component, format, args...) \
00495   do { \
00496     if (likely(LogComponents[component].comp_log_level >= NIV_WARN)) \
00497       DisplayLogComponentLevel(component,  (char *)__FUNCTION__, NIV_WARN, \
00498                                "%s: WARN: " format, \
00499                                LogComponents[component].comp_str, ## args ); \
00500   } while (0)
00501 
00502 #define LogEvent(component, format, args...) \
00503   do { \
00504     if (likely(LogComponents[component].comp_log_level >= NIV_EVENT)) \
00505       DisplayLogComponentLevel(component, (char *)__FUNCTION__, NIV_EVENT, \
00506                                "%s: EVENT: " format, \
00507                                LogComponents[component].comp_str, ## args ); \
00508   } while (0)
00509 
00510 #define LogInfo(component, format, args...) \
00511   do { \
00512     if (unlikely(LogComponents[component].comp_log_level >= NIV_INFO)) \
00513       DisplayLogComponentLevel(component, (char *) __FUNCTION__, NIV_INFO, \
00514                                "%s: INFO: " format, \
00515                                LogComponents[component].comp_str, ## args ); \
00516   } while (0)
00517 
00518 #define LogDebug(component, format, args...) \
00519   do { \
00520     if (unlikely(LogComponents[component].comp_log_level >= NIV_DEBUG)) \
00521       DisplayLogComponentLevel(component,  (char *)__FUNCTION__, NIV_DEBUG, \
00522                                "%s: DEBUG: " format, \
00523                                LogComponents[component].comp_str, ## args ); \
00524   } while (0)
00525 
00526 #define LogMidDebug(component, format, args...) \
00527   do { \
00528     if (unlikely(LogComponents[component].comp_log_level >= NIV_MID_DEBUG)) \
00529       DisplayLogComponentLevel(component,  (char *)__FUNCTION__, NIV_MID_DEBUG, \
00530                                "%s: MID DEBUG: " format, \
00531                                LogComponents[component].comp_str, ## args ); \
00532   } while (0)
00533 
00534 #define LogFullDebug(component, format, args...) \
00535   do { \
00536     if (unlikely(LogComponents[component].comp_log_level >= NIV_FULL_DEBUG)) \
00537       DisplayLogComponentLevel(component, (char *)__FUNCTION__, NIV_FULL_DEBUG, \
00538                                "%s: FULLDEBUG: " format, \
00539                                LogComponents[component].comp_str, ## args ); \
00540   } while (0)
00541 
00542 #define LogAtLevel(component, level, format, args...) \
00543   do { \
00544     if (unlikely(LogComponents[component].comp_log_level >= level)) \
00545       DisplayLogComponentLevel(component, (char *)__FUNCTION__, level, \
00546                                "%s: %s: " format, \
00547                                LogComponents[component].comp_str, tabLogLevel[level].short_str, ## args ); \
00548   } while (0)
00549 
00550 #define LogError( component, a, b, c ) \
00551   do { \
00552     if (unlikely(LogComponents[component].comp_log_level >= NIV_CRIT)) \
00553       DisplayErrorComponentLogLine( component,(char *)__FUNCTION__, a, b, c, __LINE__ ); \
00554   } while (0)
00555 
00556 #define isLevel(component, level) \
00557     (unlikely(LogComponents[component].comp_log_level >= level))
00558 
00559 #define isInfo(component) \
00560     (unlikely(LogComponents[component].comp_log_level >= NIV_INFO))
00561 
00562 #define isDebug(component) \
00563     (unlikely(LogComponents[component].comp_log_level >= NIV_DEBUG))
00564 
00565 #define isMidDebug(component) \
00566     (unlikely(LogComponents[component].comp_log_level >= NIV_MID_DEBUG))
00567 
00568 #define isFullDebug(component) \
00569     (unlikely(LogComponents[component].comp_log_level >= NIV_FULL_DEBUG))
00570 
00571 /*
00572  *  Re-export component logging to TI-RPC internal logging
00573  */
00574 void rpc_warnx(/* const */ char *fmt, ...);
00575 
00576 #endif