4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2014, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * libcfs/libcfs/debug.c
38 * Author: Phil Schwan <phil@clusterfs.com>
42 # define DEBUG_SUBSYSTEM S_LNET
44 #include <linux/kthread.h>
45 #include <libcfs/libcfs.h>
46 #include "tracefile.h"
48 static char debug_file_name[1024];
50 unsigned int libcfs_subsystem_debug = ~0;
51 CFS_MODULE_PARM(libcfs_subsystem_debug, "i", int, 0644,
52 "Lustre kernel debug subsystem mask");
53 EXPORT_SYMBOL(libcfs_subsystem_debug);
55 unsigned int libcfs_debug = (D_CANTMASK |
56 D_NETERROR | D_HA | D_CONFIG | D_IOCTL | D_LFSCK);
57 CFS_MODULE_PARM(libcfs_debug, "i", int, 0644,
58 "Lustre kernel debug mask");
59 EXPORT_SYMBOL(libcfs_debug);
61 unsigned int libcfs_debug_mb;
62 CFS_MODULE_PARM(libcfs_debug_mb, "i", uint, 0644,
63 "Total debug buffer size.");
65 unsigned int libcfs_printk = D_CANTMASK;
66 CFS_MODULE_PARM(libcfs_printk, "i", uint, 0644,
67 "Lustre kernel debug console mask");
69 unsigned int libcfs_console_ratelimit = 1;
70 CFS_MODULE_PARM(libcfs_console_ratelimit, "i", uint, 0644,
71 "Lustre kernel debug console ratelimit (0 to disable)");
73 unsigned int libcfs_console_max_delay;
74 CFS_MODULE_PARM(libcfs_console_max_delay, "l", uint, 0644,
75 "Lustre kernel debug console max delay (jiffies)");
77 unsigned int libcfs_console_min_delay;
78 CFS_MODULE_PARM(libcfs_console_min_delay, "l", uint, 0644,
79 "Lustre kernel debug console min delay (jiffies)");
81 unsigned int libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF;
82 CFS_MODULE_PARM(libcfs_console_backoff, "i", uint, 0644,
83 "Lustre kernel debug console backoff factor");
85 unsigned int libcfs_debug_binary = 1;
87 unsigned int libcfs_stack = 3 * THREAD_SIZE / 4;
88 EXPORT_SYMBOL(libcfs_stack);
90 unsigned int libcfs_catastrophe;
91 EXPORT_SYMBOL(libcfs_catastrophe);
93 unsigned int libcfs_watchdog_ratelimit = 300;
95 unsigned int libcfs_panic_on_lbug = 1;
96 CFS_MODULE_PARM(libcfs_panic_on_lbug, "i", uint, 0644,
97 "Lustre kernel panic on LBUG");
99 atomic_t libcfs_kmemory = ATOMIC_INIT(0);
100 EXPORT_SYMBOL(libcfs_kmemory);
102 static wait_queue_head_t debug_ctlwq;
104 char libcfs_debug_file_path_arr[PATH_MAX] = LIBCFS_DEBUG_FILE_PATH_DEFAULT;
106 /* We need to pass a pointer here, but elsewhere this must be a const */
107 static char *libcfs_debug_file_path;
108 CFS_MODULE_PARM(libcfs_debug_file_path, "s", charp, 0644,
109 "Path for dumping debug logs, "
110 "set 'NONE' to prevent log dumping");
112 int libcfs_panic_in_progress;
114 /* libcfs_debug_token2mask() expects the returned
115 * string in lower-case */
116 static const char *libcfs_debug_subsys2str(int subsys)
118 static const char *libcfs_debug_subsystems[] = LIBCFS_DEBUG_SUBSYS_NAMES;
120 if (subsys >= ARRAY_SIZE(libcfs_debug_subsystems))
123 return libcfs_debug_subsystems[subsys];
126 /* libcfs_debug_token2mask() expects the returned
127 * string in lower-case */
128 static const char *libcfs_debug_dbg2str(int debug)
130 static const char *libcfs_debug_masks[] = LIBCFS_DEBUG_MASKS_NAMES;
132 if (debug >= ARRAY_SIZE(libcfs_debug_masks))
135 return libcfs_debug_masks[debug];
139 libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys)
141 const char *(*fn)(int bit) = is_subsys ? libcfs_debug_subsys2str :
142 libcfs_debug_dbg2str;
147 if (mask == 0) { /* "0" */
151 } else { /* space-separated tokens */
152 for (i = 0; i < 32; i++) {
153 if ((mask & (1 << i)) == 0)
157 if (token == NULL) /* unused bit */
160 if (len > 0) { /* separator? */
166 while (*token != 0) {
175 /* terminate 'str' */
185 libcfs_debug_str2mask(int *mask, const char *str, int is_subsys)
187 const char *(*fn)(int bit) = is_subsys ? libcfs_debug_subsys2str :
188 libcfs_debug_dbg2str;
194 /* Allow a number for backwards compatibility */
196 for (n = strlen(str); n > 0; n--)
197 if (!isspace(str[n-1]))
201 if ((t = sscanf(str, "%i%n", &m, &matched)) >= 1 &&
203 /* don't print warning for lctl set_param debug=0 or -1 */
204 if (m != 0 && m != -1)
205 CWARN("You are trying to use a numerical value for the "
206 "mask - this will be deprecated in a future "
212 return cfs_str2mask(str, fn, mask, is_subsys ? 0 : D_CANTMASK,
217 * Dump Lustre log to ::debug_file_path by calling tracefile_dump_all_pages()
219 void libcfs_debug_dumplog_internal(void *arg)
221 static time_t last_dump_time;
225 journal_info = current->journal_info;
226 current->journal_info = NULL;
228 current_time = cfs_time_current_sec();
230 if (strncmp(libcfs_debug_file_path_arr, "NONE", 4) != 0 &&
231 current_time > last_dump_time) {
232 last_dump_time = current_time;
233 snprintf(debug_file_name, sizeof(debug_file_name) - 1,
234 "%s.%ld." LPLD, libcfs_debug_file_path_arr,
235 current_time, (long_ptr_t)arg);
236 printk(KERN_ALERT "LustreError: dumping log to %s\n",
238 cfs_tracefile_dump_all_pages(debug_file_name);
239 libcfs_run_debug_log_upcall(debug_file_name);
241 current->journal_info = journal_info;
244 static int libcfs_debug_dumplog_thread(void *arg)
246 libcfs_debug_dumplog_internal(arg);
247 wake_up(&debug_ctlwq);
251 void libcfs_debug_dumplog(void)
254 struct task_struct *dumper;
257 /* we're being careful to ensure that the kernel thread is
258 * able to set our state to running as it exits before we
259 * get to schedule() */
260 init_waitqueue_entry(&wait, current);
261 set_current_state(TASK_INTERRUPTIBLE);
262 add_wait_queue(&debug_ctlwq, &wait);
264 dumper = kthread_run(libcfs_debug_dumplog_thread,
265 (void *)(long)current_pid(),
266 "libcfs_debug_dumper");
268 printk(KERN_ERR "LustreError: cannot start log dump thread:"
269 " %ld\n", PTR_ERR(dumper));
273 /* be sure to teardown if cfs_create_thread() failed */
274 remove_wait_queue(&debug_ctlwq, &wait);
275 set_current_state(TASK_RUNNING);
277 EXPORT_SYMBOL(libcfs_debug_dumplog);
279 int libcfs_debug_init(unsigned long bufsize)
282 unsigned int max = libcfs_debug_mb;
284 init_waitqueue_head(&debug_ctlwq);
286 if (libcfs_console_max_delay <= 0 || /* not set by user or */
287 libcfs_console_min_delay <= 0 || /* set to invalid values */
288 libcfs_console_min_delay >= libcfs_console_max_delay) {
289 libcfs_console_max_delay = CDEBUG_DEFAULT_MAX_DELAY;
290 libcfs_console_min_delay = CDEBUG_DEFAULT_MIN_DELAY;
293 if (libcfs_debug_file_path != NULL) {
294 strlcpy(libcfs_debug_file_path_arr,
295 libcfs_debug_file_path,
296 sizeof(libcfs_debug_file_path_arr));
299 /* If libcfs_debug_mb is set to an invalid value or uninitialized
300 * then just make the total buffers smp_num_cpus * TCD_MAX_PAGES */
301 if (max > cfs_trace_max_debug_mb() || max < num_possible_cpus()) {
304 max = (max / num_possible_cpus());
305 max = (max << (20 - PAGE_CACHE_SHIFT));
307 rc = cfs_tracefile_init(max);
310 libcfs_register_panic_notifier();
315 int libcfs_debug_cleanup(void)
317 libcfs_unregister_panic_notifier();
318 cfs_tracefile_exit();
322 int libcfs_debug_clear_buffer(void)
324 cfs_trace_flush_pages();
328 /* Debug markers, although printed by S_LNET
329 * should not be be marked as such. */
330 #undef DEBUG_SUBSYSTEM
331 #define DEBUG_SUBSYSTEM S_UNDEFINED
332 int libcfs_debug_mark_buffer(const char *text)
334 CDEBUG(D_TRACE,"***************************************************\n");
335 LCONSOLE(D_WARNING, "DEBUG MARKER: %s\n", text);
336 CDEBUG(D_TRACE,"***************************************************\n");
340 #undef DEBUG_SUBSYSTEM
341 #define DEBUG_SUBSYSTEM S_LNET
343 void libcfs_debug_set_level(unsigned int debug_level)
345 printk(KERN_WARNING "Lustre: Setting portals debug level to %08x\n",
347 libcfs_debug = debug_level;
350 long libcfs_log_return(struct libcfs_debug_msg_data *msgdata, long rc)
352 libcfs_debug_msg(msgdata, "Process leaving (rc=%lu : %ld : %lx)\n",
356 EXPORT_SYMBOL(libcfs_log_return);
358 void libcfs_log_goto(struct libcfs_debug_msg_data *msgdata, const char *label,
361 libcfs_debug_msg(msgdata, "Process leaving via %s (rc=" LPLU " : " LPLD
362 " : " LPLX ")\n", label, (ulong_ptr_t)rc, rc, rc);
364 EXPORT_SYMBOL(libcfs_log_goto);