xref: /onnv-gate/usr/src/cmd/fm/modules/common/disk-monitor/util.c (revision 4582:da3c7347dfa5)
1*4582Scth /*
2*4582Scth  * CDDL HEADER START
3*4582Scth  *
4*4582Scth  * The contents of this file are subject to the terms of the
5*4582Scth  * Common Development and Distribution License (the "License").
6*4582Scth  * You may not use this file except in compliance with the License.
7*4582Scth  *
8*4582Scth  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4582Scth  * or http://www.opensolaris.org/os/licensing.
10*4582Scth  * See the License for the specific language governing permissions
11*4582Scth  * and limitations under the License.
12*4582Scth  *
13*4582Scth  * When distributing Covered Code, include this CDDL HEADER in each
14*4582Scth  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4582Scth  * If applicable, add the following below this CDDL HEADER, with the
16*4582Scth  * fields enclosed by brackets "[]" replaced with your own identifying
17*4582Scth  * information: Portions Copyright [yyyy] [name of copyright owner]
18*4582Scth  *
19*4582Scth  * CDDL HEADER END
20*4582Scth  */
21*4582Scth 
22*4582Scth /*
23*4582Scth  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*4582Scth  * Use is subject to license terms.
25*4582Scth  */
26*4582Scth 
27*4582Scth #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*4582Scth 
29*4582Scth #include <sys/types.h>
30*4582Scth #include <inttypes.h>
31*4582Scth #include <stdio.h>
32*4582Scth #include <stdarg.h>
33*4582Scth #include <ctype.h>
34*4582Scth #include <errno.h>
35*4582Scth #include <string.h>
36*4582Scth #include <stdlib.h>
37*4582Scth #include <pthread.h>
38*4582Scth #include <smbios.h>
39*4582Scth 
40*4582Scth #include <fm/fmd_api.h>
41*4582Scth 
42*4582Scth #include "util.h"
43*4582Scth #include "disk_monitor.h"
44*4582Scth 
45*4582Scth extern log_class_t g_verbose;
46*4582Scth 
47*4582Scth static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
48*4582Scth 
49*4582Scth static void
verror(const char * fmt,va_list ap)50*4582Scth verror(const char *fmt, va_list ap)
51*4582Scth {
52*4582Scth 	int error = errno;
53*4582Scth 
54*4582Scth 	dm_assert(pthread_mutex_lock(&log_mutex) == 0);
55*4582Scth 	fmd_hdl_vdebug(g_fm_hdl, fmt, ap);
56*4582Scth 
57*4582Scth 	if (fmt[strlen(fmt) - 1] != '\n')
58*4582Scth 		fmd_hdl_debug(g_fm_hdl, ": %s\n", strerror(error));
59*4582Scth 
60*4582Scth 	dm_assert(pthread_mutex_unlock(&log_mutex) == 0);
61*4582Scth }
62*4582Scth 
63*4582Scth static void
vwarn_e(const char * fmt,va_list ap)64*4582Scth vwarn_e(const char *fmt, va_list ap)
65*4582Scth {
66*4582Scth 	int error = errno;
67*4582Scth 
68*4582Scth 	dm_assert(pthread_mutex_lock(&log_mutex) == 0);
69*4582Scth 	fmd_hdl_debug(g_fm_hdl, "WARNING: ");
70*4582Scth 	fmd_hdl_vdebug(g_fm_hdl, fmt, ap);
71*4582Scth 
72*4582Scth 	if (fmt[strlen(fmt) - 1] != '\n')
73*4582Scth 		fmd_hdl_debug(g_fm_hdl, ": %s\n", strerror(error));
74*4582Scth 
75*4582Scth 	dm_assert(pthread_mutex_unlock(&log_mutex) == 0);
76*4582Scth }
77*4582Scth 
78*4582Scth static void
vwarn(const char * fmt,va_list ap)79*4582Scth vwarn(const char *fmt, va_list ap)
80*4582Scth {
81*4582Scth 	dm_assert(pthread_mutex_lock(&log_mutex) == 0);
82*4582Scth 	fmd_hdl_debug(g_fm_hdl, "WARNING: ");
83*4582Scth 	fmd_hdl_vdebug(g_fm_hdl, fmt, ap);
84*4582Scth 	dm_assert(pthread_mutex_unlock(&log_mutex) == 0);
85*4582Scth }
86*4582Scth 
87*4582Scth void
vcont(log_class_t cl,const char * fmt,va_list ap)88*4582Scth vcont(log_class_t cl, const char *fmt, va_list ap)
89*4582Scth {
90*4582Scth 	int error = errno;
91*4582Scth 
92*4582Scth 	if ((g_verbose & cl) != cl)
93*4582Scth 		return;
94*4582Scth 
95*4582Scth 	dm_assert(pthread_mutex_lock(&log_mutex) == 0);
96*4582Scth 	fmd_hdl_vdebug(g_fm_hdl, fmt, ap);
97*4582Scth 
98*4582Scth 	if (fmt[strlen(fmt) - 1] != '\n')
99*4582Scth 		fmd_hdl_debug(g_fm_hdl, ": %s\n", strerror(error));
100*4582Scth 
101*4582Scth 	dm_assert(pthread_mutex_unlock(&log_mutex) == 0);
102*4582Scth }
103*4582Scth 
104*4582Scth void
log_msg(log_class_t cl,const char * fmt,...)105*4582Scth log_msg(log_class_t cl, const char *fmt, ...)
106*4582Scth {
107*4582Scth 	va_list ap;
108*4582Scth 
109*4582Scth 	if ((g_verbose & cl) != cl)
110*4582Scth 		return;
111*4582Scth 
112*4582Scth 	dm_assert(pthread_mutex_lock(&log_mutex) == 0);
113*4582Scth 	va_start(ap, fmt);
114*4582Scth 	fmd_hdl_vdebug(g_fm_hdl, fmt, ap);
115*4582Scth 	va_end(ap);
116*4582Scth 	dm_assert(pthread_mutex_unlock(&log_mutex) == 0);
117*4582Scth }
118*4582Scth 
119*4582Scth /*PRINTFLIKE1*/
120*4582Scth void
log_err(const char * fmt,...)121*4582Scth log_err(const char *fmt, ...)
122*4582Scth {
123*4582Scth 	va_list ap;
124*4582Scth 
125*4582Scth 	if ((g_verbose & MM_ERR) != MM_ERR)
126*4582Scth 		return;
127*4582Scth 
128*4582Scth 	va_start(ap, fmt);
129*4582Scth 	verror(fmt, ap);
130*4582Scth 	va_end(ap);
131*4582Scth }
132*4582Scth 
133*4582Scth /*PRINTFLIKE1*/
134*4582Scth void
log_warn(const char * fmt,...)135*4582Scth log_warn(const char *fmt, ...)
136*4582Scth {
137*4582Scth 	va_list ap;
138*4582Scth 
139*4582Scth 	if ((g_verbose & MM_WARN) != MM_WARN)
140*4582Scth 		return;
141*4582Scth 
142*4582Scth 	va_start(ap, fmt);
143*4582Scth 	vwarn(fmt, ap);
144*4582Scth 	va_end(ap);
145*4582Scth }
146*4582Scth 
147*4582Scth /*PRINTFLIKE1*/
148*4582Scth void
log_warn_e(const char * fmt,...)149*4582Scth log_warn_e(const char *fmt, ...)
150*4582Scth {
151*4582Scth 	va_list ap;
152*4582Scth 
153*4582Scth 	if ((g_verbose & MM_WARN) != MM_WARN)
154*4582Scth 		return;
155*4582Scth 
156*4582Scth 	va_start(ap, fmt);
157*4582Scth 	vwarn_e(fmt, ap);
158*4582Scth 	va_end(ap);
159*4582Scth }
160*4582Scth 
161*4582Scth void
dfree(void * p,size_t sz)162*4582Scth dfree(void *p, size_t sz)
163*4582Scth {
164*4582Scth 	fmd_hdl_free(g_fm_hdl, p, sz);
165*4582Scth }
166*4582Scth 
167*4582Scth void
dstrfree(char * s)168*4582Scth dstrfree(char *s)
169*4582Scth {
170*4582Scth 	fmd_hdl_strfree(g_fm_hdl, s);
171*4582Scth }
172*4582Scth 
173*4582Scth void *
dmalloc(size_t sz)174*4582Scth dmalloc(size_t sz)
175*4582Scth {
176*4582Scth 	return (fmd_hdl_alloc(g_fm_hdl, sz, FMD_SLEEP));
177*4582Scth }
178*4582Scth 
179*4582Scth void *
dzmalloc(size_t sz)180*4582Scth dzmalloc(size_t sz)
181*4582Scth {
182*4582Scth 	return (fmd_hdl_zalloc(g_fm_hdl, sz, FMD_SLEEP));
183*4582Scth }
184*4582Scth 
185*4582Scth 
186*4582Scth char *
dstrdup(const char * s)187*4582Scth dstrdup(const char *s)
188*4582Scth {
189*4582Scth 	return (fmd_hdl_strdup(g_fm_hdl, s, FMD_SLEEP));
190*4582Scth }
191*4582Scth 
192*4582Scth void
queue_add(qu_t * qp,void * data)193*4582Scth queue_add(qu_t *qp, void *data)
194*4582Scth {
195*4582Scth 	struct q_node *qnp =
196*4582Scth 	    (struct q_node *)qp->nalloc(sizeof (struct q_node));
197*4582Scth 	struct q_node *nodep;
198*4582Scth 
199*4582Scth 	qnp->data = data;
200*4582Scth 	qnp->next = NULL;
201*4582Scth 	dm_assert(pthread_mutex_lock(&qp->mutex) == 0);
202*4582Scth 
203*4582Scth 	if (qp->nodep == NULL)
204*4582Scth 		qp->nodep = qnp;
205*4582Scth 	else {
206*4582Scth 		nodep = qp->nodep;
207*4582Scth 
208*4582Scth 		while (nodep->next != NULL)
209*4582Scth 			nodep = nodep->next;
210*4582Scth 
211*4582Scth 		nodep->next = qnp;
212*4582Scth 	}
213*4582Scth 
214*4582Scth 	/* If the queue was empty, we need to wake people up */
215*4582Scth 	if (qp->boe && qp->nodep == qnp)
216*4582Scth 		dm_assert(pthread_cond_broadcast(&qp->cvar) == 0);
217*4582Scth 	dm_assert(pthread_mutex_unlock(&qp->mutex) == 0);
218*4582Scth }
219*4582Scth 
220*4582Scth void *
queue_remove(qu_t * qp)221*4582Scth queue_remove(qu_t *qp)
222*4582Scth {
223*4582Scth 	void *rv = NULL;
224*4582Scth 	struct q_node *nextnode;
225*4582Scth 
226*4582Scth 	dm_assert(pthread_mutex_lock(&qp->mutex) == 0);
227*4582Scth 
228*4582Scth 	/* Wait while the queue is empty */
229*4582Scth 	while (qp->boe && qp->nodep == NULL) {
230*4582Scth 		(void) pthread_cond_wait(&qp->cvar, &qp->mutex);
231*4582Scth 	}
232*4582Scth 
233*4582Scth 	/*
234*4582Scth 	 * If Block-On-Empty is false, the queue may be empty
235*4582Scth 	 */
236*4582Scth 	if (qp->nodep != NULL) {
237*4582Scth 		rv = qp->nodep->data;
238*4582Scth 		nextnode = qp->nodep->next;
239*4582Scth 		qp->nfree(qp->nodep, sizeof (struct q_node));
240*4582Scth 		qp->nodep = nextnode;
241*4582Scth 	}
242*4582Scth 
243*4582Scth 	dm_assert(pthread_mutex_unlock(&qp->mutex) == 0);
244*4582Scth 	return (rv);
245*4582Scth }
246*4582Scth 
247*4582Scth qu_t *
new_queue(boolean_t block_on_empty,void * (* nodealloc)(size_t),void (* nodefree)(void *,size_t),void (* data_deallocator)(void *))248*4582Scth new_queue(boolean_t block_on_empty, void *(*nodealloc)(size_t),
249*4582Scth     void (*nodefree)(void *, size_t), void (*data_deallocator)(void *))
250*4582Scth {
251*4582Scth 	qu_t *newqp = (qu_t *)dmalloc(sizeof (qu_t));
252*4582Scth 
253*4582Scth 	newqp->boe = block_on_empty;
254*4582Scth 	newqp->nalloc = nodealloc;
255*4582Scth 	newqp->nfree = nodefree;
256*4582Scth 	newqp->data_dealloc = data_deallocator;
257*4582Scth 	dm_assert(pthread_mutex_init(&newqp->mutex, NULL) == 0);
258*4582Scth 	dm_assert(pthread_cond_init(&newqp->cvar, NULL) == 0);
259*4582Scth 	newqp->nodep = NULL;
260*4582Scth 
261*4582Scth 	return (newqp);
262*4582Scth }
263*4582Scth 
264*4582Scth void
queue_free(qu_t ** qpp)265*4582Scth queue_free(qu_t **qpp)
266*4582Scth {
267*4582Scth 	qu_t *qp = *qpp;
268*4582Scth 	void *item;
269*4582Scth 
270*4582Scth 	dm_assert(pthread_mutex_destroy(&qp->mutex) == 0);
271*4582Scth 	dm_assert(pthread_cond_destroy(&qp->cvar) == 0);
272*4582Scth 
273*4582Scth 	qp->boe = B_FALSE;
274*4582Scth 
275*4582Scth 	while ((item = queue_remove(qp)) != NULL) {
276*4582Scth 		qp->data_dealloc(item);
277*4582Scth 	}
278*4582Scth 
279*4582Scth 	dm_assert(qp->nodep == NULL);
280*4582Scth 
281*4582Scth 	dfree(qp, sizeof (qu_t));
282*4582Scth 	*qpp = NULL;
283*4582Scth }
284*4582Scth 
285*4582Scth int
_dm_assert(const char * assertion,const char * file,int line,const char * func)286*4582Scth _dm_assert(const char *assertion, const char *file, int line, const char *func)
287*4582Scth {
288*4582Scth 	/*
289*4582Scth 	 * No newline is appended to the assertion message so that
290*4582Scth 	 * errno can be translated for us by fmd_hdl_abort().
291*4582Scth 	 */
292*4582Scth 	if (func)
293*4582Scth 		fmd_hdl_abort(g_fm_hdl, "Assertion failed: "
294*4582Scth 		    "%s, file: %s, line: %d, function: %s", assertion, file,
295*4582Scth 		    line, func);
296*4582Scth 	else
297*4582Scth 		fmd_hdl_abort(g_fm_hdl, "Assertion failed: "
298*4582Scth 		    "%s, file: %s, line: %d", assertion, file, line);
299*4582Scth 	/*NOTREACHED*/
300*4582Scth 	return (0);
301*4582Scth }
302