13302Sagiri /*
23302Sagiri * CDDL HEADER START
33302Sagiri *
43302Sagiri * The contents of this file are subject to the terms of the
53302Sagiri * Common Development and Distribution License (the "License").
63302Sagiri * You may not use this file except in compliance with the License.
73302Sagiri *
83302Sagiri * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93302Sagiri * or http://www.opensolaris.org/os/licensing.
103302Sagiri * See the License for the specific language governing permissions
113302Sagiri * and limitations under the License.
123302Sagiri *
133302Sagiri * When distributing Covered Code, include this CDDL HEADER in each
143302Sagiri * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153302Sagiri * If applicable, add the following below this CDDL HEADER, with the
163302Sagiri * fields enclosed by brackets "[]" replaced with your own identifying
173302Sagiri * information: Portions Copyright [yyyy] [name of copyright owner]
183302Sagiri *
193302Sagiri * CDDL HEADER END
203302Sagiri */
213302Sagiri /*
22*6702Sagiri * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
233302Sagiri * Use is subject to license terms.
243302Sagiri */
253302Sagiri
263302Sagiri #pragma ident "%Z%%M% %I% %E% SMI"
273302Sagiri
283302Sagiri #include <sys/types.h>
293302Sagiri #include <sys/varargs.h>
303302Sagiri #include <sys/cmn_err.h>
313302Sagiri #include <sys/ddi.h>
323302Sagiri #include <sys/sunddi.h>
333302Sagiri #include <sys/ib/clients/rds/rdsib_debug.h>
343302Sagiri
353302Sagiri /*
363302Sagiri * This file contains the debug defines and routines.
373302Sagiri * Debugging information is collected in a circular kernel buffer. Debug
383302Sagiri * messages with level lower than rdsdbglvl are ignored. The size of the
393302Sagiri * of the debug buffer can be changed by setting 'rds_debug_buf_size' in
403302Sagiri * bytes in /etc/system.
413302Sagiri *
423302Sagiri * The debug buffer can be cleared by setting 'rds_clear_debug_buf_flag = 1'
433302Sagiri * on a running system.
443302Sagiri */
453302Sagiri
463302Sagiri #define RDS_DEBUG_SIZE_EXTRA_ALLOC 8
473302Sagiri #define RDS_MIN_DEBUG_BUF_SIZE 0x1000
483302Sagiri #define RDS_FUNCNAME_LEN 40
493302Sagiri #define RDS_PRINTBUF_LEN 4096
503302Sagiri #ifdef DEBUG
513302Sagiri #define RDS_DEBUG_BUF_SIZE 0x10000
523302Sagiri #else
533302Sagiri #define RDS_DEBUG_BUF_SIZE 0x2000
543302Sagiri #endif /* DEBUG */
553302Sagiri
563302Sagiri /* Max length of a debug statement */
573302Sagiri #define RDS_PRINT_BUF_LEN 4096
583302Sagiri
593302Sagiri int rds_suppress_dprintf; /* Suppress debug printing */
603302Sagiri int rds_buffer_dprintf = 1; /* Use debug buffer (0 == console) */
613302Sagiri int rds_debug_buf_size = RDS_DEBUG_BUF_SIZE; /* Sz of Debug buf */
623302Sagiri int rds_allow_intr_msgs = 0; /* log "intr" messages */
633302Sagiri char *rds_debug_buf = NULL; /* The Debug Buf */
643302Sagiri char *rds_buf_sptr, *rds_buf_eptr; /* debug buffer temp pointer */
653302Sagiri int rds_clear_debug_buf_flag = 0; /* Clear debug buffer */
663302Sagiri extern uint_t rdsdbglvl;
673302Sagiri
683302Sagiri /*
693302Sagiri * Print Buffer protected by mutex for debug stuff. The mutex also
703302Sagiri * ensures serializing debug messages.
713302Sagiri */
723302Sagiri static kmutex_t rds_debug_mutex;
733302Sagiri static char rds_print_buf[RDS_PRINT_BUF_LEN];
743302Sagiri
753302Sagiri /* Function Prototypes */
763302Sagiri static void rds_clear_print_buf();
773302Sagiri
783302Sagiri /* RDS logging init */
793302Sagiri void
rds_logging_initialization()803302Sagiri rds_logging_initialization()
813302Sagiri {
823302Sagiri boolean_t flag = B_FALSE;
833302Sagiri
843302Sagiri mutex_init(&rds_debug_mutex, NULL, MUTEX_DRIVER, NULL);
853302Sagiri mutex_enter(&rds_debug_mutex);
863302Sagiri
873302Sagiri if (rds_debug_buf_size <= RDS_DEBUG_SIZE_EXTRA_ALLOC) {
883302Sagiri rds_debug_buf_size = RDS_MIN_DEBUG_BUF_SIZE;
893302Sagiri flag = B_TRUE;
903302Sagiri }
913302Sagiri
923302Sagiri /* if it is less that RDS_MIN_DEBUG_BUF_SIZE, adjust it */
933302Sagiri rds_debug_buf_size = max(RDS_MIN_DEBUG_BUF_SIZE,
943302Sagiri rds_debug_buf_size);
953302Sagiri
963302Sagiri rds_debug_buf = (char *)kmem_alloc(rds_debug_buf_size, KM_SLEEP);
973302Sagiri rds_clear_print_buf();
983302Sagiri mutex_exit(&rds_debug_mutex);
993302Sagiri
1003302Sagiri if (flag == B_TRUE) {
1013302Sagiri RDS_DPRINTF2("RDS", "rds_debug_buf_size was too small, "
1023302Sagiri "adjusted to %x", rds_debug_buf_size);
1033302Sagiri }
1043302Sagiri }
1053302Sagiri
1063302Sagiri
1073302Sagiri /* RDS logging destroy */
1083302Sagiri void
rds_logging_destroy()1093302Sagiri rds_logging_destroy()
1103302Sagiri {
1113302Sagiri mutex_enter(&rds_debug_mutex);
1123302Sagiri if (rds_debug_buf) {
1133302Sagiri kmem_free(rds_debug_buf, rds_debug_buf_size);
1143302Sagiri rds_debug_buf = NULL;
1153302Sagiri }
1163302Sagiri mutex_exit(&rds_debug_mutex);
1173302Sagiri mutex_destroy(&rds_debug_mutex);
1183302Sagiri }
1193302Sagiri
1203302Sagiri
1213302Sagiri /*
1223302Sagiri * debug, log, and console message handling
1233302Sagiri */
1243302Sagiri
1253302Sagiri /*
1263302Sagiri * clear the RDS debug buffer
1273302Sagiri */
1283302Sagiri static void
rds_clear_print_buf()1293302Sagiri rds_clear_print_buf()
1303302Sagiri {
1313302Sagiri ASSERT(MUTEX_HELD(&rds_debug_mutex));
1323302Sagiri if (rds_debug_buf) {
1333302Sagiri rds_buf_sptr = rds_debug_buf;
1343302Sagiri rds_buf_eptr = rds_debug_buf + rds_debug_buf_size -
1353302Sagiri RDS_DEBUG_SIZE_EXTRA_ALLOC;
1363302Sagiri
1373302Sagiri bzero(rds_debug_buf, rds_debug_buf_size);
1383302Sagiri }
1393302Sagiri }
1403302Sagiri
1413302Sagiri
1423302Sagiri static void
rds_vlog(char * name,uint_t level,char * fmt,va_list ap)1433302Sagiri rds_vlog(char *name, uint_t level, char *fmt, va_list ap)
1443302Sagiri {
1453302Sagiri char *label = (name == NULL) ? "rds" : name;
1463302Sagiri char *msg_ptr;
1473302Sagiri size_t len;
1483302Sagiri
1493302Sagiri mutex_enter(&rds_debug_mutex);
1503302Sagiri
1513302Sagiri /* if not using logging scheme; quit */
1523302Sagiri if (rds_suppress_dprintf || (rds_debug_buf == NULL)) {
1533302Sagiri mutex_exit(&rds_debug_mutex);
1543302Sagiri return;
1553302Sagiri }
1563302Sagiri
1573302Sagiri /* If user requests to clear debug buffer, go ahead */
1583302Sagiri if (rds_clear_debug_buf_flag != 0) {
1593302Sagiri rds_clear_print_buf();
1603302Sagiri rds_clear_debug_buf_flag = 0;
1613302Sagiri }
1623302Sagiri
1633302Sagiri /*
1643302Sagiri * put "label" into the buffer
1653302Sagiri */
1663302Sagiri len = snprintf(rds_print_buf, RDS_FUNCNAME_LEN, "%s:\t", label);
1673302Sagiri
1683302Sagiri msg_ptr = rds_print_buf + len;
1693302Sagiri len += vsnprintf(msg_ptr, RDS_PRINT_BUF_LEN - len - 2, fmt, ap);
1703302Sagiri
1713302Sagiri len = min(len, RDS_PRINT_BUF_LEN - 2);
1723302Sagiri ASSERT(len == strlen(rds_print_buf));
1733302Sagiri rds_print_buf[len++] = '\n';
1743302Sagiri rds_print_buf[len] = '\0';
1753302Sagiri
1763302Sagiri /*
1773302Sagiri * stuff the message in the debug buf
1783302Sagiri */
1793302Sagiri if (rds_buffer_dprintf) {
1803302Sagiri
1813302Sagiri /*
1823302Sagiri * overwrite >>>> that might be over the end of the
1833302Sagiri * the buffer
1843302Sagiri */
1853302Sagiri *rds_buf_sptr = '\0';
1863302Sagiri
1873302Sagiri if (rds_buf_sptr + len > rds_buf_eptr) {
1883302Sagiri size_t left = (uintptr_t)rds_buf_eptr -
1893302Sagiri (uintptr_t)rds_buf_sptr;
1903302Sagiri
1913302Sagiri bcopy((caddr_t)rds_print_buf,
192*6702Sagiri (caddr_t)rds_buf_sptr, left);
1933302Sagiri bcopy((caddr_t)rds_print_buf + left,
194*6702Sagiri (caddr_t)rds_debug_buf, len - left);
1953302Sagiri rds_buf_sptr = rds_debug_buf + len - left;
1963302Sagiri } else {
1973302Sagiri bcopy((caddr_t)rds_print_buf, rds_buf_sptr, len);
1983302Sagiri rds_buf_sptr += len;
1993302Sagiri }
2003302Sagiri
2013302Sagiri /* add marker */
2023302Sagiri (void) sprintf(rds_buf_sptr, ">>>>");
2033302Sagiri }
2043302Sagiri
2053302Sagiri /*
2063302Sagiri * LINTR, L5-L2 message may go to the rds_debug_buf
207*6702Sagiri * L1 messages will go to the /var/adm/messages (debug & non-debug).
208*6702Sagiri * L0 messages will go to console (debug & non-debug).
2093302Sagiri */
2103302Sagiri switch (level) {
2113302Sagiri case RDS_LOG_LINTR:
2123302Sagiri case RDS_LOG_L5:
2133302Sagiri case RDS_LOG_L4:
2143302Sagiri case RDS_LOG_L3:
2153302Sagiri case RDS_LOG_L2:
2163302Sagiri if (!rds_buffer_dprintf) {
2173302Sagiri cmn_err(CE_CONT, "^%s", rds_print_buf);
2183302Sagiri }
2193302Sagiri break;
2203302Sagiri case RDS_LOG_L1:
2213302Sagiri if (!rds_buffer_dprintf) {
2223302Sagiri cmn_err(CE_CONT, "^%s", rds_print_buf);
223*6702Sagiri } else {
224*6702Sagiri /* go to messages file */
225*6702Sagiri cmn_err(CE_CONT, "!%s", rds_print_buf);
2263302Sagiri }
2273302Sagiri break;
2283302Sagiri case RDS_LOG_L0:
2293302Sagiri /* Strip the "\n" added earlier */
2303302Sagiri if (rds_print_buf[len - 1] == '\n') {
2313302Sagiri rds_print_buf[len - 1] = '\0';
2323302Sagiri }
2333302Sagiri if (msg_ptr[len - 1] == '\n') {
2343302Sagiri msg_ptr[len - 1] = '\0';
2353302Sagiri }
236*6702Sagiri /* go to console */
237*6702Sagiri cmn_err(CE_CONT, "^%s", rds_print_buf);
2383302Sagiri break;
2393302Sagiri }
2403302Sagiri
2413302Sagiri mutex_exit(&rds_debug_mutex);
2423302Sagiri }
2433302Sagiri
2443302Sagiri void
rds_dprintf_intr(char * name,char * fmt,...)2453302Sagiri rds_dprintf_intr(char *name, char *fmt, ...)
2463302Sagiri {
2473302Sagiri va_list ap;
2483302Sagiri
2493302Sagiri va_start(ap, fmt);
2503302Sagiri rds_vlog(name, RDS_LOG_LINTR, fmt, ap);
2513302Sagiri va_end(ap);
2523302Sagiri }
2533302Sagiri
2543302Sagiri /*
2553302Sagiri * Check individual subsystem err levels
2563302Sagiri */
2573302Sagiri #define RDS_CHECK_ERR_LEVEL(level) \
2583302Sagiri if (rdsdbglvl < level) \
2593302Sagiri return; \
2603302Sagiri
2613302Sagiri void
rds_dprintf5(char * name,char * fmt,...)2623302Sagiri rds_dprintf5(char *name, char *fmt, ...)
2633302Sagiri {
2643302Sagiri va_list ap;
2653302Sagiri
2663302Sagiri RDS_CHECK_ERR_LEVEL(RDS_LOG_L5);
2673302Sagiri
2683302Sagiri va_start(ap, fmt);
2693302Sagiri rds_vlog(name, RDS_LOG_L5, fmt, ap);
2703302Sagiri va_end(ap);
2713302Sagiri }
2723302Sagiri
2733302Sagiri void
rds_dprintf4(char * name,char * fmt,...)2743302Sagiri rds_dprintf4(char *name, char *fmt, ...)
2753302Sagiri {
2763302Sagiri va_list ap;
2773302Sagiri
2783302Sagiri RDS_CHECK_ERR_LEVEL(RDS_LOG_L4);
2793302Sagiri
2803302Sagiri va_start(ap, fmt);
2813302Sagiri rds_vlog(name, RDS_LOG_L4, fmt, ap);
2823302Sagiri va_end(ap);
2833302Sagiri }
2843302Sagiri
2853302Sagiri void
rds_dprintf3(char * name,char * fmt,...)2863302Sagiri rds_dprintf3(char *name, char *fmt, ...)
2873302Sagiri {
2883302Sagiri va_list ap;
2893302Sagiri
2903302Sagiri RDS_CHECK_ERR_LEVEL(RDS_LOG_L3);
2913302Sagiri
2923302Sagiri va_start(ap, fmt);
2933302Sagiri rds_vlog(name, RDS_LOG_L3, fmt, ap);
2943302Sagiri va_end(ap);
2953302Sagiri }
2963302Sagiri
2973302Sagiri void
rds_dprintf2(char * name,char * fmt,...)2983302Sagiri rds_dprintf2(char *name, char *fmt, ...)
2993302Sagiri {
3003302Sagiri va_list ap;
3013302Sagiri
3023302Sagiri RDS_CHECK_ERR_LEVEL(RDS_LOG_L2);
3033302Sagiri
3043302Sagiri va_start(ap, fmt);
3053302Sagiri rds_vlog(name, RDS_LOG_L2, fmt, ap);
3063302Sagiri va_end(ap);
3073302Sagiri }
3083302Sagiri
3093302Sagiri void
rds_dprintf1(char * name,char * fmt,...)3103302Sagiri rds_dprintf1(char *name, char *fmt, ...)
3113302Sagiri {
3123302Sagiri va_list ap;
3133302Sagiri
3143302Sagiri va_start(ap, fmt);
3153302Sagiri rds_vlog(name, RDS_LOG_L1, fmt, ap);
3163302Sagiri va_end(ap);
3173302Sagiri }
3183302Sagiri
3193302Sagiri
3203302Sagiri /*
3213302Sagiri * Function:
3223302Sagiri * rds_dprintf0
3233302Sagiri * Input:
3243302Sagiri * name - Name of the function generating the debug message
3253302Sagiri * fmt - The message to be displayed.
3263302Sagiri * Output:
3273302Sagiri * none
3283302Sagiri * Returns:
3293302Sagiri * none
3303302Sagiri * Description:
3313302Sagiri * A generic log function to display RDS debug messages.
3323302Sagiri */
3333302Sagiri void
rds_dprintf0(char * name,char * fmt,...)3343302Sagiri rds_dprintf0(char *name, char *fmt, ...)
3353302Sagiri {
3363302Sagiri va_list ap;
3373302Sagiri
3383302Sagiri va_start(ap, fmt);
3393302Sagiri rds_vlog(name, RDS_LOG_L0, fmt, ap);
3403302Sagiri va_end(ap);
3413302Sagiri }
342