/*
* 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
* 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
*/
/*
*/
/*
* FMA event subscription interfaces - subscribe to FMA protocol
* from outside the fault manager.
*/
#include <atomic.h>
#include <libsysevent.h>
#include <libuutil.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <fm/libfmevent.h>
#include "fmev_impl.h"
typedef struct {
/*
* For each subscription on a handle we add a node to an avl tree
* to track subscriptions.
*/
struct fmev_subinfo {
void *si_cbarg;
};
struct fmev_hdl_cmn *
{
}
static int
{
return (1); /* lock still held */
} else {
return (0);
}
}
static void
{
}
{
return (fmev_errno);
if (!shdlctl_start(ihdl))
return (fmev_seterr(FMEVERR_BUSY));
}
return (fmev_seterr(FMEV_SUCCESS));
}
{
return (fmev_errno);
if (!shdlctl_start(ihdl))
return (fmev_seterr(FMEVERR_BUSY));
return (fmev_seterr(FMEV_SUCCESS));
}
{
return (fmev_errno);
if (!shdlctl_start(ihdl))
return (fmev_seterr(FMEVERR_BUSY));
return (fmev_seterr(FMEV_SUCCESS));
}
void *cookie)
{
return (fmev_errno);
if (!shdlctl_start(ihdl))
return (fmev_seterr(FMEVERR_BUSY));
return (fmev_seterr(FMEV_SUCCESS));
}
void *cookie)
{
return (fmev_errno);
if (!shdlctl_start(ihdl))
return (fmev_seterr(FMEVERR_BUSY));
return (fmev_seterr(FMEV_SUCCESS));
}
/*
* Our door service function. We return 0 regardless so that the kernel
* does not keep either retrying (EAGAIN) or bleat to cmn_err.
*/
int
{
char *class;
return (0);
}
return (0);
}
return (0);
}
void *funcarg)
{
int serr;
return (fmev_errno);
return (fmev_seterr(FMEVERR_API));
/*
* Empty class patterns are illegal, as is the sysevent magic for
* all classes. Also validate class length.
*/
return (fmev_seterr(FMEVERR_BADCLASS));
return (fmev_seterr(FMEVERR_ALLOC));
return (fmev_seterr(FMEVERR_DUPLICATE));
}
/*
* Generate a subscriber id for GPEC that is unique to this
* subscription. There is no provision for persistent
* subscribers. The subscriber id must be unique within
* this zone.
*/
switch (serr) {
case ENOMEM:
break;
default:
break;
}
return (fmev_seterr(err));
}
return (fmev_seterr(FMEV_SUCCESS));
}
static int
{
int err;
if (err == 0) {
if (doavl) {
}
}
return (err);
}
{
int err;
return (fmev_errno);
return (fmev_seterr(FMEVERR_API));
return (fmev_seterr(FMEVERR_BADCLASS));
rv = FMEV_SUCCESS;
} else {
/*
* Return an API error if the unsubscribe was
* attempted from within a door callback invocation;
* other errors should not happen.
*/
}
}
return (fmev_seterr(rv));
}
void *
{
return (NULL);
}
void *
{
return (NULL);
}
void
{
return;
}
char *
{
char *dst;
return (NULL);
(void) fmev_seterr(FMEVERR_ALLOC);
return (NULL);
}
return (dst);
}
void
{
}
int
{
}
/*ARGSUSED*/
static int
{
}
{
const char *chan_name;
int err;
if (!fmev_api_init(&hc))
return (NULL); /* error type set */
(void) fmev_seterr(FMEVERR_API);
return (NULL);
}
else
(void) fmev_seterr(FMEVERR_ALLOC);
return (NULL);
}
err = FMEVERR_ALLOC;
goto error;
}
/*
* For simulation purposes we allow an environment variable
* to provide a different channel name.
*/
/*
* Try to bind to the event channel. If it's not already present,
* attempt to create the channel so that we can startup before
* the event producer (who will also apply choices such as
* channel depth when they bind to the channel).
*/
EVCH_CREAT | EVCH_HOLD_PEND_INDEF) != 0) {
switch (errno) {
case EINVAL:
default:
break;
case ENOMEM:
err = FMEVERR_ALLOC;
break;
case EPERM:
break;
}
goto error;
}
sizeof (struct fmev_subinfo),
UU_AVL_POOL_DEBUG)) == NULL) {
goto error;
}
UU_DEFAULT)) == NULL) {
goto error;
}
(void) fmev_seterr(err);
return (NULL);
}
{
return (fmev_errno);
return (fmev_seterr(FMEVERR_UNKNOWN));
}
} else {
} else {
}
}
if (rc != FMEV_SUCCESS) {
(void) fmev_seterr(rc);
}
return (rc);
}
char *
{
int topoerr;
return (NULL);
(void) fmev_seterr(FMEVERR_INTERNAL);
return (NULL);
}
}
return (fmricp); /* fmev_errno set if strdup failed */
}
switch (topoerr) {
case ETOPO_FMRI_NOMEM:
err = FMEVERR_ALLOC;
break;
case ETOPO_FMRI_MALFORM:
case ETOPO_METHOD_NOTSUP:
case ETOPO_METHOD_INVAL:
default:
break;
}
(void) fmev_seterr(err);
return (NULL);
}
{
return (fmev_errno);
/*
* Verify that we are not in callback context - return an API
* error if we are.
*/
EDEADLK) {
return (fmev_seterr(FMEVERR_API));
}
}
if (ihdl->sh_binding) {
}
}
}
if (g_topohdl) {
}
return (fmev_seterr(FMEV_SUCCESS));
}