view usr/src/uts/common/io/ib/clients/rds/rdsib_debug.c @ 20617:893b1f7b6690

Move everything from /var/adm to /var/log
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Mon, 20 May 2019 12:59:45 -0400
parents 845503cdd0ba
children
line wrap: on
line source

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <sys/types.h>
#include <sys/varargs.h>
#include <sys/cmn_err.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/ib/clients/rds/rdsib_debug.h>

/*
 * This file contains the debug defines and routines.
 * Debugging information is collected in a circular kernel buffer. Debug
 * messages with level lower than rdsdbglvl are ignored. The size of the
 * of the debug buffer can be changed by setting 'rds_debug_buf_size' in
 * bytes in /etc/system.
 *
 * The debug buffer can be cleared by setting 'rds_clear_debug_buf_flag = 1'
 * on a running system.
 */

#define	RDS_DEBUG_SIZE_EXTRA_ALLOC	8
#define	RDS_MIN_DEBUG_BUF_SIZE		0x1000
#define	RDS_FUNCNAME_LEN		40
#define	RDS_PRINTBUF_LEN		4096
#ifdef	DEBUG
#define	RDS_DEBUG_BUF_SIZE		0x10000
#else
#define	RDS_DEBUG_BUF_SIZE		0x2000
#endif	/* DEBUG */

/* Max length of a debug statement */
#define	RDS_PRINT_BUF_LEN	4096

int	rds_suppress_dprintf;		/* Suppress debug printing */
int	rds_buffer_dprintf = 1;		/* Use debug buffer (0 == console) */
int	rds_debug_buf_size = RDS_DEBUG_BUF_SIZE; /* Sz of Debug buf */
int	rds_allow_intr_msgs = 0;	/* log "intr" messages */
char	*rds_debug_buf = NULL;		/* The Debug Buf */
char	*rds_buf_sptr, *rds_buf_eptr;	/* debug buffer temp pointer */
int	rds_clear_debug_buf_flag = 0;	/* Clear debug buffer */
extern uint_t	rdsdbglvl;

/*
 * Print Buffer protected by mutex for debug stuff. The mutex also
 * ensures serializing debug messages.
 */
static kmutex_t	rds_debug_mutex;
static char	rds_print_buf[RDS_PRINT_BUF_LEN];

/* Function Prototypes */
static void	rds_clear_print_buf();

/* RDS logging init */
void
rds_logging_initialization()
{
	boolean_t flag = B_FALSE;

	mutex_init(&rds_debug_mutex, NULL, MUTEX_DRIVER, NULL);
	mutex_enter(&rds_debug_mutex);

	if (rds_debug_buf_size <= RDS_DEBUG_SIZE_EXTRA_ALLOC) {
		rds_debug_buf_size = RDS_MIN_DEBUG_BUF_SIZE;
		flag = B_TRUE;
	}

	/* if it is less that RDS_MIN_DEBUG_BUF_SIZE, adjust it */
	rds_debug_buf_size = max(RDS_MIN_DEBUG_BUF_SIZE,
	    rds_debug_buf_size);

	rds_debug_buf = kmem_alloc(rds_debug_buf_size, KM_SLEEP);
	rds_clear_print_buf();
	mutex_exit(&rds_debug_mutex);

	if (flag == B_TRUE) {
		RDS_DPRINTF2("RDS", "rds_debug_buf_size was too small, "
		    "adjusted to %x", rds_debug_buf_size);
	}
}


/* RDS logging destroy */
void
rds_logging_destroy()
{
	mutex_enter(&rds_debug_mutex);
	if (rds_debug_buf) {
		kmem_free(rds_debug_buf, rds_debug_buf_size);
		rds_debug_buf = NULL;
	}
	mutex_exit(&rds_debug_mutex);
	mutex_destroy(&rds_debug_mutex);
}


/*
 * debug, log, and console message handling
 */

/*
 * clear the RDS debug buffer
 */
static void
rds_clear_print_buf()
{
	ASSERT(MUTEX_HELD(&rds_debug_mutex));
	if (rds_debug_buf) {
		rds_buf_sptr = rds_debug_buf;
		rds_buf_eptr = rds_debug_buf + rds_debug_buf_size -
		    RDS_DEBUG_SIZE_EXTRA_ALLOC;

		bzero(rds_debug_buf, rds_debug_buf_size);
	}
}


