Whamcloud - gitweb
LU-2503 libcfs: Call lbug_with_loc() in LASSERT()
[fs/lustre-release.git] / libcfs / libcfs / posix / posix-debug.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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
19  *
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
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  *
34  * libcfs/libcfs/posix/posix_debug.c
35  *
36  * Userspace debugging.
37  *
38  */
39
40 # define DEBUG_SUBSYSTEM S_LNET
41
42 #include <libcfs/libcfs.h>
43
44 static char debug_file_name[1024];
45 unsigned int libcfs_subsystem_debug = ~(S_LNET | S_LND);
46 unsigned int libcfs_debug = 0;
47
48 #ifdef HAVE_NETDB_H
49 #include <sys/utsname.h>
50 #endif /* HAVE_NETDB_H */
51 struct utsname *tmp_utsname;
52 static char source_nid[sizeof(tmp_utsname->nodename)];
53
54 static int source_pid;
55 int cfs_smp_processor_id = 1;
56 char libcfs_debug_file_path[1024];
57 FILE *debug_file_fd;
58
59 int portals_do_debug_dumplog(void *arg)
60 {
61         printf("Look in %s\n", debug_file_name);
62         return 0;
63 }
64
65
66 void portals_debug_print(void)
67 {
68         return;
69 }
70
71
72 void libcfs_debug_dumplog(void)
73 {
74         printf("Look in %s\n", debug_file_name);
75         return;
76 }
77
78 int libcfs_debug_init(unsigned long bufsize)
79 {
80         char *debug_mask = NULL;
81         char *debug_subsys = NULL;
82         char *debug_filename;
83
84         struct utsname myname;
85
86         if (uname(&myname) == 0)
87                 strcpy(source_nid, myname.nodename);
88         source_pid = getpid();
89
90         /* debug masks */
91         debug_mask = getenv("LIBLUSTRE_DEBUG_MASK");
92         if (debug_mask)
93                 libcfs_debug = (unsigned int) strtol(debug_mask, NULL, 0);
94
95         debug_subsys = getenv("LIBLUSTRE_DEBUG_SUBSYS");
96         if (debug_subsys)
97                 libcfs_subsystem_debug =
98                                 (unsigned int) strtol(debug_subsys, NULL, 0);
99
100         debug_filename = getenv("LIBLUSTRE_DEBUG_BASE");
101         if (debug_filename)
102                 strncpy(libcfs_debug_file_path, debug_filename,
103                         sizeof(libcfs_debug_file_path));
104
105         debug_filename = getenv("LIBLUSTRE_DEBUG_FILE");
106         if (debug_filename)
107                 strncpy(debug_file_name,debug_filename,sizeof(debug_file_name));
108
109         if (debug_file_name[0] == '\0' && libcfs_debug_file_path[0] != '\0')
110                 snprintf(debug_file_name, sizeof(debug_file_name) - 1,
111                          "%s-%s-"CFS_TIME_T".log", libcfs_debug_file_path,
112                          source_nid, time(0));
113
114         if (strcmp(debug_file_name, "stdout") == 0 ||
115             strcmp(debug_file_name, "-") == 0) {
116                 debug_file_fd = stdout;
117         } else if (strcmp(debug_file_name, "stderr") == 0) {
118                 debug_file_fd = stderr;
119         } else if (debug_file_name[0] != '\0') {
120                 debug_file_fd = fopen(debug_file_name, "w");
121                 if (debug_file_fd == NULL)
122                         fprintf(stderr, "%s: unable to open '%s': %s\n",
123                                 source_nid, debug_file_name, strerror(errno));
124         }
125
126         if (debug_file_fd == NULL)
127                 debug_file_fd = stdout;
128
129         return 0;
130 }
131
132 int libcfs_debug_cleanup(void)
133 {
134         if (debug_file_fd != stdout && debug_file_fd != stderr)
135                 fclose(debug_file_fd);
136         return 0;
137 }
138
139 int libcfs_debug_clear_buffer(void)
140 {
141         return 0;
142 }
143
144 int libcfs_debug_mark_buffer(const char *text)
145 {
146
147         fprintf(debug_file_fd, "*******************************************************************************\n");
148         fprintf(debug_file_fd, "DEBUG MARKER: %s\n", text);
149         fprintf(debug_file_fd, "*******************************************************************************\n");
150
151         return 0;
152 }
153
154 int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
155                      const char *format, ...)
156 {
157         va_list args;
158         int     rc;
159
160         va_start(args, format);
161         rc = libcfs_debug_vmsg2(msgdata, format, args, NULL);
162         va_end(args);
163
164         return rc;
165 }
166
167 int
168 libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
169                    const char *format1, va_list args,
170                    const char *format2, ...)
171 {
172         struct timeval tv;
173         int            nob;
174         int            remain;
175         va_list        ap;
176         char           buf[CFS_PAGE_SIZE]; /* size 4096 used for compatimble
177                                             * with linux, where message can`t
178                                             * be exceed PAGE_SIZE */
179         int            console = 0;
180         char *prefix = "Lustre";
181
182         if ((!console) && (!debug_file_fd)) {
183                 return 0;
184         }
185
186         if (msgdata->msg_mask & (D_EMERG | D_ERROR))
187                prefix = "LustreError";
188
189         nob = snprintf(buf, sizeof(buf), "%s: %u-%s:(%s:%d:%s()): ", prefix,
190                        source_pid, source_nid, msgdata->msg_file,
191                        msgdata->msg_line, msgdata->msg_fn);
192
193         remain = sizeof(buf) - nob;
194         if (format1) {
195                 nob += vsnprintf(&buf[nob], remain, format1, args);
196         }
197
198         remain = sizeof(buf) - nob;
199         if ((format2) && (remain > 0)) {
200                 va_start(ap, format2);
201                 nob += vsnprintf(&buf[nob], remain, format2, ap);
202                 va_end(ap);
203         }
204
205         if (debug_file_fd == NULL)
206                 return 0;
207
208         gettimeofday(&tv, NULL);
209
210         fprintf(debug_file_fd, CFS_TIME_T".%06lu:%u:%s:(%s:%d:%s()): %s",
211                 tv.tv_sec, tv.tv_usec, source_pid, source_nid,
212                 msgdata->msg_file, msgdata->msg_line, msgdata->msg_fn, buf);
213
214         return 0;
215 }
216
217 /*
218  * a helper function for RETURN(): the sole purpose is to save 8-16 bytes
219  * on the stack - function calling RETURN() doesn't need to allocate two
220  * additional 'rc' on the stack
221  */
222 long libcfs_log_return(struct libcfs_debug_msg_data *msgdata, long rc)
223 {
224         libcfs_debug_msg(msgdata, "Process leaving (rc=%lu : %ld : %lx)\n",
225                          rc, rc, rc);
226         return rc;
227 }
228
229 /*
230  * a helper function for GOTO(): the sole purpose is to save 8-16 bytes
231  * on the stack - function calling GOTO() doesn't need to allocate two
232  * additional 'rc' on the stack
233  */
234 void libcfs_log_goto(struct libcfs_debug_msg_data *msgdata, const char *l,
235                      long_ptr_t rc)
236 {
237         libcfs_debug_msg(msgdata, "Process leaving via %s (rc=" LPLU " : "
238                          LPLD " : " LPLX ")\n", l, (ulong_ptr_t) rc, rc, rc);
239 }