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