f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * CDDL HEADER START
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The contents of this file are subject to the terms of the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Common Development and Distribution License (the "License").
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * You may not use this file except in compliance with the License.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * or http://www.opensolaris.org/os/licensing.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * See the License for the specific language governing permissions
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * and limitations under the License.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * When distributing Covered Code, include this CDDL HEADER in each
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If applicable, add the following below this CDDL HEADER, with the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * fields enclosed by brackets "[]" replaced with your own identifying
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * information: Portions Copyright [yyyy] [name of copyright owner]
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * CDDL HEADER END
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Receive (on GPEC channels) raw events published by a few select producers
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * using the private libfmevent publication interfaces, and massage those
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * raw events into full protocol events. Each raw event selects a "ruleset"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * by which to perform the transformation into a protocol event.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Only publication from userland running privileged is supported; two
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * channels are used - one for high-value and one for low-value events.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * There is some planning in the implementation below for kernel hi and low
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * value channels, and for non-privileged userland low and hi value channels.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <fm/fmd_api.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <fm/libfmevent.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <uuid/uuid.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <libsysevent.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <pthread.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <libnvpair.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <strings.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <zone.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include "fmevt.h"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic struct fmevt_inbound_stats {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t raw_callbacks;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t raw_noattrlist;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t raw_nodetector;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t pp_bad_ruleset;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t pp_explicitdrop;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t pp_fallthrurule;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t pp_fanoutmax;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t pp_intldrop;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t pp_badclass;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t pp_nvlallocfail;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t pp_nvlbuildfail;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t pp_badreturn;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_stat_t xprt_posted;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby} inbound_stats = {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "raw_callbacks", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "total raw event callbacks from producers" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "raw_noattrlist", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "missing attribute list" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "raw_nodetector", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "unable to add detector" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "pp_bad_ruleset", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "post-process bad ruleset" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "pp_explicitdrop", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "ruleset drops event with NULL func" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "pp_fanoutmax", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "post-processing produced too many events" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "pp_intldrop", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "post-processing requested event drop" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "pp_badclass", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "post-processing produced invalid event class" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "pp_nvlallocfail", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "fmd_nvl_alloc failed" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "pp_nvlbuildfail", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "nvlist_add_foo failed in building event" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "pp_badreturn", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "inconsistent number of events returned" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "xprt_posted", FMD_TYPE_UINT64,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "protocol events posted with fmd_xprt_post" },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby};
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int isglobalzone;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic char zonename[ZONENAME_MAX];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define BUMPSTAT(stat) inbound_stats.stat.fmds_value.ui64++
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define CBF_USER 0x1U
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define CBF_PRIV 0x2U
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define CBF_LV 0x4U
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define CBF_HV 0x8U
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define CBF_ALL (CBF_USER | CBF_PRIV | CBF_LV | CBF_HV)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic struct fmevt_chaninfo {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const char *ci_propname; /* property to get channel name */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evchan_t *ci_binding; /* GPEC binding for this channel */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char ci_sid[MAX_SUBID_LEN]; /* subscriber id */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint32_t ci_cbarg; /* callback cookie */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint32_t ci_sflags; /* subscription flags to use */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby} chaninfo[] = {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "user_priv_highval_channel", NULL, { 0 },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby CBF_USER | CBF_PRIV | CBF_HV, EVCH_SUB_KEEP },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { "user_priv_lowval_channel", NULL, { 0 },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby CBF_USER | CBF_PRIV | CBF_LV, EVCH_SUB_KEEP },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby};
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic pthread_cond_t fmevt_cv = PTHREAD_COND_INITIALIZER;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic pthread_mutex_t fmevt_lock = PTHREAD_MUTEX_INITIALIZER;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int fmevt_exiting;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic fmd_xprt_t *fmevt_xprt;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic uint32_t fmevt_xprt_refcnt;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic sysevent_subattr_t *subattr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Rulesets we recognize and who handles them. Additions and changes
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * must follow the Portfolio Review process. At ths time only
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * the FMEV_RULESET_ON_SUNOS and FMEVT_RULESET_SMF rulesets are
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * formally recognized by that process - the others here are experimental.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic struct fmevt_rs {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *rs_pat;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmevt_pp_func_t *rs_ppfunc;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *rs_namespace;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *rs_subsys;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby} rulelist[] = {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { FMEV_RULESET_SMF, fmevt_pp_smf },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { FMEV_RULESET_ON_EREPORT, fmevt_pp_on_ereport },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { FMEV_RULESET_ON_SUNOS, fmevt_pp_on_sunos },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { FMEV_RULESET_ON_PRIVATE, fmevt_pp_on_private },
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { FMEV_RULESET_UNREGISTERED, fmevt_pp_unregistered }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby};
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Take a ruleset specification string and separate it into namespace
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * and subsystem components.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyfmevt_rs_burst(fmd_hdl_t *hdl, char *ruleset, char **nsp, char **subsysp,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby boolean_t alloc)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *ns, *s;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby size_t len;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ruleset == NULL || *ruleset == '\0' ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strnlen(ruleset, FMEV_MAX_RULESET_LEN) == FMEV_MAX_RULESET_LEN)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (alloc == B_FALSE) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby s = ruleset;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ns = strsep(&s, FMEV_RS_SEPARATOR);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (s == NULL || s == ns + 1)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((s = strstr(ruleset, FMEV_RS_SEPARATOR)) == NULL ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby s == ruleset + strlen(ruleset) - 1)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby len = s - ruleset;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ns = fmd_hdl_alloc(hdl, len + 1, FMD_SLEEP);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) strncpy(ns, ruleset, len);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ns[len] = '\0';
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby s++;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nsp)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *nsp = ns; /* caller must free if alloc == B_TRUE */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (subsysp)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *subsysp = s; /* always within original ruleset string */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyfmevt_rs_init(fmd_hdl_t *hdl)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int i;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (i = 0; i < sizeof (rulelist) / sizeof (rulelist[0]); i++) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct fmevt_rs *rsp = &rulelist[i];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!fmevt_rs_burst(hdl, rsp->rs_pat, &rsp->rs_namespace,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &rsp->rs_subsys, B_TRUE))
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Construct a "sw" scheme detector FMRI.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * We make no use of priv or pri.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*ARGSUSED3*/
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic nvlist_t *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyfmevt_detector(nvlist_t *attr, char *ruleset, int user, int priv,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_pri_t pri)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char buf[FMEV_MAX_RULESET_LEN + 1];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *ns, *subsys;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t *obj, *dtcr, *site, *ctxt;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *execname = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int32_t i32;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int64_t i64;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int err = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *str;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) strncpy(buf, ruleset, sizeof (buf));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!fmevt_rs_burst(NULL, buf, &ns, &subsys, B_FALSE))
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby obj = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby dtcr = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby site = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ctxt = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (obj == NULL || dtcr == NULL || site == NULL || ctxt == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err++;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Build up 'object' nvlist.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_string(attr, "__fmev_execname", &execname) == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_string(obj, FM_FMRI_SW_OBJ_PATH, execname);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Build up 'site' nvlist. We should have source file and line
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * number and, if the producer was compiled with C99, function name.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_string(attr, "__fmev_file", &str) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_string(site, FM_FMRI_SW_SITE_FILE, str);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) nvlist_remove(attr, "__fmev_file", DATA_TYPE_STRING);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_string(attr, "__fmev_func", &str) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_string(site, FM_FMRI_SW_SITE_FUNC, str);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) nvlist_remove(attr, "__fmev_func", DATA_TYPE_STRING);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_int64(attr, "__fmev_line", &i64) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_int64(site, FM_FMRI_SW_SITE_LINE, i64);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) nvlist_remove(attr, "__fmev_line", DATA_TYPE_INT64);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Build up 'context' nvlist. We do not include contract id at
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * this time.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_string(ctxt, FM_FMRI_SW_CTXT_ORIGIN,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby user ? "userland" : "kernel");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (execname) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_string(ctxt, FM_FMRI_SW_CTXT_EXECNAME,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby execname);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) nvlist_remove(attr, "__fmev_execname", DATA_TYPE_STRING);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_int32(attr, "__fmev_pid", &i32) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_int32(ctxt, FM_FMRI_SW_CTXT_PID, i32);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) nvlist_remove(attr, "__fmev_pid", DATA_TYPE_INT32);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!isglobalzone)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_string(ctxt, FM_FMRI_SW_CTXT_ZONE, zonename);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* Put it all together */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_uint8(dtcr, FM_VERSION, SW_SCHEME_VERSION0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_string(dtcr, FM_FMRI_SCHEME, FM_FMRI_SCHEME_SW);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_nvlist(dtcr, FM_FMRI_SW_OBJ, obj);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_nvlist(dtcr, FM_FMRI_SW_SITE, site);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_nvlist(dtcr, FM_FMRI_SW_CTXT, ctxt);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbydone:
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(obj);
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(site);
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(ctxt);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (err == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (dtcr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_free(dtcr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyclass_ok(char *class)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const char *approved[] = {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby FM_IREPORT_CLASS ".",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby FM_EREPORT_CLASS "."
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int i;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (i = 0; i < sizeof (approved) / sizeof (approved[0]); i++) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (strncmp(class, approved[i], strlen(approved[i])) == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyfmevt_postprocess(char *ruleset, nvlist_t *dtcr, nvlist_t *rawattr,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct fmevt_ppargs *eap)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t expected = 0, processed = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char rs2burst[FMEV_MAX_RULESET_LEN + 1];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *class[FMEVT_FANOUT_MAX];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t *attr[FMEVT_FANOUT_MAX];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmevt_pp_func_t *dispf = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char buf[FMEV_MAX_CLASS];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *ns, *subsys;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int i, found = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uuid_t uu;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) strncpy(rs2burst, ruleset, sizeof (rs2burst));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!fmevt_rs_burst(NULL, rs2burst, &ns, &subsys, B_FALSE)) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(pp_bad_ruleset);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Lookup a matching rule in our table.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (i = 0; i < sizeof (rulelist) / sizeof (rulelist[0]); i++) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct fmevt_rs *rsp = &rulelist[i];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (*ns != '*' && *rsp->rs_namespace != '*' &&
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strcmp(ns, rsp->rs_namespace) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby continue;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (*subsys != '*' && *rsp->rs_subsys != '*' &&
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strcmp(subsys, rsp->rs_subsys) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby continue;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby dispf = rsp->rs_ppfunc;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby found = 1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby break;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If a ruleset matches but specifies a NULL function then
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * it's electing to drop the event. If no rule was matched
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * then default to unregistered processing.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (dispf == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (found) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(pp_explicitdrop);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(pp_fallthrurule);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby dispf = fmevt_pp_unregistered;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Clear the arrays in which class strings and attribute
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * nvlists can be returned. Pass a pointer to our stack buffer
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * that the callee can use for the first event class (for others
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * it must fmd_hdl_alloc and we'll free below). We will free
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * and nvlists that are returned.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby bzero(class, sizeof (class));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby bzero(attr, sizeof (attr));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby class[0] = buf;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Generate an event UUID which will be used for the first
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * event generated by post-processing; if post-processing
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * fans out into more than one event the additional events
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * can reference this uuid (but we don't generate their
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * UUIDs until later).
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uuid_generate(uu);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uuid_unparse(uu, eap->pp_uuidstr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Call selected post-processing function. See block comment
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * in fmevt.h for a description of this process.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby expected = (*dispf)(class, attr, ruleset,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (const nvlist_t *)dtcr, rawattr,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (const struct fmevt_ppargs *)eap);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (expected > FMEVT_FANOUT_MAX) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(pp_fanoutmax);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return; /* without freeing class and nvl - could leak */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (expected == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(pp_intldrop);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Post as many events as the callback completed.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (i = 0; i < FMEVT_FANOUT_MAX; i++) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char uuidstr[36 + 1];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *uuidstrp;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t *nvl;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int err = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (class[i] == NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby continue;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!class_ok(class[i])) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(pp_badclass);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby continue;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (processed++ == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uuidstrp = eap->pp_uuidstr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uuid_generate(uu);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uuid_unparse(uu, uuidstr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uuidstrp = uuidstr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((nvl = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(pp_nvlallocfail);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby continue;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_uint8(nvl, FM_VERSION, 0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_string(nvl, FM_CLASS, (const char *)class[i]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_string(nvl, FM_IREPORT_UUID, uuidstrp);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_nvlist(nvl, FM_IREPORT_DETECTOR, dtcr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_string(nvl, FM_IREPORT_PRIORITY,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_pri_string(eap->pp_pri) ?
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_pri_string(eap->pp_pri) : "?");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (attr[i] != NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err += nvlist_add_nvlist(nvl, FM_IREPORT_ATTRIBUTES,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby attr[i]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If we post the event into fmd_xport_post then the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * transport code is responsible for freeing the nvl we
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * posted.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (err == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_xprt_post(fmevt_hdl, fmevt_xprt, nvl,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby eap->pp_hrt);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(pp_nvlbuildfail);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_free(nvl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (processed != expected)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(pp_badreturn);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (i = 0; i < FMEVT_FANOUT_MAX; i++) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * We provided storage for class[0] but any
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * additional events have allocated a string.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (i > 0 && class[i] != NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_hdl_strfree(fmevt_hdl, class[i]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Free all attribute lists passed in if they are not
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * just a pointer to the raw attributes
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (attr[i] != NULL && attr[i] != rawattr)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_free(attr[i]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyfmevt_cb(sysevent_t *sep, void *arg)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *ruleset = NULL, *rawclass, *rawsubclass;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint32_t cbarg = (uint32_t)arg;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t *rawattr = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct fmevt_ppargs ea;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t *dtcr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int user, priv;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_pri_t pri;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(raw_callbacks);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (cbarg & ~CBF_ALL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_hdl_abort(fmevt_hdl, "event receipt callback with "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "invalid flags\n");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby user = (cbarg & CBF_USER) != 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby priv = (cbarg & CBF_PRIV) != 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby pri = (cbarg & CBF_HV ? FMEV_HIPRI : FMEV_LOPRI);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pthread_mutex_lock(&fmevt_lock);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (fmevt_exiting) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while (fmevt_xprt_refcnt > 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pthread_cond_wait(&fmevt_cv, &fmevt_lock);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pthread_mutex_unlock(&fmevt_lock);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0); /* discard event */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmevt_xprt_refcnt++;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pthread_mutex_unlock(&fmevt_lock);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ruleset = sysevent_get_vendor_name(sep); /* must free */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby rawclass = sysevent_get_class_name(sep); /* valid with sep */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby rawsubclass = sysevent_get_subclass_name(sep); /* valid with sep */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (sysevent_get_attr_list(sep, &rawattr) != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(raw_noattrlist);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((dtcr = fmevt_detector(rawattr, ruleset, user, priv,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby pri)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby BUMPSTAT(raw_nodetector);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ea.pp_rawclass = rawclass;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ea.pp_rawsubclass = rawsubclass;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sysevent_get_time(sep, &ea.pp_hrt);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ea.pp_user = user;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ea.pp_priv = priv;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ea.pp_pri = pri;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmevt_postprocess(ruleset, dtcr, rawattr, &ea);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_free(dtcr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbydone:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pthread_mutex_lock(&fmevt_lock);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (--fmevt_xprt_refcnt == 0 && fmevt_exiting)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pthread_cond_broadcast(&fmevt_cv);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pthread_mutex_unlock(&fmevt_lock);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ruleset)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(ruleset);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(rawattr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0); /* in all cases consider the event delivered */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyfmevt_init_inbound(fmd_hdl_t *hdl)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *sidpfx;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby zoneid_t zoneid;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int i;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!fmevt_rs_init(hdl))
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_hdl_abort(hdl, "error in fmevt_rs_init\n");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fmd_stat_create(hdl, FMD_STAT_NOALLOC, sizeof (inbound_stats) /
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sizeof (fmd_stat_t), (fmd_stat_t *)&inbound_stats);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby zoneid = getzoneid();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby isglobalzone = (zoneid == GLOBAL_ZONEID);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (getzonenamebyid(zoneid, zonename, sizeof (zonename)) == -1)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_hdl_abort(hdl, "getzonenamebyid failed");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((subattr = sysevent_subattr_alloc()) == NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_hdl_abort(hdl, "failed to allocate subscription "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "attributes: %s");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sysevent_subattr_thrcreate(subattr, fmd_doorthr_create, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sysevent_subattr_thrsetup(subattr, fmd_doorthr_setup, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sidpfx = fmd_prop_get_string(hdl, "sidprefix");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmevt_xprt = fmd_xprt_open(hdl, FMD_XPRT_RDONLY, NULL, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (i = 0; i < sizeof (chaninfo) / sizeof (chaninfo[0]); i++) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct fmevt_chaninfo *cip = &chaninfo[i];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *channel = fmd_prop_get_string(hdl, cip->ci_propname);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int err;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (sysevent_evc_bind(channel, &cip->ci_binding,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby EVCH_CREAT | EVCH_HOLD_PEND_INDEF) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_hdl_abort(hdl, "failed to bind GPEC channel for "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "channel %s", channel);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(cip->ci_sid, sizeof (cip->ci_sid),
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "%s_%c%c%c", sidpfx,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby cip->ci_cbarg & CBF_USER ? 'u' : 'k',
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby cip->ci_cbarg & CBF_PRIV ? 'p' : 'n',
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby cip->ci_cbarg & CBF_HV ? 'h' : 'l');
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby err = sysevent_evc_xsubscribe(cip->ci_binding, cip->ci_sid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby EC_ALL, fmevt_cb, (void *)cip->ci_cbarg,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby cip->ci_sflags, subattr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (err == EEXIST)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_hdl_abort(hdl, "another fmd is active on "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "channel %s\n", channel);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else if (err != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_hdl_abort(hdl, "failed to subscribe to channel %s",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby channel);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_prop_free_string(hdl, channel);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_prop_free_string(hdl, sidpfx);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyfmevt_fini_inbound(fmd_hdl_t *hdl)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int i;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (i = 0; i < sizeof (chaninfo) / sizeof (chaninfo[0]); i++) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct fmevt_chaninfo *cip = &chaninfo[i];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (cip->ci_binding) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sysevent_evc_unsubscribe(cip->ci_binding,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby cip->ci_sid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sysevent_evc_unbind(cip->ci_binding);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby cip->ci_binding = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (subattr) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sysevent_subattr_free(subattr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby subattr = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (fmevt_xprt) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /* drain before destruction */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pthread_mutex_lock(&fmevt_lock);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmevt_exiting = 1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while (fmevt_xprt_refcnt > 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pthread_cond_wait(&fmevt_cv, &fmevt_lock);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) pthread_mutex_unlock(&fmevt_lock);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_xprt_close(hdl, fmevt_xprt);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}