diff options
| author | Gavin Maltby <gavin.maltby@oracle.com> | 2010-07-30 17:04:17 +1000 |
|---|---|---|
| committer | Gavin Maltby <gavin.maltby@oracle.com> | 2010-07-30 17:04:17 +1000 |
| commit | f6e214c7418f43af38bd8c3a557e3d0a1d311cfa (patch) | |
| tree | 0f0e4cee5ead68ee30660107f9eccf7cd9e72c2e /usr/src/cmd/svc/common | |
| parent | 265a964d7aa43c47170d21d2f01bcf873d7fd79d (diff) | |
| download | illumos-joyent-f6e214c7418f43af38bd8c3a557e3d0a1d311cfa.tar.gz | |
PSARC/2009/617 Software Events Notification Parameters CLI
PSARC/2009/618 snmp-notify: SNMP Notification Daemon for Software Events
PSARC/2009/619 smtp-notify: Email Notification Daemon for Software Events
PSARC/2010/225 fmd for non-global Solaris zones
PSARC/2010/226 Solaris Instance UUID
PSARC/2010/227 nvlist_nvflag(3NVPAIR)
PSARC/2010/228 libfmevent additions
PSARC/2010/257 sysevent_evc_setpropnvl and sysevent_evc_getpropnvl
PSARC/2010/265 FMRI and FMA Event Stabilty, 'ireport' category 1 event class, and the 'sw' FMRI scheme
PSARC/2010/278 FMA/SMF integration: instance state transitions
PSARC/2010/279 Modelling panics within FMA
PSARC/2010/290 logadm.conf upgrade
6392476 fmdump needs to pretty-print
6393375 userland ereport/ireport event generation interfaces
6445732 Add email notification agent for FMA and software events
6804168 RFE: Allow an efficient means to monitor SMF services status changes
6866661 scf_values_destroy(3SCF) will segfault if is passed NULL
6884709 Add snmp notification agent for FMA and software events
6884712 Add private interface to tap into libfmd_msg macro expansion capabilities
6897919 fmd to run in a non-global zone
6897937 fmd use of non-private doors is not safe
6900081 add a UUID to Solaris kernel image for use in crashdump identification
6914884 model panic events as a defect diagnosis in FMA
6944862 fmd_case_open_uuid, fmd_case_uuisresolved, fmd_nvl_create_defect
6944866 log legacy sysevents in fmd
6944867 enumerate svc scheme in topo
6944868 software-diagnosis and software-response fmd modules
6944870 model SMF maintenance state as a defect diagnosis in FMA
6944876 savecore runs in foreground for systems with zfs root and dedicated dump
6965796 Implement notification parameters for SMF state transitions and FMA events
6968287 SUN-FM-MIB.mib needs to be updated to reflect Oracle information
6972331 logadm.conf upgrade PSARC/2010/290
Diffstat (limited to 'usr/src/cmd/svc/common')
| -rw-r--r-- | usr/src/cmd/svc/common/notify_params.c | 333 | ||||
| -rw-r--r-- | usr/src/cmd/svc/common/notify_params.h | 54 |
2 files changed, 387 insertions, 0 deletions
diff --git a/usr/src/cmd/svc/common/notify_params.c b/usr/src/cmd/svc/common/notify_params.c new file mode 100644 index 0000000000..e947b0fa76 --- /dev/null +++ b/usr/src/cmd/svc/common/notify_params.c @@ -0,0 +1,333 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + */ + +#include <libintl.h> +#include <libnvpair.h> +#include <libscf.h> +#include <libscf_priv.h> +#include <libuutil.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include "notify_params.h" + +static struct events { + const char *s; + int32_t c; +} smf_st_events[] = { + { "to-uninitialized", SCF_TRANS(0, SCF_STATE_UNINIT) }, + { "from-uninitialized", SCF_TRANS(SCF_STATE_UNINIT, 0) }, + { "uninitialized", SCF_TRANS(SCF_STATE_UNINIT, SCF_STATE_UNINIT) }, + { "to-maintenance", SCF_TRANS(0, SCF_STATE_MAINT) }, + { "from-maintenance", SCF_TRANS(SCF_STATE_MAINT, 0) }, + { "maintenance", SCF_TRANS(SCF_STATE_MAINT, SCF_STATE_MAINT) }, + { "to-offline", SCF_TRANS(0, SCF_STATE_OFFLINE) }, + { "from-offline", SCF_TRANS(SCF_STATE_OFFLINE, 0) }, + { "offline", SCF_TRANS(SCF_STATE_OFFLINE, SCF_STATE_OFFLINE) }, + { "to-disabled", SCF_TRANS(0, SCF_STATE_DISABLED) }, + { "from-disabled", SCF_TRANS(SCF_STATE_DISABLED, 0) }, + { "disabled", SCF_TRANS(SCF_STATE_DISABLED, SCF_STATE_DISABLED) }, + { "to-online", SCF_TRANS(0, SCF_STATE_ONLINE) }, + { "from-online", SCF_TRANS(SCF_STATE_ONLINE, 0) }, + { "online", SCF_TRANS(SCF_STATE_ONLINE, SCF_STATE_ONLINE) }, + { "to-degraded", SCF_TRANS(0, SCF_STATE_DEGRADED) }, + { "from-degraded", SCF_TRANS(SCF_STATE_DEGRADED, 0) }, + { "degraded", SCF_TRANS(SCF_STATE_DEGRADED, SCF_STATE_DEGRADED) }, + { "to-all", SCF_TRANS(0, SCF_STATE_ALL) }, + { "from-all", SCF_TRANS(SCF_STATE_ALL, 0) }, + { "all", SCF_TRANS(SCF_STATE_ALL, SCF_STATE_ALL) }, + { NULL, 0 } +}; + +static struct fma_tags { + const char *t; + const char *s; +} fma_tags[] = { + { "problem-diagnosed", "list.suspect" }, + { "problem-updated", "list.updated" }, + { "problem-repaired", "list.repaired" }, + { "problem-resolved", "list.resolved" }, + { NULL, NULL } +}; + +static char *fma_classes[] = { + "list.", + "ireport.", + NULL +}; + +/* + * get_fma_tag() + * return a pointer to the fma tag at the passed index. NULL if no entry exist + * for index + */ +const char * +get_fma_tag(uint32_t index) +{ + if (index > (sizeof (fma_tags) / sizeof (struct fma_tags))) + return (NULL); + + return (fma_tags[index].t); +} + +/* + * get_fma_class() + * return a pointer to the fma class at the passed index. NULL if no entry exist + * for index + */ +const char * +get_fma_class(uint32_t index) +{ + if (index > (sizeof (fma_tags) / sizeof (struct fma_tags))) + return (NULL); + + return (fma_tags[index].s); +} + +/* + * is_fma_token() + * check if the parameter is an fma token by comparing with the + * fma_classes[] and the fma_tags[] arrays. + */ +int +is_fma_token(const char *t) +{ + int i; + + for (i = 0; fma_classes[i]; ++i) + if (strncmp(t, fma_classes[i], strlen(fma_classes[i])) == 0) + return (1); + + for (i = 0; fma_tags[i].t; ++i) + if (strcmp(t, fma_tags[i].t) == 0) + return (1); + + return (0); +} + +/* + * has_fma_tag() + * returns 1 if there is an fma tag for the passed class, 0 otherwise + */ +int +has_fma_tag(const char *c) +{ + int i; + + for (i = 0; fma_tags[i].s; ++i) + if (strcmp(c, fma_tags[i].s) == 0) + return (1); + + return (0); +} + +const char * +de_tag(const char *tag) +{ + int i; + + for (i = 0; fma_tags[i].t; ++i) + if (strcmp(tag, fma_tags[i].t) == 0) + return (fma_tags[i].s); + + return (tag); +} + +const char * +re_tag(const char *fma_event) +{ + int i; + + for (i = 0; fma_tags[i].s; ++i) + if (strcmp(fma_event, fma_tags[i].s) == 0) + return (fma_tags[i].t); + + return (fma_event); +} + +int32_t +string_to_tset(const char *str) +{ + int i; + + for (i = 0; smf_st_events[i].s != NULL; ++i) { + if (strcmp(str, smf_st_events[i].s) == 0) + return (smf_st_events[i].c); + } + + return (0); +} + +const char * +tset_to_string(int32_t t) +{ + int i; + + for (i = 0; smf_st_events[i].s != NULL; ++i) { + if (smf_st_events[i].c == t) + return (smf_st_events[i].s); + } + + return (NULL); +} + +void +safe_printf(const char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + if (vprintf(fmt, va) < 0) + uu_die(gettext("Error writing to stdout")); + va_end(va); +} + +static uint32_t +notify_params_get_version(nvlist_t *nvl) +{ + uint32_t v; + + if (nvl == NULL) + return (0xFFFFFFFFU); + + if (nvlist_lookup_uint32(nvl, SCF_NOTIFY_NAME_VERSION, &v) != 0) + return (0xFFFFFFFFU); + else + return (v); +} + +static void +nvpair_print(nvpair_t *p) +{ + char **v; + uint_t n; + int i; + + safe_printf(" %s:", nvpair_name(p)); + (void) nvpair_value_string_array(p, &v, &n); + for (i = 0; i < n; ++i) { + safe_printf(" %s", v[i]); + } + safe_printf("\n"); +} + +static void +params_type_print(nvlist_t *p, const char *name, const char *fmri) +{ + nvpair_t *tnvp, *nvp; + nvlist_t *nvl; + boolean_t *a; + uint_t n; + int has_output = 0; + + /* for each event e print all notification parameters */ + for (tnvp = nvlist_next_nvpair(p, NULL); tnvp != NULL; + tnvp = nvlist_next_nvpair(p, tnvp)) { + /* We only want the NVLIST memebers */ + if (nvpair_type(tnvp) != DATA_TYPE_NVLIST) + continue; + + if (nvpair_value_nvlist(tnvp, &nvl) != 0) + uu_die("nvpair_value_nvlist"); + + if (!has_output) + if (fmri == NULL) + safe_printf(gettext(" Event: %s\n"), name); + else + safe_printf(gettext( + " Event: %s (source: %s)\n"), + name, fmri); + + has_output = 1; + + safe_printf(gettext(" Notification Type: %s\n"), + nvpair_name(tnvp)); + + if (nvlist_lookup_boolean_array(nvl, PARAM_ACTIVE, &a, &n) != 0) + uu_warn(gettext("Missing 'active' property")); + else + safe_printf(gettext(" Active: %s\n"), + *a ? "true" : "false"); + + for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL; + nvp = nvlist_next_nvpair(nvl, nvp)) { + if (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY) + continue; + nvpair_print(nvp); + } + safe_printf("\n"); + } +} + +void +listnotify_print(nvlist_t *nvl, const char *event) +{ + char *fmri; + nvlist_t **params; + size_t n; + int32_t tset; + int i; + + /* + * Check the nvl we got is from a version we understand + */ + if (nvl != NULL && notify_params_get_version(nvl) != + SCF_NOTIFY_PARAMS_VERSION) + uu_die(gettext("libscf(3LIB) mismatch\n")); + + if (nvl != NULL && nvlist_lookup_nvlist_array(nvl, SCF_NOTIFY_PARAMS, + ¶ms, &n) != 0) + /* Sanity check. If we get here nvl is bad! */ + uu_die(gettext("nvlist_lookup_nvlist_array\n")); + + if (event == NULL) { + /* this is an SMF state transition nvlist */ + for (i = 0; i < n; ++i) { + nvlist_t *p = *(params + i); + + if (nvlist_lookup_string(p, + SCF_NOTIFY_PARAMS_SOURCE_NAME, &fmri) != 0) + fmri = NULL; + if (nvlist_lookup_int32(p, SCF_NOTIFY_NAME_TSET, + &tset) != 0) + uu_die("nvlist_lookup_int32"); + params_type_print(p, tset_to_string(tset), fmri); + } + } else { + /* this is FMA event nvlist */ + if (nvl == NULL) { /* preferences not found */ + return; + } + for (i = 0; i < n; ++i) { + nvlist_t *p = *(params + i); + + if (nvlist_lookup_string(p, + SCF_NOTIFY_PARAMS_SOURCE_NAME, &fmri) != 0) + fmri = NULL; + params_type_print(p, event, fmri); + } + } +} diff --git a/usr/src/cmd/svc/common/notify_params.h b/usr/src/cmd/svc/common/notify_params.h new file mode 100644 index 0000000000..7f1527ae16 --- /dev/null +++ b/usr/src/cmd/svc/common/notify_params.h @@ -0,0 +1,54 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + */ + +#ifndef _CMD_COMMON_NOTIFY_PARAMS_H +#define _CMD_COMMON_NOTIFY_PARAMS_H + +#include <libnvpair.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define PARAM_ACTIVE ((const char *) "active") +#define PARAM_INACTIVE ((const char *) "inactive") +#define PARAM_SMTP_TO ((const char *) "to") + +const char *get_fma_tag(uint32_t); +const char *get_fma_class(uint32_t); +int is_fma_token(const char *); +int has_fma_tag(const char *); +const char *de_tag(const char *); +const char *re_tag(const char *); +int32_t string_to_tset(const char *); +const char *tset_to_string(int32_t); +void listnotify_print(nvlist_t *, const char *); +void safe_printf(const char *, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* _CMD_COMMON_NOTIFY_PARAMS_H */ |
