Print this page
patch v2
6120 libzfs leaks a config nvlist for spares and l2arc
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>

*** 238,247 **** --- 238,248 ---- return (-1); } ne->ne_guid = vdev_guid; ne->ne_next = pl->names; pl->names = ne; + nvlist_free(config); return (0); } /* * If we have a valid config but cannot read any of these fields, then
*** 271,284 **** if (pe->pe_guid == pool_guid) break; } if (pe == NULL) { ! if ((pe = zfs_alloc(hdl, sizeof (pool_entry_t))) == NULL) { ! nvlist_free(config); return (-1); - } pe->pe_guid = pool_guid; pe->pe_next = pl->pools; pl->pools = pe; } --- 272,283 ---- if (pe->pe_guid == pool_guid) break; } if (pe == NULL) { ! if ((pe = zfs_alloc(hdl, sizeof (pool_entry_t))) == NULL) return (-1); pe->pe_guid = pool_guid; pe->pe_next = pl->pools; pl->pools = pe; }
*** 290,349 **** if (ve->ve_guid == top_guid) break; } if (ve == NULL) { ! if ((ve = zfs_alloc(hdl, sizeof (vdev_entry_t))) == NULL) { ! nvlist_free(config); return (-1); - } ve->ve_guid = top_guid; ve->ve_next = pe->pe_vdevs; pe->pe_vdevs = ve; } /* ! * Third, see if we have a config with a matching transaction group. If ! * so, then we do nothing. Otherwise, add it to the list of known ! * configs. */ for (ce = ve->ve_configs; ce != NULL; ce = ce->ce_next) { if (ce->ce_txg == txg) break; } if (ce == NULL) { ! if ((ce = zfs_alloc(hdl, sizeof (config_entry_t))) == NULL) { ! nvlist_free(config); return (-1); - } ce->ce_txg = txg; ce->ce_config = config; ce->ce_next = ve->ve_configs; ve->ve_configs = ce; } else { nvlist_free(config); } - /* - * At this point we've successfully added our config to the list of - * known configs. The last thing to do is add the vdev guid -> path - * mappings so that we can fix up the configuration as necessary before - * doing the import. - */ - if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL) - return (-1); - - if ((ne->ne_name = zfs_strdup(hdl, path)) == NULL) { - free(ne); - return (-1); - } - - ne->ne_guid = vdev_guid; - ne->ne_next = pl->names; - pl->names = ne; - return (0); } /* * Returns true if the named pool matches the given GUID. --- 289,342 ---- if (ve->ve_guid == top_guid) break; } if (ve == NULL) { ! if ((ve = zfs_alloc(hdl, sizeof (vdev_entry_t))) == NULL) return (-1); ve->ve_guid = top_guid; ve->ve_next = pe->pe_vdevs; pe->pe_vdevs = ve; } /* ! * Third, add the vdev guid -> path mappings so that we can fix up ! * the configuration as necessary before doing the import. ! */ ! if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL) ! return (-1); ! ! if ((ne->ne_name = zfs_strdup(hdl, path)) == NULL) { ! free(ne); ! return (-1); ! } ! ! ne->ne_guid = vdev_guid; ! ne->ne_next = pl->names; ! pl->names = ne; ! ! /* ! * Finally, see if we have a config with a matching transaction ! * group. If so, then we do nothing. Otherwise, add it to the list ! * of known configs. */ for (ce = ve->ve_configs; ce != NULL; ce = ce->ce_next) { if (ce->ce_txg == txg) break; } if (ce == NULL) { ! if ((ce = zfs_alloc(hdl, sizeof (config_entry_t))) == NULL) return (-1); ce->ce_txg = txg; ce->ce_config = config; ce->ce_next = ve->ve_configs; ve->ve_configs = ce; } else { nvlist_free(config); } return (0); } /* * Returns true if the named pool matches the given GUID.
*** 1256,1269 **** * use the non-raw path for the config */ (void) strlcpy(end, slice->rn_name, pathleft); if (add_config(hdl, &pools, path, ! config) != 0) config_failed = B_TRUE; } } free(slice->rn_name); free(slice); } avl_destroy(&slice_cache); --- 1249,1264 ---- * use the non-raw path for the config */ (void) strlcpy(end, slice->rn_name, pathleft); if (add_config(hdl, &pools, path, ! config) != 0) { ! nvlist_free(config); config_failed = B_TRUE; } } + } free(slice->rn_name); free(slice); } avl_destroy(&slice_cache);