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>

@@ -16,12 +16,14 @@
  * fields enclosed by brackets "[]" replaced with your own identifying
  * information: Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
  */
+
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc.
  */
 
 /*
  * SCSI FMA implementation
  */

@@ -97,10 +99,12 @@
 {
         char            class[ERPT_CLASS_SZ];
         dev_info_t      *dip = sd->sd_dev;
         dev_info_t      *eqdip = dip;
         char            *minor_name;
+        nvlist_t        *nvl;
+        char            *prop;
         va_list         ap;
 
         /*
          * If the scsi_device eqdip is not yet ereport capable, send the
          * report based on parent capabilities.  This is needed for

@@ -137,16 +141,46 @@
          * retire at the block/partition level, the user level retire agent
          * should map the 'lba' to the current effected partition.
          */
         minor_name = NULL;
 
+        /* Create nvlist containing inquiry properties (if available) */
+        if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, (sflag & DDI_NOSLEEP) ?
+            KM_NOSLEEP : KM_SLEEP) != 0)
+                return;
+        if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+            INQUIRY_VENDOR_ID, &prop) == DDI_PROP_SUCCESS) {
+                (void) nvlist_add_string(nvl, "vendor", prop);
+                ddi_prop_free(prop);
+        }
+        if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+            INQUIRY_PRODUCT_ID, &prop) == DDI_PROP_SUCCESS) {
+                (void) nvlist_add_string(nvl, "product", prop);
+                ddi_prop_free(prop);
+        }
+        if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+            INQUIRY_REVISION_ID, &prop) == DDI_PROP_SUCCESS) {
+                (void) nvlist_add_string(nvl, "revision", prop);
+                ddi_prop_free(prop);
+        }
+        if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+            INQUIRY_SERIAL_NO, &prop) == DDI_PROP_SUCCESS) {
+                (void) nvlist_add_string(nvl, "serial", prop);
+                ddi_prop_free(prop);
+        }
+        /* Merge the provided payload if any */
+        if (pl != NULL)
+                (void) nvlist_merge(nvl, pl, 0);
+
         /*
          * NOTE: If there is a 'linked' ena to be had, it should likely come
          * from the buf structure via the scsi_pkt pkt->pkt_bp.
          */
 
         /* Post the ereport */
         va_start(ap, pl);
         fm_dev_ereport_postv(dip, eqdip, devpath, minor_name, devid, tpl0,
-            class, ena, sflag, pl, ap);
+            class, ena, sflag, nvl, ap);
         va_end(ap);
+
+        nvlist_free(nvl);
 }