1*f6e214c7SGavin Maltby /*
2*f6e214c7SGavin Maltby * CDDL HEADER START
3*f6e214c7SGavin Maltby *
4*f6e214c7SGavin Maltby * The contents of this file are subject to the terms of the
5*f6e214c7SGavin Maltby * Common Development and Distribution License (the "License").
6*f6e214c7SGavin Maltby * You may not use this file except in compliance with the License.
7*f6e214c7SGavin Maltby *
8*f6e214c7SGavin Maltby * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*f6e214c7SGavin Maltby * or http://www.opensolaris.org/os/licensing.
10*f6e214c7SGavin Maltby * See the License for the specific language governing permissions
11*f6e214c7SGavin Maltby * and limitations under the License.
12*f6e214c7SGavin Maltby *
13*f6e214c7SGavin Maltby * When distributing Covered Code, include this CDDL HEADER in each
14*f6e214c7SGavin Maltby * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*f6e214c7SGavin Maltby * If applicable, add the following below this CDDL HEADER, with the
16*f6e214c7SGavin Maltby * fields enclosed by brackets "[]" replaced with your own identifying
17*f6e214c7SGavin Maltby * information: Portions Copyright [yyyy] [name of copyright owner]
18*f6e214c7SGavin Maltby *
19*f6e214c7SGavin Maltby * CDDL HEADER END
20*f6e214c7SGavin Maltby */
21*f6e214c7SGavin Maltby
22*f6e214c7SGavin Maltby /*
23*f6e214c7SGavin Maltby * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*f6e214c7SGavin Maltby */
25*f6e214c7SGavin Maltby
26*f6e214c7SGavin Maltby #include <strings.h>
27*f6e214c7SGavin Maltby #include <libscf.h>
28*f6e214c7SGavin Maltby #include <fm/fmd_api.h>
29*f6e214c7SGavin Maltby #include <fm/libtopo.h>
30*f6e214c7SGavin Maltby #include <fm/libfmevent.h>
31*f6e214c7SGavin Maltby
32*f6e214c7SGavin Maltby #include "fmevt.h"
33*f6e214c7SGavin Maltby
34*f6e214c7SGavin Maltby /*
35*f6e214c7SGavin Maltby * Post-processing according to the FMEV_RULESET_SMF ruleset.
36*f6e214c7SGavin Maltby *
37*f6e214c7SGavin Maltby * Raw event we expect:
38*f6e214c7SGavin Maltby *
39*f6e214c7SGavin Maltby * ==========================================================================
40*f6e214c7SGavin Maltby * Class: "state-transition"
41*f6e214c7SGavin Maltby * Subclasses: The new state, one of SCF_STATE_STRING_* from libscf.h
42*f6e214c7SGavin Maltby * Attr:
43*f6e214c7SGavin Maltby * Name DATA_TYPE_* Description
44*f6e214c7SGavin Maltby * ------------ --------------- ---------------------------------------------
45*f6e214c7SGavin Maltby * fmri STRING svc:/... (svc scheme shorthand version)
46*f6e214c7SGavin Maltby * transition INT32 (old_state << 16) | new_state
47*f6e214c7SGavin Maltby * reason-version UINT32 reason-short namespace version
48*f6e214c7SGavin Maltby * reason-short STRING Short/keyword reason for transition
49*f6e214c7SGavin Maltby * reason-long STRING Long-winded reason for the transition
50*f6e214c7SGavin Maltby * ==========================================================================
51*f6e214c7SGavin Maltby *
52*f6e214c7SGavin Maltby * Protocol event components we return:
53*f6e214c7SGavin Maltby *
54*f6e214c7SGavin Maltby * ==========================================================================
55*f6e214c7SGavin Maltby * Class: ireport.os.smf.state-transition.<new-state>
56*f6e214c7SGavin Maltby * Attr:
57*f6e214c7SGavin Maltby * Name DATA_TYPE_* Description
58*f6e214c7SGavin Maltby * ------------ --------------- ----------------------------------------
59*f6e214c7SGavin Maltby * svc NVLIST "svc" scheme FMRI of affected service instance
60*f6e214c7SGavin Maltby * svc-string STRING SMF FMRI in short string form svc:/foo/bar
61*f6e214c7SGavin Maltby * from-state STRING Previous state; SCF_STATE_STRING_*
62*f6e214c7SGavin Maltby * to-state STRING New state; SCF_STATE_STRING_*
63*f6e214c7SGavin Maltby * reason-version UINT32 reason-short namespace version
64*f6e214c7SGavin Maltby * reason-short STRING Short/keyword reason for transition
65*f6e214c7SGavin Maltby * reason-long STRING Long-winded reason for the transition
66*f6e214c7SGavin Maltby * ==========================================================================
67*f6e214c7SGavin Maltby */
68*f6e214c7SGavin Maltby
69*f6e214c7SGavin Maltby /*
70*f6e214c7SGavin Maltby * svc.startd generates events using the FMRI shorthand (svc:/foo/bar)
71*f6e214c7SGavin Maltby * instead of the standard form (svc:///foo/bar). This function converts to
72*f6e214c7SGavin Maltby * the standard representation. The caller must free the allocated string.
73*f6e214c7SGavin Maltby */
74*f6e214c7SGavin Maltby static char *
shortfmri_to_fmristr(fmd_hdl_t * hdl,const char * shortfmristr)75*f6e214c7SGavin Maltby shortfmri_to_fmristr(fmd_hdl_t *hdl, const char *shortfmristr)
76*f6e214c7SGavin Maltby {
77*f6e214c7SGavin Maltby size_t len;
78*f6e214c7SGavin Maltby char *fmristr;
79*f6e214c7SGavin Maltby
80*f6e214c7SGavin Maltby if (strncmp(shortfmristr, "svc:/", 5) != 0)
81*f6e214c7SGavin Maltby return (NULL);
82*f6e214c7SGavin Maltby
83*f6e214c7SGavin Maltby len = strlen(shortfmristr) + 3;
84*f6e214c7SGavin Maltby fmristr = fmd_hdl_alloc(hdl, len, FMD_SLEEP);
85*f6e214c7SGavin Maltby (void) snprintf(fmristr, len, "svc:///%s", shortfmristr + 5);
86*f6e214c7SGavin Maltby
87*f6e214c7SGavin Maltby return (fmristr);
88*f6e214c7SGavin Maltby }
89*f6e214c7SGavin Maltby
90*f6e214c7SGavin Maltby /*
91*f6e214c7SGavin Maltby * Convert a shorthand svc FMRI into a full svc FMRI nvlist
92*f6e214c7SGavin Maltby */
93*f6e214c7SGavin Maltby static nvlist_t *
shortfmri_to_fmri(fmd_hdl_t * hdl,const char * shortfmristr)94*f6e214c7SGavin Maltby shortfmri_to_fmri(fmd_hdl_t *hdl, const char *shortfmristr)
95*f6e214c7SGavin Maltby {
96*f6e214c7SGavin Maltby nvlist_t *ret, *fmri;
97*f6e214c7SGavin Maltby topo_hdl_t *thp;
98*f6e214c7SGavin Maltby char *fmristr;
99*f6e214c7SGavin Maltby int err;
100*f6e214c7SGavin Maltby
101*f6e214c7SGavin Maltby if ((fmristr = shortfmri_to_fmristr(hdl, shortfmristr)) == NULL)
102*f6e214c7SGavin Maltby return (NULL);
103*f6e214c7SGavin Maltby
104*f6e214c7SGavin Maltby thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION);
105*f6e214c7SGavin Maltby
106*f6e214c7SGavin Maltby if (topo_fmri_str2nvl(thp, fmristr, &fmri, &err) != 0) {
107*f6e214c7SGavin Maltby fmd_hdl_error(hdl, "failed to convert '%s' to nvlist\n",
108*f6e214c7SGavin Maltby fmristr);
109*f6e214c7SGavin Maltby fmd_hdl_strfree(hdl, fmristr);
110*f6e214c7SGavin Maltby fmd_hdl_topo_rele(hdl, thp);
111*f6e214c7SGavin Maltby return (NULL);
112*f6e214c7SGavin Maltby }
113*f6e214c7SGavin Maltby
114*f6e214c7SGavin Maltby fmd_hdl_strfree(hdl, fmristr);
115*f6e214c7SGavin Maltby
116*f6e214c7SGavin Maltby if ((ret = fmd_nvl_dup(hdl, fmri, FMD_SLEEP)) == NULL) {
117*f6e214c7SGavin Maltby fmd_hdl_error(hdl, "failed to dup fmri\n");
118*f6e214c7SGavin Maltby nvlist_free(fmri);
119*f6e214c7SGavin Maltby fmd_hdl_topo_rele(hdl, thp);
120*f6e214c7SGavin Maltby return (NULL);
121*f6e214c7SGavin Maltby }
122*f6e214c7SGavin Maltby
123*f6e214c7SGavin Maltby nvlist_free(fmri);
124*f6e214c7SGavin Maltby fmd_hdl_topo_rele(hdl, thp);
125*f6e214c7SGavin Maltby
126*f6e214c7SGavin Maltby return (ret);
127*f6e214c7SGavin Maltby }
128*f6e214c7SGavin Maltby
129*f6e214c7SGavin Maltby /*ARGSUSED*/
130*f6e214c7SGavin Maltby uint_t
fmevt_pp_smf(char * classes[FMEVT_FANOUT_MAX],nvlist_t * attr[FMEVT_FANOUT_MAX],const char * ruleset,const nvlist_t * detector,nvlist_t * rawattr,const struct fmevt_ppargs * eap)131*f6e214c7SGavin Maltby fmevt_pp_smf(char *classes[FMEVT_FANOUT_MAX],
132*f6e214c7SGavin Maltby nvlist_t *attr[FMEVT_FANOUT_MAX], const char *ruleset,
133*f6e214c7SGavin Maltby const nvlist_t *detector, nvlist_t *rawattr,
134*f6e214c7SGavin Maltby const struct fmevt_ppargs *eap)
135*f6e214c7SGavin Maltby {
136*f6e214c7SGavin Maltby int32_t transition, from, to;
137*f6e214c7SGavin Maltby const char *fromstr, *tostr;
138*f6e214c7SGavin Maltby char *svcname, *rsn, *rsnl;
139*f6e214c7SGavin Maltby nvlist_t *myattr;
140*f6e214c7SGavin Maltby nvlist_t *fmri;
141*f6e214c7SGavin Maltby uint32_t ver;
142*f6e214c7SGavin Maltby
143*f6e214c7SGavin Maltby if (!fmd_prop_get_int32(fmevt_hdl, "inbound_postprocess_smf"))
144*f6e214c7SGavin Maltby return (0);
145*f6e214c7SGavin Maltby
146*f6e214c7SGavin Maltby if (rawattr == NULL ||
147*f6e214c7SGavin Maltby strcmp(eap->pp_rawclass, "state-transition") != 0 ||
148*f6e214c7SGavin Maltby nvlist_lookup_string(rawattr, "fmri", &svcname) != 0 ||
149*f6e214c7SGavin Maltby nvlist_lookup_int32(rawattr, "transition", &transition) != 0 ||
150*f6e214c7SGavin Maltby nvlist_lookup_string(rawattr, "reason-short", &rsn) != 0 ||
151*f6e214c7SGavin Maltby nvlist_lookup_string(rawattr, "reason-long", &rsnl) != 0 ||
152*f6e214c7SGavin Maltby nvlist_lookup_uint32(rawattr, "reason-version", &ver) != 0)
153*f6e214c7SGavin Maltby return (0);
154*f6e214c7SGavin Maltby
155*f6e214c7SGavin Maltby from = transition >> 16;
156*f6e214c7SGavin Maltby to = transition & 0xffff;
157*f6e214c7SGavin Maltby
158*f6e214c7SGavin Maltby fromstr = smf_state_to_string(from);
159*f6e214c7SGavin Maltby tostr = smf_state_to_string(to);
160*f6e214c7SGavin Maltby
161*f6e214c7SGavin Maltby if (fromstr == NULL || tostr == NULL)
162*f6e214c7SGavin Maltby return (0);
163*f6e214c7SGavin Maltby
164*f6e214c7SGavin Maltby if (strcmp(eap->pp_rawsubclass, tostr) != 0)
165*f6e214c7SGavin Maltby return (0);
166*f6e214c7SGavin Maltby
167*f6e214c7SGavin Maltby if ((fmri = shortfmri_to_fmri(fmevt_hdl, svcname)) == NULL)
168*f6e214c7SGavin Maltby return (0);
169*f6e214c7SGavin Maltby
170*f6e214c7SGavin Maltby if (snprintf(classes[0], FMEVT_MAX_CLASS, "%s.%s.%s.%s",
171*f6e214c7SGavin Maltby FM_IREPORT_CLASS, "os.smf", eap->pp_rawclass,
172*f6e214c7SGavin Maltby eap->pp_rawsubclass) >= FMEVT_MAX_CLASS - 1)
173*f6e214c7SGavin Maltby return (0);
174*f6e214c7SGavin Maltby
175*f6e214c7SGavin Maltby if ((myattr = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP)) == NULL)
176*f6e214c7SGavin Maltby return (0);
177*f6e214c7SGavin Maltby
178*f6e214c7SGavin Maltby if (nvlist_add_nvlist(myattr, "svc", fmri) != 0 ||
179*f6e214c7SGavin Maltby nvlist_add_string(myattr, "svc-string", svcname) != 0 ||
180*f6e214c7SGavin Maltby nvlist_add_string(myattr, "from-state", fromstr) != 0 ||
181*f6e214c7SGavin Maltby nvlist_add_string(myattr, "to-state", tostr) != 0 ||
182*f6e214c7SGavin Maltby nvlist_add_uint32(myattr, "reason-version", ver) != 0 ||
183*f6e214c7SGavin Maltby nvlist_add_string(myattr, "reason-short", rsn) != 0 ||
184*f6e214c7SGavin Maltby nvlist_add_string(myattr, "reason-long", rsnl) != 0) {
185*f6e214c7SGavin Maltby nvlist_free(fmri);
186*f6e214c7SGavin Maltby nvlist_free(myattr);
187*f6e214c7SGavin Maltby return (0);
188*f6e214c7SGavin Maltby }
189*f6e214c7SGavin Maltby
190*f6e214c7SGavin Maltby attr[0] = myattr;
191*f6e214c7SGavin Maltby nvlist_free(fmri);
192*f6e214c7SGavin Maltby
193*f6e214c7SGavin Maltby return (1);
194*f6e214c7SGavin Maltby }
195