Print this page
NEX-9654 sd(7D) leaks memory when posting ereports
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/scsi/impl/scsi_fm.c
          +++ new/usr/src/uts/common/io/scsi/impl/scsi_fm.c
↓ open down ↓ 10 lines elided ↑ open up ↑
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  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   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright 2017 Nexenta Systems, Inc.
  23   25   */
  24   26  
  25   27  /*
  26   28   * SCSI FMA implementation
  27   29   */
  28   30  
  29   31  #include <sys/scsi/scsi_types.h>
  30   32  #include <sys/sunmdi.h>
  31   33  #include <sys/va_list.h>
  32   34  
↓ open down ↓ 59 lines elided ↑ open up ↑
  92   94   */
  93   95  void
  94   96  scsi_fm_ereport_post(struct scsi_device *sd, int path_instance,
  95   97      char *devpath, const char *error_class, uint64_t ena,
  96   98      char *devid, char *tpl0, int sflag, nvlist_t *pl, ...)
  97   99  {
  98  100          char            class[ERPT_CLASS_SZ];
  99  101          dev_info_t      *dip = sd->sd_dev;
 100  102          dev_info_t      *eqdip = dip;
 101  103          char            *minor_name;
      104 +        nvlist_t        *nvl;
      105 +        char            *prop;
 102  106          va_list         ap;
 103  107  
 104  108          /*
 105  109           * If the scsi_device eqdip is not yet ereport capable, send the
 106  110           * report based on parent capabilities.  This is needed for
 107  111           * telemetry during enumeration.
 108  112           */
 109  113          if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(eqdip)))
 110  114                  eqdip = ddi_get_parent(eqdip);
 111  115  
↓ open down ↓ 20 lines elided ↑ open up ↑
 132  136           * Set the minor_name to NULL. The block location of a media error
 133  137           * is described by the 'lba' property. We use the 'lba' instead of
 134  138           * the partition (minor_name) because the defect stays in the same
 135  139           * place even when a repartition operation may result in the defect
 136  140           * showing up in a different partition (minor_name). To support
 137  141           * retire at the block/partition level, the user level retire agent
 138  142           * should map the 'lba' to the current effected partition.
 139  143           */
 140  144          minor_name = NULL;
 141  145  
      146 +        /* Create nvlist containing inquiry properties (if available) */
      147 +        if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, (sflag & DDI_NOSLEEP) ?
      148 +            KM_NOSLEEP : KM_SLEEP) != 0)
      149 +                return;
      150 +        if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
      151 +            INQUIRY_VENDOR_ID, &prop) == DDI_PROP_SUCCESS) {
      152 +                (void) nvlist_add_string(nvl, "vendor", prop);
      153 +                ddi_prop_free(prop);
      154 +        }
      155 +        if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
      156 +            INQUIRY_PRODUCT_ID, &prop) == DDI_PROP_SUCCESS) {
      157 +                (void) nvlist_add_string(nvl, "product", prop);
      158 +                ddi_prop_free(prop);
      159 +        }
      160 +        if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
      161 +            INQUIRY_REVISION_ID, &prop) == DDI_PROP_SUCCESS) {
      162 +                (void) nvlist_add_string(nvl, "revision", prop);
      163 +                ddi_prop_free(prop);
      164 +        }
      165 +        if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
      166 +            INQUIRY_SERIAL_NO, &prop) == DDI_PROP_SUCCESS) {
      167 +                (void) nvlist_add_string(nvl, "serial", prop);
      168 +                ddi_prop_free(prop);
      169 +        }
      170 +        /* Merge the provided payload if any */
      171 +        if (pl != NULL)
      172 +                (void) nvlist_merge(nvl, pl, 0);
      173 +
 142  174          /*
 143  175           * NOTE: If there is a 'linked' ena to be had, it should likely come
 144  176           * from the buf structure via the scsi_pkt pkt->pkt_bp.
 145  177           */
 146  178  
 147  179          /* Post the ereport */
 148  180          va_start(ap, pl);
 149  181          fm_dev_ereport_postv(dip, eqdip, devpath, minor_name, devid, tpl0,
 150      -            class, ena, sflag, pl, ap);
      182 +            class, ena, sflag, nvl, ap);
 151  183          va_end(ap);
      184 +
      185 +        nvlist_free(nvl);
 152  186  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX