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