Print this page
NEX-17446 cleanup of hot unplugged disks fails intermittently
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-17944 HBA drivers don't need the redundant devfs_clean step
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-17934 NULL pointer reference in kstat_rele()
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-15288 getting kstat_create('mdi'...) errors on each reboot
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-15925 pseudonex, rootnex, and friends don't need to log useless device announcements
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
OS-253 we should not free mdi_pathinfo_t in mptsas when device(s) are retired
OS-126 Creating a LUN for retired device results in sysevent loop

*** 16,43 **** * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright (c) 2014 Nexenta Systems Inc. All rights reserved. */ /* * Multipath driver interface (MDI) implementation; see mdi_impldefs.h for a * more detailed discussion of the overall mpxio architecture. - * - * Default locking order: - * - * _NOTE(LOCK_ORDER(mdi_mutex, mdi_vhci:vh_phci_mutex); - * _NOTE(LOCK_ORDER(mdi_mutex, mdi_vhci:vh_client_mutex); - * _NOTE(LOCK_ORDER(mdi_vhci:vh_phci_mutex, mdi_phci::ph_mutex); - * _NOTE(LOCK_ORDER(mdi_vhci:vh_client_mutex, mdi_client::ct_mutex); - * _NOTE(LOCK_ORDER(mdi_phci::ph_mutex mdi_pathinfo::pi_mutex)) - * _NOTE(LOCK_ORDER(mdi_phci::ph_mutex mdi_client::ct_mutex)) - * _NOTE(LOCK_ORDER(mdi_client::ct_mutex mdi_pathinfo::pi_mutex)) */ #include <sys/note.h> #include <sys/types.h> #include <sys/varargs.h> --- 16,34 ---- * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ + /* * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2018 Nexenta Systems, Inc. */ /* * Multipath driver interface (MDI) implementation; see mdi_impldefs.h for a * more detailed discussion of the overall mpxio architecture. */ #include <sys/note.h> #include <sys/types.h> #include <sys/varargs.h>
*** 1194,1204 **** { int rv = MDI_SUCCESS; if (i_mdi_is_child_present(vdip, cdip) == MDI_SUCCESS || (flags & MDI_CLIENT_FLAGS_DEV_NOT_SUPPORTED)) { ! rv = ndi_devi_offline(cdip, NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE); if (rv != NDI_SUCCESS) { MDI_DEBUG(1, (MDI_NOTE, cdip, "!failed: cdip %p", (void *)cdip)); } /* --- 1185,1200 ---- { int rv = MDI_SUCCESS; if (i_mdi_is_child_present(vdip, cdip) == MDI_SUCCESS || (flags & MDI_CLIENT_FLAGS_DEV_NOT_SUPPORTED)) { ! int nflags = NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE; ! ! if (flags & MDI_CLIENT_FLAGS_NO_EVENT) ! nflags |= NDI_NO_EVENT; ! ! rv = ndi_devi_offline(cdip, nflags); if (rv != NDI_SUCCESS) { MDI_DEBUG(1, (MDI_NOTE, cdip, "!failed: cdip %p", (void *)cdip)); } /*
*** 3261,3270 **** --- 3257,3267 ---- if (ct->ct_path_count == 0) { /* * Client lost its last path. * Clean up the client device */ + ct->ct_flags |= flags; MDI_CLIENT_UNLOCK(ct); (void) i_mdi_client_free(ct->ct_vhci, ct); MDI_VHCI_CLIENT_UNLOCK(vh); return (rv); }
*** 3668,3698 **** case MDI_CLIENT_STATE_FAILED: /* * This is the last path case for * non-user initiated events. */ ! if (((flag & NDI_USER_REQ) == 0) && ! cdip && (i_ddi_node_state(cdip) >= ! DS_INITIALIZED)) { MDI_CLIENT_UNLOCK(ct); ! rv = ndi_devi_offline(cdip, ! NDI_DEVFS_CLEAN); MDI_CLIENT_LOCK(ct); if (rv != NDI_SUCCESS) { /* ! * ndi_devi_offline failed. ! * Reset client flags to ! * online as the path could not ! * be offlined. */ MDI_DEBUG(1, (MDI_WARN, cdip, ! "!ndi_devi_offline failed: " ! "error %x", rv)); MDI_CLIENT_SET_ONLINE(ct); } - } break; } /* * Convert to MDI error code */ --- 3665,3694 ---- case MDI_CLIENT_STATE_FAILED: /* * This is the last path case for * non-user initiated events. */ ! if ((flag & NDI_USER_REQ) || ! cdip == NULL || i_ddi_node_state(cdip) < ! DS_INITIALIZED) ! break; ! MDI_CLIENT_UNLOCK(ct); ! rv = ndi_devi_offline(cdip, NDI_DEVFS_CLEAN | ! NDI_DEVI_GONE); MDI_CLIENT_LOCK(ct); if (rv != NDI_SUCCESS) { /* ! * Reset client flags to online as the ! * path could not be offlined. */ MDI_DEBUG(1, (MDI_WARN, cdip, ! "!ndi_devi_offline failed: %d", ! rv)); MDI_CLIENT_SET_ONLINE(ct); } break; } /* * Convert to MDI error code */
*** 4853,4870 **** status = "faulted"; } else { status = "unknown"; } ! if (cdip) { ct_path = kmem_alloc(MAXPATHLEN, KM_SLEEP); - /* - * NOTE: Keeping "multipath status: %s" and - * "Load balancing: %s" format unchanged in case someone - * scrubs /var/adm/messages looking for these messages. - */ if (report_lb_c && report_lb_p) { if (ct->ct_lb == LOAD_BALANCE_LBA) { (void) snprintf(lb_buf, sizeof (lb_buf), "%s, region-size: %d", mdi_load_balance_lba, ct->ct_lb_args->region_size); --- 4849,4861 ---- status = "faulted"; } else { status = "unknown"; } ! if (cdip != NULL) { ct_path = kmem_alloc(MAXPATHLEN, KM_SLEEP); if (report_lb_c && report_lb_p) { if (ct->ct_lb == LOAD_BALANCE_LBA) { (void) snprintf(lb_buf, sizeof (lb_buf), "%s, region-size: %d", mdi_load_balance_lba, ct->ct_lb_args->region_size);
*** 4874,4897 **** } else { (void) snprintf(lb_buf, sizeof (lb_buf), "%s", mdi_load_balance_rr); } ! cmn_err(mdi_debug_consoleonly ? CE_NOTE : CE_CONT, ! "?%s (%s%d) multipath status: %s: " ! "path %d %s is %s: Load balancing: %s\n", ! ddi_pathname(cdip, ct_path), ddi_driver_name(cdip), ! ddi_get_instance(cdip), ct_status, ! mdi_pi_get_path_instance(pip), mdi_pi_spathname(pip), status, lb_buf); } else { ! cmn_err(mdi_debug_consoleonly ? CE_NOTE : CE_CONT, ! "?%s (%s%d) multipath status: %s: " ! "path %d %s is %s\n", ! ddi_pathname(cdip, ct_path), ddi_driver_name(cdip), ! ddi_get_instance(cdip), ct_status, ! mdi_pi_get_path_instance(pip), mdi_pi_spathname(pip), status); } kmem_free(ct_path, MAXPATHLEN); MDI_CLIENT_CLEAR_REPORT_DEV_NEEDED(ct); --- 4865,4882 ---- } else { (void) snprintf(lb_buf, sizeof (lb_buf), "%s", mdi_load_balance_rr); } ! dev_err(cdip, CE_CONT, "!multipath status: %s: " ! "path %d %s is %s; load balancing: %s\n", ! ct_status, mdi_pi_get_path_instance(pip), mdi_pi_spathname(pip), status, lb_buf); } else { ! dev_err(cdip, CE_CONT, ! "!multipath status: %s: path %d %s is %s\n", ! ct_status, mdi_pi_get_path_instance(pip), mdi_pi_spathname(pip), status); } kmem_free(ct_path, MAXPATHLEN); MDI_CLIENT_CLEAR_REPORT_DEV_NEEDED(ct);
*** 6073,6097 **** mdi_pi_kstat_create(mdi_pathinfo_t *pip, char *ksname) { kstat_t *kiosp, *kerrsp; struct pi_errs *nsp; struct mdi_pi_kstats *mdi_statp; ! if (MDI_PI(pip)->pi_kstats != NULL) return (MDI_SUCCESS); if ((kiosp = kstat_create("mdi", 0, ksname, "iopath", KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT)) == NULL) { return (MDI_FAILURE); } ! (void) strcat(ksname, ",err"); ! kerrsp = kstat_create("mdi", 0, ksname, "iopath_errors", KSTAT_TYPE_NAMED, sizeof (struct pi_errs) / sizeof (kstat_named_t), 0); if (kerrsp == NULL) { kstat_delete(kiosp); return (MDI_FAILURE); } nsp = (struct pi_errs *)kerrsp->ks_data; kstat_named_init(&nsp->pi_softerrs, "Soft Errors", KSTAT_DATA_UINT32); --- 6058,6094 ---- mdi_pi_kstat_create(mdi_pathinfo_t *pip, char *ksname) { kstat_t *kiosp, *kerrsp; struct pi_errs *nsp; struct mdi_pi_kstats *mdi_statp; + char *errksname; + size_t len; ! /* ! * If the kstat name was already created nothing to do. ! */ ! if ((kiosp = kstat_hold_byname("mdi", 0, ksname, ! ALL_ZONES)) != NULL) { ! kstat_rele(kiosp); return (MDI_SUCCESS); + } if ((kiosp = kstat_create("mdi", 0, ksname, "iopath", KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT)) == NULL) { return (MDI_FAILURE); } ! len = strlen(ksname) + strlen(",err") + 1; ! errksname = kmem_alloc(len, KM_SLEEP); ! (void) snprintf(errksname, len, "%s,err", ksname); ! ! kerrsp = kstat_create("mdi", 0, errksname, "iopath_errors", KSTAT_TYPE_NAMED, sizeof (struct pi_errs) / sizeof (kstat_named_t), 0); if (kerrsp == NULL) { kstat_delete(kiosp); + kmem_free(errksname, len); return (MDI_FAILURE); } nsp = (struct pi_errs *)kerrsp->ks_data; kstat_named_init(&nsp->pi_softerrs, "Soft Errors", KSTAT_DATA_UINT32);
*** 6117,6126 **** --- 6114,6124 ---- mdi_statp->pi_kstat_iostats = kiosp; mdi_statp->pi_kstat_errstats = kerrsp; kstat_install(kiosp); kstat_install(kerrsp); MDI_PI(pip)->pi_kstats = mdi_statp; + kmem_free(errksname, len); return (MDI_SUCCESS); } /* * destroy per-path properties