Whamcloud - gitweb
c91eb7bebeaacb0ab1fde8f5144a5314d78c58a9
[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
46 #ifdef HAVE_NETDB_H
47 #include <sys/utsname.h>
48 #endif /* HAVE_NETDB_H */
49 struct utsname *tmp_utsname;
50 static char source_nid[sizeof(tmp_utsname->nodename)];
51
52 static int source_pid;
53 int cfs_smp_processor_id = 1;
54 char libcfs_debug_file_path[1024];
55 FILE *debug_file_fd;
56
57 int portals_do_debug_dumplog(void *arg)
58 {
59         printf("Look in %s\n", debug_file_name);
60         return 0;
61 }
62
63
64 void portals_debug_print(void)
65 {
66         return;
67 }
68
69
70 void libcfs_debug_dumplog(void)
71 {
72         printf("Look in %s\n", debug_file_name);
73         return;
74 }
75
76 int libcfs_debug_init(unsigned long bufsize)
77 {
78         char *debug_mask = NULL;
79         char *debug_subsys = NULL;
80         char *debug_filename;
81
82         struct utsname myname;
83
84         if (uname(&myname) == 0)
85                 strcpy(source_nid, myname.nodename);
86         source_pid = getpid();
87
88         /* debug masks */
89         debug_mask = getenv("LIBLUSTRE_DEBUG_MASK");
90         if (debug_mask)
91                 libcfs_debug = (unsigned int) strtol(debug_mask, NULL, 0);
92
93         debug_subsys = getenv("LIBLUSTRE_DEBUG_SUBSYS");
94         if (debug_subsys)
95                 libcfs_subsystem_debug =
96                                 (unsigned int) strtol(debug_subsys, NULL, 0);
97
98         debug_filename = getenv("LIBLUSTRE_DEBUG_BASE");
99         if (debug_filename)
100                 strncpy(libcfs_debug_file_path, debug_filename,
101                         sizeof(libcfs_debug_file_path));
102
103         debug_filename = getenv("LIBLUSTRE_DEBUG_FILE");
104         if (debug_filename)
105                 strncpy(debug_file_name,debug_filename,sizeof(debug_file_name));
106
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));
111
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));
122         }
123
124         if (debug_file_fd == NULL)
125                 debug_file_fd = stdout;
126
127         return 0;
128 }
129
130 int libcfs_debug_cleanup(void)
131 {
132         if (debug_file_fd != stdout && debug_file_fd != stderr)
133                 fclose(debug_file_fd);
134         return 0;
135 }
136
137 int libcfs_debug_clear_buffer(void)
138 {
139         return 0;
140 }
141
142 int libcfs_debug_mark_buffer(const char *text)
143 {
144
145         fprintf(debug_file_fd, "*******************************************************************************\n");
146         fprintf(debug_file_fd, "DEBUG MARKER: %s\n", text);
147         fprintf(debug_file_fd, "*******************************************************************************\n");
148
149         return 0;
150 }
151
152 int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
153                      const char *format, ...)
154 {
155         va_list args;
156         int     rc;
157
158         va_start(args, format);
159         rc = libcfs_debug_vmsg2(msgdata, format, args, NULL);
160         va_end(args);
161
162         return rc;
163 }
164
165 int
166 libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
167                    const char *format1, va_list args,
168                    const char *format2, ...)
169 {
170         struct timeval tv;
171         int            nob;
172         int            remain;
173         va_list        ap;
174         char           buf[CFS_PAGE_SIZE]; /* size 4096 used for compatimble
175                                             * with linux, where message can`t
176                                             * be exceed PAGE_SIZE */
177         int            console = 0;
178         char *prefix = "Lustre";
179
180         if ((!console) && (!debug_file_fd)) {
181                 return 0;
182         }
183
184         if (msgdata->msg_mask & (D_EMERG | D_ERROR))
185                prefix = "LustreError";
186
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);
190
191         remain = sizeof(buf) - nob;
192         if (format1) {
193                 nob += vsnprintf(&buf[nob], remain, format1, args);
194         }
195
196         remain = sizeof(buf) - nob;
197         if ((format2) && (remain > 0)) {
198                 va_start(ap, format2);
199                 nob += vsnprintf(&buf[nob], remain, format2, ap);
200                 va_end(ap);
201         }
202
203         if (debug_file_fd == NULL)
204                 return 0;
205
206         gettimeofday(&tv, NULL);
207
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);
211
212         return 0;
213 }
214
215 void
216 libcfs_assertion_failed(const char *expr, struct libcfs_debug_msg_data *msgdata)
217 {
218         libcfs_debug_msg(msgdata, "ASSERTION(%s) failed\n", expr);
219         abort();
220 }
221
222 /*
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
226  */
227 long libcfs_log_return(struct libcfs_debug_msg_data *msgdata, long rc)
228 {
229         libcfs_debug_msg(msgdata, "Process leaving (rc=%lu : %ld : %lx)\n",
230                          rc, rc, rc);
231         return rc;
232 }
233
234 /*
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
238  */
239 void libcfs_log_goto(struct libcfs_debug_msg_data *msgdata, const char *l,
240                      long_ptr_t rc)
241 {
242         libcfs_debug_msg(msgdata, "Process leaving via %s (rc=" LPLU " : "
243                          LPLD " : " LPLX ")\n", l, (ulong_ptr_t) rc, rc, rc);
244 }