1b86efd96Sagiri /*
2b86efd96Sagiri * CDDL HEADER START
3b86efd96Sagiri *
4b86efd96Sagiri * The contents of this file are subject to the terms of the
5b86efd96Sagiri * Common Development and Distribution License (the "License").
6b86efd96Sagiri * You may not use this file except in compliance with the License.
7b86efd96Sagiri *
8b86efd96Sagiri * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9b86efd96Sagiri * or http://www.opensolaris.org/os/licensing.
10b86efd96Sagiri * See the License for the specific language governing permissions
11b86efd96Sagiri * and limitations under the License.
12b86efd96Sagiri *
13b86efd96Sagiri * When distributing Covered Code, include this CDDL HEADER in each
14b86efd96Sagiri * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15b86efd96Sagiri * If applicable, add the following below this CDDL HEADER, with the
16b86efd96Sagiri * fields enclosed by brackets "[]" replaced with your own identifying
17b86efd96Sagiri * information: Portions Copyright [yyyy] [name of copyright owner]
18b86efd96Sagiri *
19b86efd96Sagiri * CDDL HEADER END
20b86efd96Sagiri */
21b86efd96Sagiri /*
22*74242422Sagiri * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23b86efd96Sagiri * Use is subject to license terms.
24b86efd96Sagiri */
25b86efd96Sagiri
26b86efd96Sagiri #include <sys/types.h>
27b86efd96Sagiri #include <sys/varargs.h>
28b86efd96Sagiri #include <sys/cmn_err.h>
29b86efd96Sagiri #include <sys/ddi.h>
30b86efd96Sagiri #include <sys/sunddi.h>
31b86efd96Sagiri #include <sys/ib/clients/rds/rdsib_debug.h>
32b86efd96Sagiri
33b86efd96Sagiri /*
34b86efd96Sagiri * This file contains the debug defines and routines.
35b86efd96Sagiri * Debugging information is collected in a circular kernel buffer. Debug
36b86efd96Sagiri * messages with level lower than rdsdbglvl are ignored. The size of the
37b86efd96Sagiri * of the debug buffer can be changed by setting 'rds_debug_buf_size' in
38b86efd96Sagiri * bytes in /etc/system.
39b86efd96Sagiri *
40b86efd96Sagiri * The debug buffer can be cleared by setting 'rds_clear_debug_buf_flag = 1'
41b86efd96Sagiri * on a running system.
42b86efd96Sagiri */
43b86efd96Sagiri
44b86efd96Sagiri #define RDS_DEBUG_SIZE_EXTRA_ALLOC 8
45b86efd96Sagiri #define RDS_MIN_DEBUG_BUF_SIZE 0x1000
46b86efd96Sagiri #define RDS_FUNCNAME_LEN 40
47b86efd96Sagiri #define RDS_PRINTBUF_LEN 4096
48b86efd96Sagiri #ifdef DEBUG
49b86efd96Sagiri #define RDS_DEBUG_BUF_SIZE 0x10000
50b86efd96Sagiri #else
51b86efd96Sagiri #define RDS_DEBUG_BUF_SIZE 0x2000
52b86efd96Sagiri #endif /* DEBUG */
53b86efd96Sagiri
54b86efd96Sagiri /* Max length of a debug statement */
55b86efd96Sagiri #define RDS_PRINT_BUF_LEN 4096
56b86efd96Sagiri
57b86efd96Sagiri int rds_suppress_dprintf; /* Suppress debug printing */
58b86efd96Sagiri int rds_buffer_dprintf = 1; /* Use debug buffer (0 == console) */
59b86efd96Sagiri int rds_debug_buf_size = RDS_DEBUG_BUF_SIZE; /* Sz of Debug buf */
60b86efd96Sagiri int rds_allow_intr_msgs = 0; /* log "intr" messages */
61b86efd96Sagiri char *rds_debug_buf = NULL; /* The Debug Buf */
62b86efd96Sagiri char *rds_buf_sptr, *rds_buf_eptr; /* debug buffer temp pointer */
63b86efd96Sagiri int rds_clear_debug_buf_flag = 0; /* Clear debug buffer */
64b86efd96Sagiri extern uint_t rdsdbglvl;
65b86efd96Sagiri
66b86efd96Sagiri /*
67b86efd96Sagiri * Print Buffer protected by mutex for debug stuff. The mutex also
68b86efd96Sagiri * ensures serializing debug messages.
69b86efd96Sagiri */
70b86efd96Sagiri static kmutex_t rds_debug_mutex;
71b86efd96Sagiri static char rds_print_buf[RDS_PRINT_BUF_LEN];
72b86efd96Sagiri
73b86efd96Sagiri /* Function Prototypes */
74b86efd96Sagiri static void rds_clear_print_buf();
75b86efd96Sagiri
76b86efd96Sagiri /* RDS logging init */
77b86efd96Sagiri void
rds_logging_initialization()78b86efd96Sagiri rds_logging_initialization()
79b86efd96Sagiri {
80b86efd96Sagiri boolean_t flag = B_FALSE;
81b86efd96Sagiri
82b86efd96Sagiri mutex_init(&rds_debug_mutex, NULL, MUTEX_DRIVER, NULL);
83b86efd96Sagiri mutex_enter(&rds_debug_mutex);
84b86efd96Sagiri
85b86efd96Sagiri if (rds_debug_buf_size <= RDS_DEBUG_SIZE_EXTRA_ALLOC) {
86b86efd96Sagiri rds_debug_buf_size = RDS_MIN_DEBUG_BUF_SIZE;
87b86efd96Sagiri flag = B_TRUE;
88b86efd96Sagiri }
89b86efd96Sagiri
90b86efd96Sagiri /* if it is less that RDS_MIN_DEBUG_BUF_SIZE, adjust it */
91b86efd96Sagiri rds_debug_buf_size = max(RDS_MIN_DEBUG_BUF_SIZE,
92b86efd96Sagiri rds_debug_buf_size);
93b86efd96Sagiri
94b86efd96Sagiri rds_debug_buf = (char *)kmem_alloc(rds_debug_buf_size, KM_SLEEP);
95b86efd96Sagiri rds_clear_print_buf();
96b86efd96Sagiri mutex_exit(&rds_debug_mutex);
97b86efd96Sagiri
98b86efd96Sagiri if (flag == B_TRUE) {
99b86efd96Sagiri RDS_DPRINTF2("RDS", "rds_debug_buf_size was too small, "
100b86efd96Sagiri "adjusted to %x", rds_debug_buf_size);
101b86efd96Sagiri }
102b86efd96Sagiri }
103b86efd96Sagiri
104b86efd96Sagiri
105b86efd96Sagiri /* RDS logging destroy */
106b86efd96Sagiri void
rds_logging_destroy()107b86efd96Sagiri rds_logging_destroy()
108b86efd96Sagiri {
109b86efd96Sagiri mutex_enter(&rds_debug_mutex);
110b86efd96Sagiri if (rds_debug_buf) {
111b86efd96Sagiri kmem_free(rds_debug_buf, rds_debug_buf_size);
112b86efd96Sagiri rds_debug_buf = NULL;
113b86efd96Sagiri }
114b86efd96Sagiri mutex_exit(&rds_debug_mutex);
115b86efd96Sagiri mutex_destroy(&rds_debug_mutex);
116b86efd96Sagiri }
117b86efd96Sagiri
118b86efd96Sagiri
119b86efd96Sagiri /*
120b86efd96Sagiri * debug, log, and console message handling
121b86efd96Sagiri */
122b86efd96Sagiri
123b86efd96Sagiri /*
124b86efd96Sagiri * clear the RDS debug buffer
125b86efd96Sagiri */
126b86efd96Sagiri static void
rds_clear_print_buf()127b86efd96Sagiri rds_clear_print_buf()
128b86efd96Sagiri {
129b86efd96Sagiri ASSERT(MUTEX_HELD(&rds_debug_mutex));
130b86efd96Sagiri if (rds_debug_buf) {
131b86efd96Sagiri rds_buf_sptr = rds_debug_buf;
132b86efd96Sagiri rds_buf_eptr = rds_debug_buf + rds_debug_buf_size -
133b86efd96Sagiri RDS_DEBUG_SIZE_EXTRA_ALLOC;
134b86efd96Sagiri
135b86efd96Sagiri bzero(rds_debug_buf, rds_debug_buf_size);
136b86efd96Sagiri }
137b86efd96Sagiri }
138b86efd96Sagiri
139b86efd96Sagiri
140b86efd96Sagiri static void
rds_vlog(char * name,uint_t level,char * fmt,va_list ap)141b86efd96Sagiri rds_vlog(char *name, uint_t level, char *fmt, va_list ap)
142b86efd96Sagiri {
143b86efd96Sagiri char *label = (name == NULL) ? "rds" : name;
144b86efd96Sagiri char *msg_ptr;
145b86efd96Sagiri size_t len;
146b86efd96Sagiri
147b86efd96Sagiri mutex_enter(&rds_debug_mutex);
148b86efd96Sagiri
149b86efd96Sagiri /* if not using logging scheme; quit */
150b86efd96Sagiri if (rds_suppress_dprintf || (rds_debug_buf == NULL)) {
151b86efd96Sagiri mutex_exit(&rds_debug_mutex);
152b86efd96Sagiri return;
153b86efd96Sagiri }
154b86efd96Sagiri
155b86efd96Sagiri /* If user requests to clear debug buffer, go ahead */
156b86efd96Sagiri if (rds_clear_debug_buf_flag != 0) {
157b86efd96Sagiri rds_clear_print_buf();
158b86efd96Sagiri rds_clear_debug_buf_flag = 0;
159b86efd96Sagiri }
160b86efd96Sagiri
161b86efd96Sagiri /*
162b86efd96Sagiri * put "label" into the buffer
163b86efd96Sagiri */
164b86efd96Sagiri len = snprintf(rds_print_buf, RDS_FUNCNAME_LEN, "%s:\t", label);
165b86efd96Sagiri
166b86efd96Sagiri msg_ptr = rds_print_buf + len;
167b86efd96Sagiri len += vsnprintf(msg_ptr, RDS_PRINT_BUF_LEN - len - 2, fmt, ap);
168b86efd96Sagiri
169b86efd96Sagiri len = min(len, RDS_PRINT_BUF_LEN - 2);
170b86efd96Sagiri ASSERT(len == strlen(rds_print_buf));
171b86efd96Sagiri rds_print_buf[len++] = '\n';
172b86efd96Sagiri rds_print_buf[len] = '\0';
173b86efd96Sagiri
174b86efd96Sagiri /*
175b86efd96Sagiri * stuff the message in the debug buf
176b86efd96Sagiri */
177b86efd96Sagiri if (rds_buffer_dprintf) {
178b86efd96Sagiri
179b86efd96Sagiri /*
180b86efd96Sagiri * overwrite >>>> that might be over the end of the
181b86efd96Sagiri * the buffer
182b86efd96Sagiri */
183b86efd96Sagiri *rds_buf_sptr = '\0';
184b86efd96Sagiri
185b86efd96Sagiri if (rds_buf_sptr + len > rds_buf_eptr) {
186b86efd96Sagiri size_t left = (uintptr_t)rds_buf_eptr -
187b86efd96Sagiri (uintptr_t)rds_buf_sptr;
188b86efd96Sagiri
189b86efd96Sagiri bcopy((caddr_t)rds_print_buf,
190*74242422Sagiri (caddr_t)rds_buf_sptr, left);
191b86efd96Sagiri bcopy((caddr_t)rds_print_buf + left,
192*74242422Sagiri (caddr_t)rds_debug_buf, len - left);
193b86efd96Sagiri rds_buf_sptr = rds_debug_buf + len - left;
194b86efd96Sagiri } else {
195b86efd96Sagiri bcopy((caddr_t)rds_print_buf, rds_buf_sptr, len);
196b86efd96Sagiri rds_buf_sptr += len;
197b86efd96Sagiri }
198b86efd96Sagiri
199b86efd96Sagiri /* add marker */
200b86efd96Sagiri (void) sprintf(rds_buf_sptr, ">>>>");
201b86efd96Sagiri }
202b86efd96Sagiri
203b86efd96Sagiri /*
204b86efd96Sagiri * LINTR, L5-L2 message may go to the rds_debug_buf
205*74242422Sagiri * L1 messages will go to the /var/adm/messages (debug & non-debug).
206*74242422Sagiri * L0 messages will go to console (debug & non-debug).
207b86efd96Sagiri */
208b86efd96Sagiri switch (level) {
209b86efd96Sagiri case RDS_LOG_LINTR:
210b86efd96Sagiri case RDS_LOG_L5:
211b86efd96Sagiri case RDS_LOG_L4:
212b86efd96Sagiri case RDS_LOG_L3:
213b86efd96Sagiri case RDS_LOG_L2:
214b86efd96Sagiri if (!rds_buffer_dprintf) {
215b86efd96Sagiri cmn_err(CE_CONT, "^%s", rds_print_buf);
216b86efd96Sagiri }
217b86efd96Sagiri break;
218b86efd96Sagiri case RDS_LOG_L1:
219b86efd96Sagiri if (!rds_buffer_dprintf) {
220b86efd96Sagiri cmn_err(CE_CONT, "^%s", rds_print_buf);
221*74242422Sagiri } else {
222*74242422Sagiri /* go to messages file */
223*74242422Sagiri cmn_err(CE_CONT, "!%s", rds_print_buf);
224b86efd96Sagiri }
225b86efd96Sagiri break;
226b86efd96Sagiri case RDS_LOG_L0:
227b86efd96Sagiri /* Strip the "\n" added earlier */
228b86efd96Sagiri if (rds_print_buf[len - 1] == '\n') {
229b86efd96Sagiri rds_print_buf[len - 1] = '\0';
230b86efd96Sagiri }
231b86efd96Sagiri if (msg_ptr[len - 1] == '\n') {
232b86efd96Sagiri msg_ptr[len - 1] = '\0';
233b86efd96Sagiri }
234*74242422Sagiri /* go to console */
235*74242422Sagiri cmn_err(CE_CONT, "^%s", rds_print_buf);
236b86efd96Sagiri break;
237b86efd96Sagiri }
238b86efd96Sagiri
239b86efd96Sagiri mutex_exit(&rds_debug_mutex);
240b86efd96Sagiri }
241b86efd96Sagiri
242b86efd96Sagiri void
rds_dprintf_intr(char * name,char * fmt,...)243b86efd96Sagiri rds_dprintf_intr(char *name, char *fmt, ...)
244b86efd96Sagiri {
245b86efd96Sagiri va_list ap;
246b86efd96Sagiri
247b86efd96Sagiri va_start(ap, fmt);
248b86efd96Sagiri rds_vlog(name, RDS_LOG_LINTR, fmt, ap);
249b86efd96Sagiri va_end(ap);
250b86efd96Sagiri }
251b86efd96Sagiri
252b86efd96Sagiri /*
253b86efd96Sagiri * Check individual subsystem err levels
254b86efd96Sagiri */
255b86efd96Sagiri #define RDS_CHECK_ERR_LEVEL(level) \
256b86efd96Sagiri if (rdsdbglvl < level) \
257b86efd96Sagiri return; \
258b86efd96Sagiri
259b86efd96Sagiri void
rds_dprintf5(char * name,char * fmt,...)260b86efd96Sagiri rds_dprintf5(char *name, char *fmt, ...)
261b86efd96Sagiri {
262b86efd96Sagiri va_list ap;
263b86efd96Sagiri
264b86efd96Sagiri RDS_CHECK_ERR_LEVEL(RDS_LOG_L5);
265b86efd96Sagiri
266b86efd96Sagiri va_start(ap, fmt);
267b86efd96Sagiri rds_vlog(name, RDS_LOG_L5, fmt, ap);
268b86efd96Sagiri va_end(ap);
269b86efd96Sagiri }
270b86efd96Sagiri
271b86efd96Sagiri void
rds_dprintf4(char * name,char * fmt,...)272b86efd96Sagiri rds_dprintf4(char *name, char *fmt, ...)
273b86efd96Sagiri {
274b86efd96Sagiri va_list ap;
275b86efd96Sagiri
276b86efd96Sagiri RDS_CHECK_ERR_LEVEL(RDS_LOG_L4);
277b86efd96Sagiri
278b86efd96Sagiri va_start(ap, fmt);
279b86efd96Sagiri rds_vlog(name, RDS_LOG_L4, fmt, ap);
280b86efd96Sagiri va_end(ap);
281b86efd96Sagiri }
282b86efd96Sagiri
283b86efd96Sagiri void
rds_dprintf3(char * name,char * fmt,...)284b86efd96Sagiri rds_dprintf3(char *name, char *fmt, ...)
285b86efd96Sagiri {
286b86efd96Sagiri va_list ap;
287b86efd96Sagiri
288b86efd96Sagiri RDS_CHECK_ERR_LEVEL(RDS_LOG_L3);
289b86efd96Sagiri
290b86efd96Sagiri va_start(ap, fmt);
291b86efd96Sagiri rds_vlog(name, RDS_LOG_L3, fmt, ap);
292b86efd96Sagiri va_end(ap);
293b86efd96Sagiri }
294b86efd96Sagiri
295b86efd96Sagiri void
rds_dprintf2(char * name,char * fmt,...)296b86efd96Sagiri rds_dprintf2(char *name, char *fmt, ...)
297b86efd96Sagiri {
298b86efd96Sagiri va_list ap;
299b86efd96Sagiri
300b86efd96Sagiri RDS_CHECK_ERR_LEVEL(RDS_LOG_L2);
301b86efd96Sagiri
302b86efd96Sagiri va_start(ap, fmt);
303b86efd96Sagiri rds_vlog(name, RDS_LOG_L2, fmt, ap);
304b86efd96Sagiri va_end(ap);
305b86efd96Sagiri }
306b86efd96Sagiri
307b86efd96Sagiri void
rds_dprintf1(char * name,char * fmt,...)308b86efd96Sagiri rds_dprintf1(char *name, char *fmt, ...)
309b86efd96Sagiri {
310b86efd96Sagiri va_list ap;
311b86efd96Sagiri
312b86efd96Sagiri va_start(ap, fmt);
313b86efd96Sagiri rds_vlog(name, RDS_LOG_L1, fmt, ap);
314b86efd96Sagiri va_end(ap);
315b86efd96Sagiri }
316b86efd96Sagiri
317b86efd96Sagiri
318b86efd96Sagiri /*
319b86efd96Sagiri * Function:
320b86efd96Sagiri * rds_dprintf0
321b86efd96Sagiri * Input:
322b86efd96Sagiri * name - Name of the function generating the debug message
323b86efd96Sagiri * fmt - The message to be displayed.
324b86efd96Sagiri * Output:
325b86efd96Sagiri * none
326b86efd96Sagiri * Returns:
327b86efd96Sagiri * none
328b86efd96Sagiri * Description:
329b86efd96Sagiri * A generic log function to display RDS debug messages.
330b86efd96Sagiri */
331b86efd96Sagiri void
rds_dprintf0(char * name,char * fmt,...)332b86efd96Sagiri rds_dprintf0(char *name, char *fmt, ...)
333b86efd96Sagiri {
334b86efd96Sagiri va_list ap;
335b86efd96Sagiri
336b86efd96Sagiri va_start(ap, fmt);
337b86efd96Sagiri rds_vlog(name, RDS_LOG_L0, fmt, ap);
338b86efd96Sagiri va_end(ap);
339b86efd96Sagiri }
340