fmd_subr.c revision 1bbdaf51e5a066c12cca745ff7cdd1e08d91b5fa
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <atomic.h>
#include <alloca.h>
#include <syslog.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <exacct.h>
#include <fmd_subr.h>
#include <fmd_conf.h>
#include <fmd_error.h>
#include <fmd_thread.h>
#include <fmd_protocol.h>
#include <fmd_event.h>
#include <fmd_dispq.h>
#include <fmd_log.h>
#include <fmd.h>
struct _rwlock;
struct _lwp_mutex;
int
{
extern int _rw_read_held(struct _rwlock *);
}
int
{
extern int _rw_write_held(struct _rwlock *);
}
int
{
extern int _mutex_held(struct _lwp_mutex *);
}
int
{
/*NOTREACHED*/
return (0);
}
/*
* To implement a reasonable panic() equivalent for fmd, we atomically bump a
* global counter of calls to fmd_vpanic() and attempt to print a panic message
* to stderr and dump core as a result of raising SIGABRT. This function must
* not attempt to grab any locks so that it can be called from any fmd code.
*/
void
{
/*
* If this is not the first call to fmd_vpanic(), then check d_panictid
* to see if we are the panic thread. If so, then proceed directly to
* abort() because we have recursively panicked. If not, then pause()
* indefinitely waiting for the panic thread to terminate the daemon.
*/
(void) pause();
goto abort;
}
/*
* Use fmd.d_pid != 0 as a cheap test to see if fmd.d_key is valid
* (i.e. we're after fmd_create() and before fmd_destroy()).
*/
}
abort();
}
/*PRINTFLIKE1*/
void
{
}
void
{
fmd_event_t *e;
char *class;
tp->thr_errdepth++;
}
}
/*
* If we are at error nesting level one and running in the background,
* log the error as an ereport to our own log and dispatch it. If the
* FMD_LF_BUSY flag is set, we can't attempt to log the event because
* a replay is running and we will deadlock on ourself in log_append.
*/
}
tp->thr_errdepth--;
int core = 0;
if (core)
fmd_panic("forcing core dump at user request\n");
}
}
/*PRINTFLIKE2*/
void
{
}
void
{
char *msg;
char c;
return; /* none of the specified modes are enabled */
if (fmd.d_fmd_dbout == 0)
return; /* no debugging output sinks are enabled */
}
}
}
/*PRINTFLIKE2*/
void
{
}
/*
* The fmd_trace.c routines set tr_file and tr_line to NULL and 0 respectively.
* If they are invoked from a macro (see <fmd_subr.h>) this tail function is
* called as part of the TRACE() macro to fill in these fields from the cpp
* macro values for __FILE__ and __LINE__. No locking is needed because all
* trace buffers are allocated separately for each fmd thread.
*/
void
{
}
}
/*
* The fmd_trace() function is the wrapper for the tracing routines provided in
* fmd_trace.c. It is invoked by the TRACE() macro in <fmd_subr.h>, and uses
* the per-thread trace buffer set up in fmd_thread.c to trace debugging info.
*/
/*PRINTFLIKE2*/
void *
{
void *trp;
return (NULL); /* drop trace record if not ready yet */
return (trp);
}
const char *
fmd_ea_strerror(int err)
{
switch (err) {
case EXR_OK: return ("no exacct error");
case EXR_CORRUPT_FILE: return ("file corruption detected");
case EXR_EOF: return ("end-of-file reached");
case EXR_NO_CREATOR: return ("creator tag mismatch");
case EXR_INVALID_BUF: return ("invalid unpack buffer");
case EXR_NOTSUPP: return ("exacct operation not supported");
case EXR_UNKN_VERSION: return ("unsupported exacct file version");
case EXR_INVALID_OBJ: return ("invalid exacct object");
default: return ("unknown exacct error");
}
}
/*
* Create a local ENA value for fmd-generated ereports. We use ENA Format 1
* with the low bits of gethrtime() and pthread_self() as the processor ID.
*/
fmd_ena(void)
{
}
/*
* fmd_ntz32() computes the number of trailing zeroes. The algorithm here is
* from "Hacker's Delight" by Henry Warren, Jr.
*/
{
uint_t n = 1;
if (x == 0)
return (32);
if ((x & 0xFFFF) == 0) {
n += 16;
x >>= 16;
}
if ((x & 0xFF) == 0) {
n += 8;
x >>= 8;
}
if ((x & 0xF) == 0) {
n += 4;
x >>= 4;
}
if ((x & 0x3) == 0) {
n += 2;
x >>= 2;
}
return (n - (x & 1));
}