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.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
34 * libcfs/libcfs/posix/posix_debug.c
36 * Userspace debugging.
40 # define DEBUG_SUBSYSTEM S_LNET
42 #include <libcfs/libcfs.h>
44 static char debug_file_name[1024];
47 #include <sys/utsname.h>
48 #endif /* HAVE_NETDB_H */
49 struct utsname *tmp_utsname;
50 static char source_nid[sizeof(tmp_utsname->nodename)];
52 static int source_pid;
53 int cfs_smp_processor_id = 1;
54 char libcfs_debug_file_path[1024];
57 int portals_do_debug_dumplog(void *arg)
59 printf("Look in %s\n", debug_file_name);
64 void portals_debug_print(void)
70 void libcfs_debug_dumplog(void)
72 printf("Look in %s\n", debug_file_name);
76 int libcfs_debug_init(unsigned long bufsize)
78 char *debug_mask = NULL;
79 char *debug_subsys = NULL;
82 struct utsname myname;
84 if (uname(&myname) == 0)
85 strcpy(source_nid, myname.nodename);
86 source_pid = getpid();
89 debug_mask = getenv("LIBLUSTRE_DEBUG_MASK");
91 libcfs_debug = (unsigned int) strtol(debug_mask, NULL, 0);
93 debug_subsys = getenv("LIBLUSTRE_DEBUG_SUBSYS");
95 libcfs_subsystem_debug =
96 (unsigned int) strtol(debug_subsys, NULL, 0);
98 debug_filename = getenv("LIBLUSTRE_DEBUG_BASE");
100 strncpy(libcfs_debug_file_path, debug_filename,
101 sizeof(libcfs_debug_file_path));
103 debug_filename = getenv("LIBLUSTRE_DEBUG_FILE");
105 strncpy(debug_file_name,debug_filename,sizeof(debug_file_name));
107 if (debug_file_name[0] == '\0' && libcfs_debug_file_path[0] != '\0')
108 snprintf(debug_file_name, sizeof(debug_file_name) - 1,
109 "%s-%s-"CFS_TIME_T".log", libcfs_debug_file_path,
110 source_nid, time(0));
112 if (strcmp(debug_file_name, "stdout") == 0 ||
113 strcmp(debug_file_name, "-") == 0) {
114 debug_file_fd = stdout;
115 } else if (strcmp(debug_file_name, "stderr") == 0) {
116 debug_file_fd = stderr;
117 } else if (debug_file_name[0] != '\0') {
118 debug_file_fd = fopen(debug_file_name, "w");
119 if (debug_file_fd == NULL)
120 fprintf(stderr, "%s: unable to open '%s': %s\n",
121 source_nid, debug_file_name, strerror(errno));
124 if (debug_file_fd == NULL)
125 debug_file_fd = stdout;
130 int libcfs_debug_cleanup(void)
132 if (debug_file_fd != stdout && debug_file_fd != stderr)
133 fclose(debug_file_fd);
137 int libcfs_debug_clear_buffer(void)
142 int libcfs_debug_mark_buffer(const char *text)
145 fprintf(debug_file_fd, "*******************************************************************************\n");
146 fprintf(debug_file_fd, "DEBUG MARKER: %s\n", text);
147 fprintf(debug_file_fd, "*******************************************************************************\n");
152 int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
153 const char *format, ...)
158 va_start(args, format);
159 rc = libcfs_debug_vmsg2(msgdata, format, args, NULL);
166 libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
167 const char *format1, va_list args,
168 const char *format2, ...)
174 char buf[CFS_PAGE_SIZE]; /* size 4096 used for compatimble
175 * with linux, where message can`t
176 * be exceed PAGE_SIZE */
178 char *prefix = "Lustre";
180 if ((!console) && (!debug_file_fd)) {
184 if (msgdata->msg_mask & (D_EMERG | D_ERROR))
185 prefix = "LustreError";
187 nob = snprintf(buf, sizeof(buf), "%s: %u-%s:(%s:%d:%s()): ", prefix,
188 source_pid, source_nid, msgdata->msg_file,
189 msgdata->msg_line, msgdata->msg_fn);
191 remain = sizeof(buf) - nob;
193 nob += vsnprintf(&buf[nob], remain, format1, args);
196 remain = sizeof(buf) - nob;
197 if ((format2) && (remain > 0)) {
198 va_start(ap, format2);
199 nob += vsnprintf(&buf[nob], remain, format2, ap);
203 if (debug_file_fd == NULL)
206 gettimeofday(&tv, NULL);
208 fprintf(debug_file_fd, CFS_TIME_T".%06lu:%u:%s:(%s:%d:%s()): %s",
209 tv.tv_sec, tv.tv_usec, source_pid, source_nid,
210 msgdata->msg_file, msgdata->msg_line, msgdata->msg_fn, buf);
216 libcfs_assertion_failed(const char *expr, struct libcfs_debug_msg_data *msgdata)
218 libcfs_debug_msg(msgdata, "ASSERTION(%s) failed\n", expr);
223 * a helper function for RETURN(): the sole purpose is to save 8-16 bytes
224 * on the stack - function calling RETURN() doesn't need to allocate two
225 * additional 'rc' on the stack
227 long libcfs_log_return(struct libcfs_debug_msg_data *msgdata, long rc)
229 libcfs_debug_msg(msgdata, "Process leaving (rc=%lu : %ld : %lx)\n",
235 * a helper function for GOTO(): the sole purpose is to save 8-16 bytes
236 * on the stack - function calling GOTO() doesn't need to allocate two
237 * additional 'rc' on the stack
239 void libcfs_log_goto(struct libcfs_debug_msg_data *msgdata, const char *l,
242 libcfs_debug_msg(msgdata, "Process leaving via %s (rc=" LPLU " : "
243 LPLD " : " LPLX ")\n", l, (ulong_ptr_t) rc, rc, rc);