static void
rds_vlog(char *name, uint_t level, char *fmt, va_list ap)
{
	char	*label = (name == NULL) ? "rds" : name;
	char	*msg_ptr;
	size_t	len;

	mutex_enter(&rds_debug_mutex);

	/* if not using logging scheme; quit */
	if (rds_suppress_dprintf || (rds_debug_buf == NULL)) {
		mutex_exit(&rds_debug_mutex);
		return;
	}

	/* If user requests to clear debug buffer, go ahead */
	if (rds_clear_debug_buf_flag != 0) {
		rds_clear_print_buf();
		rds_clear_debug_buf_flag = 0;
	}

	/*
	 * put "label" into the buffer
	 */
	len = snprintf(rds_print_buf, RDS_FUNCNAME_LEN, "%s:\t", label);

	msg_ptr = rds_print_buf + len;
	len += vsnprintf(msg_ptr, RDS_PRINT_BUF_LEN - len - 2, fmt, ap);

	len = min(len, RDS_PRINT_BUF_LEN - 2);
	ASSERT(len == strlen(rds_print_buf));
	rds_print_buf[len++] = '\n';
	rds_print_buf[len] = '\0';

	/*
	 * stuff the message in the debug buf
	 */
	if (rds_buffer_dprintf) {

		/*
		 * overwrite >>>> that might be over the end of the
		 * the buffer
		 */
		*rds_buf_sptr = '\0';

		if (rds_buf_sptr + len > rds_buf_eptr) {
			size_t left = (uintptr_t)rds_buf_eptr -
			    (uintptr_t)rds_buf_sptr;

			bcopy((caddr_t)rds_print_buf,
			    (caddr_t)rds_buf_sptr, left);
			bcopy((caddr_t)rds_print_buf + left,
			    (caddr_t)rds_debug_buf, len - left);
			rds_buf_sptr = rds_debug_buf + len - left;
		} else {
			bcopy((caddr_t)rds_print_buf, rds_buf_sptr, len);
			rds_buf_sptr += len;
		}

		/* add marker */
		(void) sprintf(rds_buf_sptr, ">>>>");
	}

	/*
	 * LINTR, L5-L2 message may go to the rds_debug_buf
	 * L1 messages will go to the /var/log/messages (debug & non-debug).
	 * L0 messages will go to console (debug & non-debug).
	 */
	switch (level) {
	case RDS_LOG_LINTR:
	case RDS_LOG_L5:
	case RDS_LOG_L4:
	case RDS_LOG_L3:
	case RDS_LOG_L2:
		if (!rds_buffer_dprintf) {
			cmn_err(CE_CONT, "^%s", rds_print_buf);
		}
		break;
	case RDS_LOG_L1:
		if (!rds_buffer_dprintf) {
			cmn_err(CE_CONT, "^%s", rds_print_buf);
		} else {
			/* go to messages file */
			cmn_err(CE_CONT, "!%s", rds_print_buf);
		}
		break;
	case RDS_LOG_L0:
		/* Strip the "\n" added earlier */
		if (rds_print_buf[len - 1] == '\n') {
			rds_print_buf[len - 1] = '\0';
		}
		if (msg_ptr[len - 1] == '\n') {
			msg_ptr[len - 1] = '\0';
		}
		/* go to console */
		cmn_err(CE_CONT, "^%s", rds_print_buf);
		break;
	}

	mutex_exit(&rds_debug_mutex);
}

void
rds_dprintf_intr(char *name, char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	rds_vlog(name, RDS_LOG_LINTR, fmt, ap);
	va_end(ap);
}

/*
 * Check individual subsystem err levels
 */
#define	RDS_CHECK_ERR_LEVEL(level)		\
	if (rdsdbglvl < level)			\
		return;				\

void
rds_dprintf5(char *name, char *fmt, ...)
{
	va_list ap;

	RDS_CHECK_ERR_LEVEL(RDS_LOG_L5);

	va_start(ap, fmt);
	rds_vlog(name, RDS_LOG_L5, fmt, ap);
	va_end(ap);
}

void
rds_dprintf4(char *name, char *fmt, ...)
{
	va_list ap;

	RDS_CHECK_ERR_LEVEL(RDS_LOG_L4);

	va_start(ap, fmt);
	rds_vlog(name, RDS_LOG_L4, fmt, ap);
	va_end(ap);
}

void
rds_dprintf3(char *name, char *fmt, ...)
{
	va_list ap;

	RDS_CHECK_ERR_LEVEL(RDS_LOG_L3);

	va_start(ap, fmt);
	rds_vlog(name, RDS_LOG_L3, fmt, ap);
	va_end(ap);
}

void
rds_dprintf2(char *name, char *fmt, ...)
{
	va_list ap;

	RDS_CHECK_ERR_LEVEL(RDS_LOG_L2);

	va_start(ap, fmt);
	rds_vlog(name, RDS_LOG_L2, fmt, ap);
	va_end(ap);
}

void
rds_dprintf1(char *name, char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	rds_vlog(name, RDS_LOG_L1, fmt, ap);
	va_end(ap);
}


/*
 * Function:
 *      rds_dprintf0
 * Input:
 *      name	- Name of the function generating the debug message
 *  	fmt	- The message to be displayed.
 * Output:
 *      none
 * Returns:
 *      none
 * Description:
 *  	A generic log function to display RDS debug messages.
 */
void
rds_dprintf0(char *name, char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	rds_vlog(name, RDS_LOG_L0, fmt, ap);
	va_end(ap);
}