Print this page
NEX-17829 libfmd_snmp and snmp-notify should provide FMRIs for all fault types
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-16536 SUN-IREPORT-MIB is broken
NEX-16537 enhance FM traps
NEX-16545 SMF dict should have obsolete entries removed
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/fm/libfmnotify/common/libfmnotify.c
          +++ new/usr/src/lib/fm/libfmnotify/common/libfmnotify.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   */
       25 +
       26 +/*
       27 + * Copyright 2018 Nexenta Systems, Inc.
       28 + */
       29 +
       30 +#include <fm/libtopo.h>
       31 +
  25   32  #include <alloca.h>
  26   33  
  27   34  #include "libfmnotify.h"
  28   35  
  29   36  /*ARGSUSED*/
  30   37  void
  31   38  nd_cleanup(nd_hdl_t *nhdl)
  32   39  {
  33   40          nd_debug(nhdl, "Cleaning up ...");
  34   41          if (nhdl->nh_evhdl)
↓ open down ↓ 216 lines elided ↑ open up ↑
 251  258          scf_property_destroy(prop);
 252  259          scf_pg_destroy(pg);
 253  260          scf_handle_destroy(handle);
 254  261  
 255  262          return (ret);
 256  263  }
 257  264  
 258  265  char *
 259  266  nd_get_event_fmri(nd_hdl_t *nhdl, fmev_t ev)
 260  267  {
 261      -        nvlist_t *ev_nvl, *attr_nvl;
      268 +        nvlist_t *ev_nvl, *snvl;
      269 +        nvlist_t **fnvl;
      270 +        uint_t nnvl;
 262  271          char *svcname;
 263  272  
 264  273          if ((ev_nvl = fmev_attr_list(ev)) == NULL) {
 265      -                nd_error(nhdl, "Failed to lookup event attr nvlist");
      274 +                nd_error(nhdl, "failed to lookup event nvlist");
 266  275                  return (NULL);
 267  276          }
 268      -        if (nvlist_lookup_nvlist(ev_nvl, "attr", &attr_nvl) ||
 269      -            nvlist_lookup_string(attr_nvl, "svc-string", &svcname)) {
 270      -                nd_error(nhdl, "Malformed event 0x%p", (void *)ev_nvl);
      277 +
      278 +        /* If this is an ireport, simply lookup svc-string */
      279 +        if (nvlist_lookup_nvlist(ev_nvl, "attr", &snvl) == 0 &&
      280 +            nvlist_lookup_string(snvl, "svc-string", &svcname) == 0)
      281 +                return (strdup((const char *)svcname));
      282 +
      283 +        /* Otherwise extract the fault-list and use the first element */
      284 +        if (nvlist_lookup_nvlist_array(ev_nvl, FM_SUSPECT_FAULT_LIST,
      285 +            &fnvl, &nnvl) != 0 || nnvl != 1)
 271  286                  return (NULL);
      287 +
      288 +        /*
      289 +         * NOTE: this should match the logic in libfmd_snmp.
      290 +         *
      291 +         * Use the following order of nested nvlists to make up FMRI:
      292 +         * - FRU
      293 +         * - ASRU
      294 +         * - resource
      295 +         */
      296 +        if (nvlist_lookup_nvlist(fnvl[0], FM_FAULT_FRU, &snvl) == 0 ||
      297 +            nvlist_lookup_nvlist(fnvl[0], FM_FAULT_ASRU, &snvl) == 0 ||
      298 +            nvlist_lookup_nvlist(fnvl[0], FM_FAULT_RESOURCE, &snvl) == 0) {
      299 +                topo_hdl_t *thp;
      300 +                int topoerr;
      301 +                char *fmri, *ret = NULL;
      302 +
      303 +                thp = topo_open(TOPO_VERSION, NULL, &topoerr);
      304 +                if (thp == NULL)
      305 +                        return (NULL);
      306 +
      307 +                if (topo_fmri_nvl2str(thp, snvl, &fmri, &topoerr) == 0) {
      308 +                        ret = strdup(fmri);
      309 +                        topo_hdl_strfree(thp, fmri);
      310 +                }
      311 +
      312 +                topo_close(thp);
      313 +                return (ret);
 272  314          }
 273  315  
 274      -        return (strdup((const char *)svcname));
      316 +        return (NULL);
 275  317  }
 276  318  
 277  319  int
 278  320  nd_get_notify_prefs(nd_hdl_t *nhdl, const char *mech, fmev_t ev,
 279  321      nvlist_t ***pref_nvl, uint_t *nprefs)
 280  322  {
 281  323          nvlist_t *ev_nvl, *top_nvl, **np_nvlarr, *mech_nvl;
 282  324          int ret = 1;
 283  325          uint_t nelem;
 284  326  
↓ open down ↓ 219 lines elided ↑ open up ↑
 504  546   * single struct.
 505  547   *
 506  548   * The caller is responsible for freeing ev_info and any contained strings and
 507  549   * nvlists.  A convenience function, nd_free_event_info(), is provided for this
 508  550   * purpose.
 509  551   */
 510  552  int
 511  553  nd_get_event_info(nd_hdl_t *nhdl, const char *class, fmev_t ev,
 512  554      nd_ev_info_t **ev_info)
 513  555  {
 514      -        nvlist_t *ev_nvl, *attr_nvl;
      556 +        nvlist_t *attr_nvl;
 515  557          nd_ev_info_t *evi;
 516      -        char *code, *uuid, *fmri, *from_state, *to_state, *reason;
      558 +        char *code, *uuid, *from_state, *to_state, *reason;
 517  559  
 518  560          if ((evi = calloc(1, sizeof (nd_ev_info_t))) == NULL) {
 519  561                  nd_error(nhdl, "Failed to allocate memory");
 520  562                  return (-1);
 521  563          }
 522  564  
 523  565          /*
 524  566           * Hold event; class and payload will be valid for as long as
 525  567           * we hold the event.
 526  568           */
 527  569          fmev_hold(ev);
      570 +
 528  571          evi->ei_ev = ev;
 529      -        ev_nvl = fmev_attr_list(ev);
      572 +        evi->ei_class = fmev_class(ev);
      573 +        evi->ei_payload = fmev_attr_list(ev);
 530  574  
      575 +        if (nvlist_lookup_string(evi->ei_payload, FM_SUSPECT_UUID,
      576 +            &uuid) == 0) {
      577 +                evi->ei_uuid = strdup(uuid);
      578 +        } else {
      579 +                nd_error(nhdl, "Malformed event");
      580 +                nd_dump_nvlist(nhdl, evi->ei_payload);
      581 +                nd_free_event_info(evi);
      582 +                return (-1);
      583 +        }
      584 +
 531  585          /*
 532      -         * Lookup the MSGID, event description and severity and KA URL
      586 +         * Lookup the MSGID, type, severity, description, and KA URL.
 533  587           *
 534  588           * For FMA list.* events we just pull it out of the the event nvlist.
 535  589           * For all other events we call a utility function that computes the
 536  590           * diagcode using the dict name and class.
 537  591           */
 538  592          evi->ei_diagcode = calloc(32, sizeof (char));
 539      -        if ((nvlist_lookup_string(ev_nvl, FM_SUSPECT_DIAG_CODE, &code) == 0 &&
 540      -            strcpy(evi->ei_diagcode, code)) ||
 541      -            nd_get_diagcode(nhdl, "SMF", class, evi->ei_diagcode, 32)
 542      -            == 0) {
      593 +        if ((nvlist_lookup_string(evi->ei_payload, FM_SUSPECT_DIAG_CODE,
      594 +            &code) == 0 && strcpy(evi->ei_diagcode, code) != NULL) ||
      595 +            nd_get_diagcode(nhdl, "SMF", class, evi->ei_diagcode, 32) == 0) {
      596 +                evi->ei_type = fmd_msg_getitem_id(nhdl->nh_msghdl,
      597 +                    NULL, evi->ei_diagcode, FMD_MSG_ITEM_TYPE);
 543  598                  evi->ei_severity = fmd_msg_getitem_id(nhdl->nh_msghdl,
 544  599                      NULL, evi->ei_diagcode, FMD_MSG_ITEM_SEVERITY);
 545  600                  evi->ei_descr = fmd_msg_getitem_id(nhdl->nh_msghdl,
 546  601                      NULL, evi->ei_diagcode, FMD_MSG_ITEM_DESC);
 547  602                  evi->ei_url = fmd_msg_getitem_id(nhdl->nh_msghdl,
 548  603                      NULL, evi->ei_diagcode, FMD_MSG_ITEM_URL);
 549  604          } else
 550  605                  (void) strcpy(evi->ei_diagcode, ND_UNKNOWN);
 551  606  
 552      -        if (!evi->ei_severity)
      607 +        if (evi->ei_type == NULL)
      608 +                evi->ei_type = strdup(ND_UNKNOWN);
      609 +        if (evi->ei_severity == NULL)
 553  610                  evi->ei_severity = strdup(ND_UNKNOWN);
 554      -        if (!evi->ei_descr)
      611 +        if (evi->ei_descr == NULL)
 555  612                  evi->ei_descr = strdup(ND_UNKNOWN);
 556      -        if (!evi->ei_url)
      613 +        if (evi->ei_url == NULL)
 557  614                  evi->ei_url = strdup(ND_UNKNOWN);
 558  615  
 559      -        evi->ei_payload = ev_nvl;
 560      -        evi->ei_class = fmev_class(ev);
 561      -        if (nvlist_lookup_string(ev_nvl, FM_SUSPECT_UUID, &uuid) == 0)
 562      -                evi->ei_uuid = strdup(uuid);
 563      -        else {
 564      -                nd_error(nhdl, "Malformed event");
 565      -                nd_dump_nvlist(nhdl, evi->ei_payload);
 566      -                nd_free_event_info(evi);
 567      -                return (-1);
 568      -        }
      616 +        if ((evi->ei_fmri = nd_get_event_fmri(nhdl, ev)) == NULL)
      617 +                evi->ei_fmri = strdup(ND_UNKNOWN);
 569  618  
 570  619          if (strncmp(class, "ireport.os.smf", 14) == 0) {
 571      -                if ((fmri = nd_get_event_fmri(nhdl, ev)) == NULL) {
 572      -                        nd_error(nhdl, "Failed to get fmri from event payload");
 573      -                        nd_free_event_info(evi);
 574      -                        return (-1);
 575      -                }
 576      -                if (nvlist_lookup_nvlist(evi->ei_payload, "attr", &attr_nvl) ||
 577      -                    nvlist_lookup_string(attr_nvl, "from-state", &from_state) ||
 578      -                    nvlist_lookup_string(attr_nvl, "to-state", &to_state) ||
 579      -                    nvlist_lookup_string(attr_nvl, "reason-long", &reason)) {
      620 +                if (nvlist_lookup_nvlist(evi->ei_payload, "attr",
      621 +                    &attr_nvl) != 0 ||
      622 +                    nvlist_lookup_string(attr_nvl, "from-state",
      623 +                    &from_state) != 0 ||
      624 +                    nvlist_lookup_string(attr_nvl, "to-state",
      625 +                    &to_state) != 0 ||
      626 +                    nvlist_lookup_string(attr_nvl, "reason-long",
      627 +                    &reason) != 0) {
 580  628                          nd_error(nhdl, "Malformed event");
 581  629                          nd_dump_nvlist(nhdl, evi->ei_payload);
 582  630                          nd_free_event_info(evi);
 583      -                        free(fmri);
 584  631                          return (-1);
 585  632                  }
 586      -                evi->ei_fmri = fmri;
 587  633                  evi->ei_to_state = strdup(to_state);
 588  634                  evi->ei_from_state = strdup(from_state);
 589  635                  evi->ei_reason = strdup(reason);
 590  636          }
 591  637          *ev_info = evi;
 592  638          return (0);
 593  639  }
 594  640  
 595  641  static void
 596  642  condfree(void *buf)
↓ open down ↓ 20 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX