Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lnet / libcfs / debug.c
index 5de53f4..baeaeac 100644 (file)
@@ -26,6 +26,7 @@
 
 # define DEBUG_SUBSYSTEM S_LNET
 
+#include <stdarg.h>
 #include <libcfs/kp30.h>
 #include <libcfs/libcfs.h>
 #include "tracefile.h"
@@ -37,8 +38,7 @@ unsigned int libcfs_subsystem_debug = ~0;
 EXPORT_SYMBOL(libcfs_subsystem_debug);
 
 unsigned int libcfs_debug = (D_EMERG | D_ERROR | D_WARNING | D_CONSOLE |
-                             D_NETERROR | D_HA | D_CONFIG | D_IOCTL |
-                             D_DLMTRACE | D_RPCTRACE | D_VFSTRACE);
+                             D_NETERROR | D_HA | D_CONFIG | D_IOCTL);
 EXPORT_SYMBOL(libcfs_debug);
 
 unsigned int libcfs_printk;
@@ -47,6 +47,15 @@ EXPORT_SYMBOL(libcfs_printk);
 unsigned int libcfs_console_ratelimit = 1;
 EXPORT_SYMBOL(libcfs_console_ratelimit);
 
+cfs_duration_t libcfs_console_max_delay;
+EXPORT_SYMBOL(libcfs_console_max_delay);
+
+cfs_duration_t libcfs_console_min_delay;
+EXPORT_SYMBOL(libcfs_console_min_delay);
+
+unsigned int libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF;
+EXPORT_SYMBOL(libcfs_console_backoff);
+
 unsigned int libcfs_debug_binary = 1;
 EXPORT_SYMBOL(libcfs_debug_binary);
 
@@ -59,12 +68,19 @@ EXPORT_SYMBOL(portal_enter_debugger);
 unsigned int libcfs_catastrophe;
 EXPORT_SYMBOL(libcfs_catastrophe);
 
+unsigned int libcfs_panic_on_lbug = 0;
+EXPORT_SYMBOL(libcfs_panic_on_lbug);
+
 atomic_t libcfs_kmemory = ATOMIC_INIT(0);
 EXPORT_SYMBOL(libcfs_kmemory);
 
 static cfs_waitq_t debug_ctlwq;
 
+#ifdef __arch_um__
+char debug_file_path[1024] = "/r/tmp/lustre-log";
+#else
 char debug_file_path[1024] = "/tmp/lustre-log";
+#endif
 
 int libcfs_panic_in_progress;
 
@@ -222,7 +238,7 @@ libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys)
                                         str[len] = ' ';
                                 len++;
                         }
-                
+
                         while (*token != 0) {
                                 if (len < size)
                                         str[len] = *token;
@@ -258,7 +274,7 @@ libcfs_debug_token2mask(int *mask, const char *str, int len, int is_subsys)
                 token = fn(bit);
                 if (token == NULL)              /* unused? */
                         continue;
-                
+
                 /* strcasecmp */
                 for (j = 0; ; j++) {
                         if (j == len) {         /* end of token */
@@ -268,13 +284,13 @@ libcfs_debug_token2mask(int *mask, const char *str, int len, int is_subsys)
                                 }
                                 break;
                         }
-                        
+
                         if (token[j] == 0)
                                 break;
-                                
+
                         if (str[j] == token[j])
                                 continue;
-                        
+
                         if (str[j] < 'A' || 'Z' < str[j])
                                 break;
 
@@ -282,7 +298,7 @@ libcfs_debug_token2mask(int *mask, const char *str, int len, int is_subsys)
                                 break;
                 }
         }
-        
+
         return -EINVAL;                         /* no match */
 }
 
