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 * 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 * 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 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 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 * 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 * 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 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 * 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 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 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 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 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 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