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 <libintl.h>
27*f6e214c7SGavin Maltby #include <libnvpair.h>
28*f6e214c7SGavin Maltby #include <libscf.h>
29*f6e214c7SGavin Maltby #include <libscf_priv.h>
30*f6e214c7SGavin Maltby #include <libuutil.h>
31*f6e214c7SGavin Maltby #include <stdarg.h>
32*f6e214c7SGavin Maltby #include <stdio.h>
33*f6e214c7SGavin Maltby #include <string.h>
34*f6e214c7SGavin Maltby
35*f6e214c7SGavin Maltby #include "notify_params.h"
36*f6e214c7SGavin Maltby
37*f6e214c7SGavin Maltby static struct events {
38*f6e214c7SGavin Maltby const char *s;
39*f6e214c7SGavin Maltby int32_t c;
40*f6e214c7SGavin Maltby } smf_st_events[] = {
41*f6e214c7SGavin Maltby { "to-uninitialized", SCF_TRANS(0, SCF_STATE_UNINIT) },
42*f6e214c7SGavin Maltby { "from-uninitialized", SCF_TRANS(SCF_STATE_UNINIT, 0) },
43*f6e214c7SGavin Maltby { "uninitialized", SCF_TRANS(SCF_STATE_UNINIT, SCF_STATE_UNINIT) },
44*f6e214c7SGavin Maltby { "to-maintenance", SCF_TRANS(0, SCF_STATE_MAINT) },
45*f6e214c7SGavin Maltby { "from-maintenance", SCF_TRANS(SCF_STATE_MAINT, 0) },
46*f6e214c7SGavin Maltby { "maintenance", SCF_TRANS(SCF_STATE_MAINT, SCF_STATE_MAINT) },
47*f6e214c7SGavin Maltby { "to-offline", SCF_TRANS(0, SCF_STATE_OFFLINE) },
48*f6e214c7SGavin Maltby { "from-offline", SCF_TRANS(SCF_STATE_OFFLINE, 0) },
49*f6e214c7SGavin Maltby { "offline", SCF_TRANS(SCF_STATE_OFFLINE, SCF_STATE_OFFLINE) },
50*f6e214c7SGavin Maltby { "to-disabled", SCF_TRANS(0, SCF_STATE_DISABLED) },
51*f6e214c7SGavin Maltby { "from-disabled", SCF_TRANS(SCF_STATE_DISABLED, 0) },
52*f6e214c7SGavin Maltby { "disabled", SCF_TRANS(SCF_STATE_DISABLED, SCF_STATE_DISABLED) },
53*f6e214c7SGavin Maltby { "to-online", SCF_TRANS(0, SCF_STATE_ONLINE) },
54*f6e214c7SGavin Maltby { "from-online", SCF_TRANS(SCF_STATE_ONLINE, 0) },
55*f6e214c7SGavin Maltby { "online", SCF_TRANS(SCF_STATE_ONLINE, SCF_STATE_ONLINE) },
56*f6e214c7SGavin Maltby { "to-degraded", SCF_TRANS(0, SCF_STATE_DEGRADED) },
57*f6e214c7SGavin Maltby { "from-degraded", SCF_TRANS(SCF_STATE_DEGRADED, 0) },
58*f6e214c7SGavin Maltby { "degraded", SCF_TRANS(SCF_STATE_DEGRADED, SCF_STATE_DEGRADED) },
59*f6e214c7SGavin Maltby { "to-all", SCF_TRANS(0, SCF_STATE_ALL) },
60*f6e214c7SGavin Maltby { "from-all", SCF_TRANS(SCF_STATE_ALL, 0) },
61*f6e214c7SGavin Maltby { "all", SCF_TRANS(SCF_STATE_ALL, SCF_STATE_ALL) },
62*f6e214c7SGavin Maltby { NULL, 0 }
63*f6e214c7SGavin Maltby };
64*f6e214c7SGavin Maltby
65*f6e214c7SGavin Maltby static struct fma_tags {
66*f6e214c7SGavin Maltby const char *t;
67*f6e214c7SGavin Maltby const char *s;
68*f6e214c7SGavin Maltby } fma_tags[] = {
69*f6e214c7SGavin Maltby { "problem-diagnosed", "list.suspect" },
70*f6e214c7SGavin Maltby { "problem-updated", "list.updated" },
71*f6e214c7SGavin Maltby { "problem-repaired", "list.repaired" },
72*f6e214c7SGavin Maltby { "problem-resolved", "list.resolved" },
73*f6e214c7SGavin Maltby { NULL, NULL }
74*f6e214c7SGavin Maltby };
75*f6e214c7SGavin Maltby
76*f6e214c7SGavin Maltby static char *fma_classes[] = {
77*f6e214c7SGavin Maltby "list.",
78*f6e214c7SGavin Maltby "ireport.",
79*f6e214c7SGavin Maltby NULL
80*f6e214c7SGavin Maltby };
81*f6e214c7SGavin Maltby
82*f6e214c7SGavin Maltby /*
83*f6e214c7SGavin Maltby * get_fma_tag()
84*f6e214c7SGavin Maltby * return a pointer to the fma tag at the passed index. NULL if no entry exist
85*f6e214c7SGavin Maltby * for index
86*f6e214c7SGavin Maltby */
87*f6e214c7SGavin Maltby const char *
get_fma_tag(uint32_t index)88*f6e214c7SGavin Maltby get_fma_tag(uint32_t index)
89*f6e214c7SGavin Maltby {
90*f6e214c7SGavin Maltby if (index > (sizeof (fma_tags) / sizeof (struct fma_tags)))
91*f6e214c7SGavin Maltby return (NULL);
92*f6e214c7SGavin Maltby
93*f6e214c7SGavin Maltby return (fma_tags[index].t);
94*f6e214c7SGavin Maltby }
95*f6e214c7SGavin Maltby
96*f6e214c7SGavin Maltby /*
97*f6e214c7SGavin Maltby * get_fma_class()
98*f6e214c7SGavin Maltby * return a pointer to the fma class at the passed index. NULL if no entry exist
99*f6e214c7SGavin Maltby * for index
100*f6e214c7SGavin Maltby */
101*f6e214c7SGavin Maltby const char *
get_fma_class(uint32_t index)102*f6e214c7SGavin Maltby get_fma_class(uint32_t index)
103*f6e214c7SGavin Maltby {
104*f6e214c7SGavin Maltby if (index > (sizeof (fma_tags) / sizeof (struct fma_tags)))
105*f6e214c7SGavin Maltby return (NULL);
106*f6e214c7SGavin Maltby
107*f6e214c7SGavin Maltby return (fma_tags[index].s);
108*f6e214c7SGavin Maltby }
109*f6e214c7SGavin Maltby
110*f6e214c7SGavin Maltby /*
111*f6e214c7SGavin Maltby * is_fma_token()
112*f6e214c7SGavin Maltby * check if the parameter is an fma token by comparing with the
113*f6e214c7SGavin Maltby * fma_classes[] and the fma_tags[] arrays.
114*f6e214c7SGavin Maltby */
115*f6e214c7SGavin Maltby int
is_fma_token(const char * t)116*f6e214c7SGavin Maltby is_fma_token(const char *t)
117*f6e214c7SGavin Maltby {
118*f6e214c7SGavin Maltby int i;
119*f6e214c7SGavin Maltby
120*f6e214c7SGavin Maltby for (i = 0; fma_classes[i]; ++i)
121*f6e214c7SGavin Maltby if (strncmp(t, fma_classes[i], strlen(fma_classes[i])) == 0)
122*f6e214c7SGavin Maltby return (1);
123*f6e214c7SGavin Maltby
124*f6e214c7SGavin Maltby for (i = 0; fma_tags[i].t; ++i)
125*f6e214c7SGavin Maltby if (strcmp(t, fma_tags[i].t) == 0)
126*f6e214c7SGavin Maltby return (1);
127*f6e214c7SGavin Maltby
128*f6e214c7SGavin Maltby return (0);
129*f6e214c7SGavin Maltby }
130*f6e214c7SGavin Maltby
131*f6e214c7SGavin Maltby /*
132*f6e214c7SGavin Maltby * has_fma_tag()
133*f6e214c7SGavin Maltby * returns 1 if there is an fma tag for the passed class, 0 otherwise
134*f6e214c7SGavin Maltby */
135*f6e214c7SGavin Maltby int
has_fma_tag(const char * c)136*f6e214c7SGavin Maltby has_fma_tag(const char *c)
137*f6e214c7SGavin Maltby {
138*f6e214c7SGavin Maltby int i;
139*f6e214c7SGavin Maltby
140*f6e214c7SGavin Maltby for (i = 0; fma_tags[i].s; ++i)
141*f6e214c7SGavin Maltby if (strcmp(c, fma_tags[i].s) == 0)
142*f6e214c7SGavin Maltby return (1);
143*f6e214c7SGavin Maltby
144*f6e214c7SGavin Maltby return (0);
145*f6e214c7SGavin Maltby }
146*f6e214c7SGavin Maltby
147*f6e214c7SGavin Maltby const char *
de_tag(const char * tag)148*f6e214c7SGavin Maltby de_tag(const char *tag)
149*f6e214c7SGavin Maltby {
150*f6e214c7SGavin Maltby int i;
151*f6e214c7SGavin Maltby
152*f6e214c7SGavin Maltby for (i = 0; fma_tags[i].t; ++i)
153*f6e214c7SGavin Maltby if (strcmp(tag, fma_tags[i].t) == 0)
154*f6e214c7SGavin Maltby return (fma_tags[i].s);
155*f6e214c7SGavin Maltby
156*f6e214c7SGavin Maltby return (tag);
157*f6e214c7SGavin Maltby }
158*f6e214c7SGavin Maltby
159*f6e214c7SGavin Maltby const char *
re_tag(const char * fma_event)160*f6e214c7SGavin Maltby re_tag(const char *fma_event)
161*f6e214c7SGavin Maltby {
162*f6e214c7SGavin Maltby int i;
163*f6e214c7SGavin Maltby
164*f6e214c7SGavin Maltby for (i = 0; fma_tags[i].s; ++i)
165*f6e214c7SGavin Maltby if (strcmp(fma_event, fma_tags[i].s) == 0)
166*f6e214c7SGavin Maltby return (fma_tags[i].t);
167*f6e214c7SGavin Maltby
168*f6e214c7SGavin Maltby return (fma_event);
169*f6e214c7SGavin Maltby }
170*f6e214c7SGavin Maltby
171*f6e214c7SGavin Maltby int32_t
string_to_tset(const char * str)172*f6e214c7SGavin Maltby string_to_tset(const char *str)
173*f6e214c7SGavin Maltby {
174*f6e214c7SGavin Maltby int i;
175*f6e214c7SGavin Maltby
176*f6e214c7SGavin Maltby for (i = 0; smf_st_events[i].s != NULL; ++i) {
177*f6e214c7SGavin Maltby if (strcmp(str, smf_st_events[i].s) == 0)
178*f6e214c7SGavin Maltby return (smf_st_events[i].c);
179*f6e214c7SGavin Maltby }
180*f6e214c7SGavin Maltby
181*f6e214c7SGavin Maltby return (0);
182*f6e214c7SGavin Maltby }
183*f6e214c7SGavin Maltby
184*f6e214c7SGavin Maltby const char *
tset_to_string(int32_t t)185*f6e214c7SGavin Maltby tset_to_string(int32_t t)
186*f6e214c7SGavin Maltby {
187*f6e214c7SGavin Maltby int i;
188*f6e214c7SGavin Maltby
189*f6e214c7SGavin Maltby for (i = 0; smf_st_events[i].s != NULL; ++i) {
190*f6e214c7SGavin Maltby if (smf_st_events[i].c == t)
191*f6e214c7SGavin Maltby return (smf_st_events[i].s);
192*f6e214c7SGavin Maltby }
193*f6e214c7SGavin Maltby
194*f6e214c7SGavin Maltby return (NULL);
195*f6e214c7SGavin Maltby }
196*f6e214c7SGavin Maltby
197*f6e214c7SGavin Maltby void
safe_printf(const char * fmt,...)198*f6e214c7SGavin Maltby safe_printf(const char *fmt, ...)
199*f6e214c7SGavin Maltby {
200*f6e214c7SGavin Maltby va_list va;
201*f6e214c7SGavin Maltby
202*f6e214c7SGavin Maltby va_start(va, fmt);
203*f6e214c7SGavin Maltby if (vprintf(fmt, va) < 0)
204*f6e214c7SGavin Maltby uu_die(gettext("Error writing to stdout"));
205*f6e214c7SGavin Maltby va_end(va);
206*f6e214c7SGavin Maltby }
207*f6e214c7SGavin Maltby
208*f6e214c7SGavin Maltby static uint32_t
notify_params_get_version(nvlist_t * nvl)209*f6e214c7SGavin Maltby notify_params_get_version(nvlist_t *nvl)
210*f6e214c7SGavin Maltby {
211*f6e214c7SGavin Maltby uint32_t v;
212*f6e214c7SGavin Maltby
213*f6e214c7SGavin Maltby if (nvl == NULL)
214*f6e214c7SGavin Maltby return (0xFFFFFFFFU);
215*f6e214c7SGavin Maltby
216*f6e214c7SGavin Maltby if (nvlist_lookup_uint32(nvl, SCF_NOTIFY_NAME_VERSION, &v) != 0)
217*f6e214c7SGavin Maltby return (0xFFFFFFFFU);
218*f6e214c7SGavin Maltby else
219*f6e214c7SGavin Maltby return (v);
220*f6e214c7SGavin Maltby }
221*f6e214c7SGavin Maltby
222*f6e214c7SGavin Maltby static void
nvpair_print(nvpair_t * p)223*f6e214c7SGavin Maltby nvpair_print(nvpair_t *p)
224*f6e214c7SGavin Maltby {
225*f6e214c7SGavin Maltby char **v;
226*f6e214c7SGavin Maltby uint_t n;
227*f6e214c7SGavin Maltby int i;
228*f6e214c7SGavin Maltby
229*f6e214c7SGavin Maltby safe_printf(" %s:", nvpair_name(p));
230*f6e214c7SGavin Maltby (void) nvpair_value_string_array(p, &v, &n);
231*f6e214c7SGavin Maltby for (i = 0; i < n; ++i) {
232*f6e214c7SGavin Maltby safe_printf(" %s", v[i]);
233*f6e214c7SGavin Maltby }
234*f6e214c7SGavin Maltby safe_printf("\n");
235*f6e214c7SGavin Maltby }
236*f6e214c7SGavin Maltby
237*f6e214c7SGavin Maltby static void
params_type_print(nvlist_t * p,const char * name,const char * fmri)238*f6e214c7SGavin Maltby params_type_print(nvlist_t *p, const char *name, const char *fmri)
239*f6e214c7SGavin Maltby {
240*f6e214c7SGavin Maltby nvpair_t *tnvp, *nvp;
241*f6e214c7SGavin Maltby nvlist_t *nvl;
242*f6e214c7SGavin Maltby boolean_t *a;
243*f6e214c7SGavin Maltby uint_t n;
244*f6e214c7SGavin Maltby int has_output = 0;
245*f6e214c7SGavin Maltby
246*f6e214c7SGavin Maltby /* for each event e print all notification parameters */
247*f6e214c7SGavin Maltby for (tnvp = nvlist_next_nvpair(p, NULL); tnvp != NULL;
248*f6e214c7SGavin Maltby tnvp = nvlist_next_nvpair(p, tnvp)) {
249*f6e214c7SGavin Maltby /* We only want the NVLIST memebers */
250*f6e214c7SGavin Maltby if (nvpair_type(tnvp) != DATA_TYPE_NVLIST)
251*f6e214c7SGavin Maltby continue;
252*f6e214c7SGavin Maltby
253*f6e214c7SGavin Maltby if (nvpair_value_nvlist(tnvp, &nvl) != 0)
254*f6e214c7SGavin Maltby uu_die("nvpair_value_nvlist");
255*f6e214c7SGavin Maltby
256*f6e214c7SGavin Maltby if (!has_output)
257*f6e214c7SGavin Maltby if (fmri == NULL)
258*f6e214c7SGavin Maltby safe_printf(gettext(" Event: %s\n"), name);
259*f6e214c7SGavin Maltby else
260*f6e214c7SGavin Maltby safe_printf(gettext(
261*f6e214c7SGavin Maltby " Event: %s (source: %s)\n"),
262*f6e214c7SGavin Maltby name, fmri);
263*f6e214c7SGavin Maltby
264*f6e214c7SGavin Maltby has_output = 1;
265*f6e214c7SGavin Maltby
266*f6e214c7SGavin Maltby safe_printf(gettext(" Notification Type: %s\n"),
267*f6e214c7SGavin Maltby nvpair_name(tnvp));
268*f6e214c7SGavin Maltby
269*f6e214c7SGavin Maltby if (nvlist_lookup_boolean_array(nvl, PARAM_ACTIVE, &a, &n) != 0)
270*f6e214c7SGavin Maltby uu_warn(gettext("Missing 'active' property"));
271*f6e214c7SGavin Maltby else
272*f6e214c7SGavin Maltby safe_printf(gettext(" Active: %s\n"),
273*f6e214c7SGavin Maltby *a ? "true" : "false");
274*f6e214c7SGavin Maltby
275*f6e214c7SGavin Maltby for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
276*f6e214c7SGavin Maltby nvp = nvlist_next_nvpair(nvl, nvp)) {
277*f6e214c7SGavin Maltby if (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)
278*f6e214c7SGavin Maltby continue;
279*f6e214c7SGavin Maltby nvpair_print(nvp);
280*f6e214c7SGavin Maltby }
281*f6e214c7SGavin Maltby safe_printf("\n");
282*f6e214c7SGavin Maltby }
283*f6e214c7SGavin Maltby }
284*f6e214c7SGavin Maltby
285*f6e214c7SGavin Maltby void
listnotify_print(nvlist_t * nvl,const char * event)286*f6e214c7SGavin Maltby listnotify_print(nvlist_t *nvl, const char *event)
287*f6e214c7SGavin Maltby {
288*f6e214c7SGavin Maltby char *fmri;
289*f6e214c7SGavin Maltby nvlist_t **params;
290*f6e214c7SGavin Maltby size_t n;
291*f6e214c7SGavin Maltby int32_t tset;
292*f6e214c7SGavin Maltby int i;
293*f6e214c7SGavin Maltby
294*f6e214c7SGavin Maltby /*
295*f6e214c7SGavin Maltby * Check the nvl we got is from a version we understand
296*f6e214c7SGavin Maltby */
297*f6e214c7SGavin Maltby if (nvl != NULL && notify_params_get_version(nvl) !=
298*f6e214c7SGavin Maltby SCF_NOTIFY_PARAMS_VERSION)
299*f6e214c7SGavin Maltby uu_die(gettext("libscf(3LIB) mismatch\n"));
300*f6e214c7SGavin Maltby
301*f6e214c7SGavin Maltby if (nvl != NULL && nvlist_lookup_nvlist_array(nvl, SCF_NOTIFY_PARAMS,
302*f6e214c7SGavin Maltby ¶ms, &n) != 0)
303*f6e214c7SGavin Maltby /* Sanity check. If we get here nvl is bad! */
304*f6e214c7SGavin Maltby uu_die(gettext("nvlist_lookup_nvlist_array\n"));
305*f6e214c7SGavin Maltby
306*f6e214c7SGavin Maltby if (event == NULL) {
307*f6e214c7SGavin Maltby /* this is an SMF state transition nvlist */
308*f6e214c7SGavin Maltby for (i = 0; i < n; ++i) {
309*f6e214c7SGavin Maltby nvlist_t *p = *(params + i);
310*f6e214c7SGavin Maltby
311*f6e214c7SGavin Maltby if (nvlist_lookup_string(p,
312*f6e214c7SGavin Maltby SCF_NOTIFY_PARAMS_SOURCE_NAME, &fmri) != 0)
313*f6e214c7SGavin Maltby fmri = NULL;
314*f6e214c7SGavin Maltby if (nvlist_lookup_int32(p, SCF_NOTIFY_NAME_TSET,
315*f6e214c7SGavin Maltby &tset) != 0)
316*f6e214c7SGavin Maltby uu_die("nvlist_lookup_int32");
317*f6e214c7SGavin Maltby params_type_print(p, tset_to_string(tset), fmri);
318*f6e214c7SGavin Maltby }
319*f6e214c7SGavin Maltby } else {
320*f6e214c7SGavin Maltby /* this is FMA event nvlist */
321*f6e214c7SGavin Maltby if (nvl == NULL) { /* preferences not found */
322*f6e214c7SGavin Maltby return;
323*f6e214c7SGavin Maltby }
324*f6e214c7SGavin Maltby for (i = 0; i < n; ++i) {
325*f6e214c7SGavin Maltby nvlist_t *p = *(params + i);
326*f6e214c7SGavin Maltby
327*f6e214c7SGavin Maltby if (nvlist_lookup_string(p,
328*f6e214c7SGavin Maltby SCF_NOTIFY_PARAMS_SOURCE_NAME, &fmri) != 0)
329*f6e214c7SGavin Maltby fmri = NULL;
330*f6e214c7SGavin Maltby params_type_print(p, event, fmri);
331*f6e214c7SGavin Maltby }
332*f6e214c7SGavin Maltby }
333*f6e214c7SGavin Maltby }
334