@@ -290,17 +306,31 @@ int
 libcfs_debug_str2mask(int *mask, const char *str, int is_subsys)
 {
         int         m = 0;
-        int         matched = 0;
         char        op = 0;
+        int         matched;
         int         n;
         int         t;
 
+        /* Allow a number for backwards compatibility */
+
+        for (n = strlen(str); n > 0; n--)
+                if (!isspace(str[n-1]))
+                        break;
+        matched = n;
+
+        if ((t = sscanf(str, "%i%n", &m, &matched)) >= 1 &&
+            matched == n) {
+                *mask = m;
+                return 0;
+        }
+
         /* <str> must be a list of debug tokens or numbers separated by
          * whitespace and optionally an operator ('+' or '-').  If an operator
          * appears first in <str>, '*mask' is used as the starting point
          * (relative), otherwise 0 is used (absolute).  An operator applies to
          * all following tokens up to the next operator. */
-        
+
+        matched = 0;
         while (*str != 0) {
                 while (isspace(*str)) /* skip whitespace */
                         str++;
@@ -328,13 +358,13 @@ libcfs_debug_str2mask(int *mask, const char *str, int is_subsys)
                 /* match token */
                 if (libcfs_debug_token2mask(&t, str, n, is_subsys) != 0)
                         return -EINVAL;
-                
+
                 matched = 1;
                 if (op == '-')
                         m &= ~t;
                 else
                         m |= t;
-                
+
                 str += n;
         }
 
@@ -399,6 +429,8 @@ int libcfs_debug_init(unsigned long bufsize)
         int    rc;
 
         cfs_waitq_init(&debug_ctlwq);
+        libcfs_console_max_delay = CDEBUG_DEFAULT_MAX_DELAY;
+        libcfs_console_min_delay = CDEBUG_DEFAULT_MIN_DELAY;
         rc = tracefile_init();
 
         if (rc == 0)
@@ -450,10 +482,6 @@ EXPORT_SYMBOL(libcfs_debug_set_level);
 
 #include <libcfs/libcfs.h>
 
-#ifdef HAVE_SYS_USER_H
-# include <sys/user.h>
-#endif
-
 #ifdef HAVE_CATAMOUNT_DATA_H
 #include <catamount/data.h>
 #include <catamount/lputs.h>
@@ -462,13 +490,16 @@ static char source_nid[16];
 /* 0 indicates no messages to console, 1 is errors, > 1 is all debug messages */
 static int toconsole = 1;
 unsigned int libcfs_console_ratelimit = 1;
+cfs_duration_t libcfs_console_max_delay;
+cfs_duration_t libcfs_console_min_delay;
+unsigned int libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF;
 #else /* !HAVE_CATAMOUNT_DATA_H */
 #ifdef HAVE_NETDB_H
 #include <sys/utsname.h>
-#endif /* HAVE_CATAMOUNT_DATA_H */
+#endif /* HAVE_NETDB_H */
 struct utsname *tmp_utsname;
 static char source_nid[sizeof(tmp_utsname->nodename)];
-#endif /* __KERNEL__ */
+#endif /* HAVE_CATAMOUNT_DATA_H */
 
 static int source_pid;
 int smp_processor_id = 1;
@@ -503,6 +534,12 @@ int libcfs_debug_init(unsigned long bufsize)
 #ifdef HAVE_CATAMOUNT_DATA_H
         char *debug_console = NULL;
         char *debug_ratelimit = NULL;
+        char *debug_max_delay = NULL;
+        char *debug_min_delay = NULL;
+        char *debug_backoff = NULL;
+
+        libcfs_console_max_delay = CDEBUG_DEFAULT_MAX_DELAY;
+        libcfs_console_min_delay = CDEBUG_DEFAULT_MIN_DELAY;
 
         snprintf(source_nid, sizeof(source_nid) - 1, "%u", _my_pnid);
         source_pid = _my_pid;
@@ -515,7 +552,47 @@ int libcfs_debug_init(unsigned long bufsize)
         debug_ratelimit = getenv("LIBLUSTRE_DEBUG_CONSOLE_RATELIMIT");
         if (debug_ratelimit != NULL) {
                 libcfs_console_ratelimit = strtoul(debug_ratelimit, NULL, 0);
-                CDEBUG(D_INFO, "set liblustre console ratelimit to %u\n", libcfs_console_ratelimit);
+                CDEBUG(D_INFO, "set liblustre console ratelimit to %u\n",
+                                libcfs_console_ratelimit);
+        }
+        debug_max_delay = getenv("LIBLUSTRE_DEBUG_CONSOLE_MAX_DELAY");
+        if (debug_max_delay != NULL)
+                libcfs_console_max_delay =
+                            cfs_time_seconds(strtoul(debug_max_delay, NULL, 0));
+        debug_min_delay = getenv("LIBLUSTRE_DEBUG_CONSOLE_MIN_DELAY");
+        if (debug_min_delay != NULL)
+                libcfs_console_min_delay =
+                            cfs_time_seconds(strtoul(debug_min_delay, NULL, 0));
+        if (debug_min_delay || debug_max_delay) {
+                if (!libcfs_console_max_delay || !libcfs_console_min_delay ||
+                    libcfs_console_max_delay < libcfs_console_min_delay) {
+                        libcfs_console_max_delay = CDEBUG_DEFAULT_MAX_DELAY;
+                        libcfs_console_min_delay = CDEBUG_DEFAULT_MIN_DELAY;
+                        CDEBUG(D_INFO, "LIBLUSTRE_DEBUG_CONSOLE_MAX_DELAY "
+                                       "should be greater than "
+                                       "LIBLUSTRE_DEBUG_CONSOLE_MIN_DELAY "
+                                       "and both parameters should be non-null"
+                                       ": restore default values\n");
+                } else {
+                        CDEBUG(D_INFO, "set liblustre console max delay to %lus"
+                                       " and min delay to %lus\n",
+                               (cfs_duration_t)
+                                     cfs_duration_sec(libcfs_console_max_delay),
+                               (cfs_duration_t)
+                                    cfs_duration_sec(libcfs_console_min_delay));
+                }
+        }
+        debug_backoff = getenv("LIBLUSTRE_DEBUG_CONSOLE_BACKOFF");
+        if (debug_backoff != NULL) {
+                libcfs_console_backoff = strtoul(debug_backoff, NULL, 0);
+                if (libcfs_console_backoff <= 0) {
+                        libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF;
+                        CDEBUG(D_INFO, "LIBLUSTRE_DEBUG_CONSOLE_BACKOFF <= 0: "
+                                       "restore default value\n");
+                } else {
+                        CDEBUG(D_INFO, "set liblustre console backoff to %u\n",
+                               libcfs_console_backoff);
+                }
         }
 #else
         struct utsname myname;
@@ -653,10 +730,6 @@ libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls,
         if (console) {
                 /* check rate limit for console */
                 if (cdls != NULL) {
-                        cfs_time_t t = cdls->cdls_next +
-                                       cfs_time_seconds(CDEBUG_MAX_LIMIT + 10);
-                        cfs_duration_t  dmax = cfs_time_seconds(CDEBUG_MAX_LIMIT);
-
                         if (libcfs_console_ratelimit &&
                                 cdls->cdls_next != 0 &&     /* not first time ever */
                                 !cfs_time_after(cfs_time_current(), cdls->cdls_next)) {
@@ -666,16 +739,22 @@ libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls,
                                 goto out_file;
                         }
 
-                        if (cfs_time_after(cfs_time_current(), t)) {
+                        if (cfs_time_after(cfs_time_current(), cdls->cdls_next +
+                                           libcfs_console_max_delay +
+                                           cfs_time_seconds(10))) {
                                 /* last timeout was a long time ago */
-                                cdls->cdls_delay /= 8;
+                                cdls->cdls_delay /= libcfs_console_backoff * 4;
                         } else {
-                                cdls->cdls_delay *= 2;
-
-                                if (cdls->cdls_delay < CFS_TICK)
-                                        cdls->cdls_delay = CFS_TICK;
-                                else if (cdls->cdls_delay > dmax)
-                                        cdls->cdls_delay = dmax;
+                                cdls->cdls_delay *= libcfs_console_backoff;
+
+                                if (cdls->cdls_delay <
+                                                libcfs_console_min_delay)
+                                        cdls->cdls_delay =
+                                                libcfs_console_min_delay;
+                                else if (cdls->cdls_delay >
+                                                libcfs_console_max_delay)
+                                        cdls->cdls_delay =
+                                                libcfs_console_max_delay;
                         }
 
                         /* ensure cdls_next is never zero after it's been seen */