Print this page
NEX-18492 Disk can't be restored in pool if disappeared under active I/O
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-18264 devi_detach_node() should be aware that device class can be NULL
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-18214 unplug of multipathed disks doesn't produce EC_DEV_REMOVE/ESC_DISK event (fix build)
NEX-18214 unplug of multipathed disks doesn't produce EC_DEV_REMOVE/ESC_DISK event
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Revert "NEX-18214 unplug of multipathed disks doesn't produce EC_DEV_REMOVE/ESC_DISK event"
This reverts commit b0f7e47b60b115c1bb6c07dc5aa150cc519790e7.
NEX-18214 unplug of multipathed disks doesn't produce EC_DEV_REMOVE/ESC_DISK event
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
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-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>
NEX-15146 Retired device is not listed after appliance reboot
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Dmitry Savitsky <dmitry.savitsky@nexenta.com>
OS-164 Add ddi property to allow device
retire to succeed when device is in use

*** 16,30 **** * 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 2012 Nexenta Systems, Inc. All rights reserved. * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2016 by Delphix. All rights reserved. */ #include <sys/note.h> #include <sys/t_lock.h> --- 16,31 ---- * 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 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright 2018 Nexenta Systems, Inc. * Copyright (c) 2016 by Delphix. All rights reserved. */ #include <sys/note.h> #include <sys/t_lock.h>
*** 169,182 **** * 3rd party driver depends on identify(9e) being called. */ int identify_9e = 0; /* ! * Add flag so behaviour of preventing attach for retired persistant nodes ! * can be disabled. */ ! int retire_prevents_attach = 1; int mtc_off; /* turn off mt config */ int quiesce_debug = 0; --- 170,182 ---- * 3rd party driver depends on identify(9e) being called. */ int identify_9e = 0; /* ! * Don't prevent attaching retired devices by default. */ ! int retire_prevents_attach = 0; int mtc_off; /* turn off mt config */ int quiesce_debug = 0;
*** 483,497 **** mutex_destroy(&(devi->devi_ct_lock)); RIO_TRACE((CE_NOTE, "i_ddi_free_node: destroyed all contract fields: " "dip=%p, name=%s", (void *)dip, devi->devi_node_name)); kmem_free(devi->devi_node_name, strlen(devi->devi_node_name) + 1); - - /* free event data */ - if (devi->devi_ev_path) - kmem_free(devi->devi_ev_path, MAXPATHLEN); - kmem_cache_free(ddi_node_cache, devi); } /* --- 483,492 ----
*** 1358,1369 **** int rv; ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip))); ASSERT(i_ddi_node_state(dip) == DS_ATTACHED); ! /* check references */ ! if (DEVI(dip)->devi_ref) return (DDI_FAILURE); NDI_CONFIG_DEBUG((CE_CONT, "detach_node: 0x%p(%s%d)\n", (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip))); --- 1353,1364 ---- int rv; ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip))); ASSERT(i_ddi_node_state(dip) == DS_ATTACHED); ! /* Check references */ ! if (DEVI(dip)->devi_ref != 0 && !DEVI_IS_GONE(dip)) return (DDI_FAILURE); NDI_CONFIG_DEBUG((CE_CONT, "detach_node: 0x%p(%s%d)\n", (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
*** 1461,1470 **** --- 1456,1467 ---- static int postattach_node(dev_info_t *dip) { int rval; + DEVI_UNSET_GONE(dip); + /* * For hotplug busses like USB, it's possible that devices * are removed but dip is still around. We don't want to * run dacf routines as part of detach failure recovery. *
*** 3819,3830 **** * with argument "ioc@xxxxxxx,yyyyyyy:port=1". After configuring * the ioc, look for minor node dhcp. If not found, pass ":dhcp" * to ioc's bus_config entry point. */ int ! resolve_pathname(char *pathname, ! dev_info_t **dipp, dev_t *devtp, int *spectypep) { int error; dev_info_t *parent, *child; struct pathname pn; char *component, *config_name; --- 3816,3827 ---- * with argument "ioc@xxxxxxx,yyyyyyy:port=1". After configuring * the ioc, look for minor node dhcp. If not found, pass ":dhcp" * to ioc's bus_config entry point. */ int ! resolve_pathname(char *pathname, dev_info_t **dipp, dev_t *devtp, ! int *spectypep) { int error; dev_info_t *parent, *child; struct pathname pn; char *component, *config_name;
*** 4598,4610 **** /* * report device status */ static void ! i_ndi_devi_report_status_change(dev_info_t *dip, char *path) { ! char *status; if (!DEVI_NEED_REPORT(dip) || (i_ddi_node_state(dip) < DS_INITIALIZED) || ndi_dev_is_hidden_node(dip)) { return; --- 4595,4607 ---- /* * report device status */ static void ! i_ndi_devi_report_status_change(dev_info_t *dip) { ! const char *status; if (!DEVI_NEED_REPORT(dip) || (i_ddi_node_state(dip) < DS_INITIALIZED) || ndi_dev_is_hidden_node(dip)) { return;
*** 4627,4647 **** status = "online"; } else { status = "unknown"; } ! if (path == NULL) { ! path = kmem_alloc(MAXPATHLEN, KM_SLEEP); ! cmn_err(CE_CONT, "?%s (%s%d) %s\n", ! ddi_pathname(dip, path), ddi_driver_name(dip), ddi_get_instance(dip), status); - kmem_free(path, MAXPATHLEN); - } else { - cmn_err(CE_CONT, "?%s (%s%d) %s\n", - path, ddi_driver_name(dip), - ddi_get_instance(dip), status); - } mutex_enter(&(DEVI(dip)->devi_lock)); DEVI_REPORT_DONE(dip); mutex_exit(&(DEVI(dip)->devi_lock)); } --- 4624,4635 ---- status = "online"; } else { status = "unknown"; } ! cmn_err(CE_CONT, "?%s%d %s\n", ddi_driver_name(dip), ddi_get_instance(dip), status); mutex_enter(&(DEVI(dip)->devi_lock)); DEVI_REPORT_DONE(dip); mutex_exit(&(DEVI(dip)->devi_lock)); }
*** 5225,5235 **** (void) ddi_remove_child(dip, 0); } return (NDI_FAILURE); } ! i_ndi_devi_report_status_change(dip, NULL); /* * log an event, but not during devfs lookups in which case * NDI_NO_EVENT is set. */ --- 5213,5223 ---- (void) ddi_remove_child(dip, 0); } return (NDI_FAILURE); } ! i_ndi_devi_report_status_change(dip); /* * log an event, but not during devfs lookups in which case * NDI_NO_EVENT is set. */
*** 5763,5772 **** --- 5751,5771 ---- break; default: ASSERT(retval == LDI_EV_NONE); } + /* + * In order to allow a device retire to succeed that is in use + */ + + if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, + "allow-unconstrained-retire", 0) == 1 && failure == 0) { + RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): setting " + "constraint flag due to 'allow-unconstrained-retire' " + "property on dip=%p", (void *)dip)); + constraint = 1; + } out: mutex_enter(&(DEVI(dip)->devi_lock)); if ((DEVI(dip)->devi_flags & DEVI_RETIRING) && failure) { RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): setting " "BLOCKED flag. dip=%p", (void *)dip));
*** 5928,5959 **** DEVI_SET_DEVICE_OFFLINE(dip); mutex_exit(&(DEVI(dip)->devi_lock)); } if (i_ddi_node_state(dip) == DS_INITIALIZED) { - struct dev_info *devi = DEVI(dip); - - if (devi->devi_ev_path == NULL) { - devi->devi_ev_path = kmem_alloc(MAXPATHLEN, KM_SLEEP); - (void) ddi_pathname(dip, devi->devi_ev_path); - } if (flags & NDI_DEVI_OFFLINE) ! i_ndi_devi_report_status_change(dip, ! devi->devi_ev_path); if (need_remove_event(dip, flags)) { - /* - * instance and path data are lost in call to - * ddi_uninitchild - */ - devi->devi_ev_instance = ddi_get_instance(dip); - mutex_enter(&(DEVI(dip)->devi_lock)); DEVI_SET_EVREMOVE(dip); mutex_exit(&(DEVI(dip)->devi_lock)); } } if (flags & (NDI_UNCONFIG | NDI_DEVI_REMOVE)) { ret = ddi_uninitchild(dip); if (ret == NDI_SUCCESS) { /* --- 5927,5961 ---- DEVI_SET_DEVICE_OFFLINE(dip); mutex_exit(&(DEVI(dip)->devi_lock)); } if (i_ddi_node_state(dip) == DS_INITIALIZED) { if (flags & NDI_DEVI_OFFLINE) ! i_ndi_devi_report_status_change(dip); if (need_remove_event(dip, flags)) { mutex_enter(&(DEVI(dip)->devi_lock)); DEVI_SET_EVREMOVE(dip); mutex_exit(&(DEVI(dip)->devi_lock)); + + post_event = (flags & NDI_DEVI_REMOVE) || + DEVI_IS_GONE(dip); } + + if (post_event) { + /* + * Instance and path data are lost in call to + * ddi_uninitchild. + */ + path = kmem_alloc(MAXPATHLEN, KM_SLEEP); + (void) ddi_pathname(dip, path); + class = i_ddi_strdup(i_ddi_devi_class(dip), KM_SLEEP); + driver = i_ddi_strdup((char *)ddi_driver_name(dip), + KM_SLEEP); + instance = ddi_get_instance(dip); } + } if (flags & (NDI_UNCONFIG | NDI_DEVI_REMOVE)) { ret = ddi_uninitchild(dip); if (ret == NDI_SUCCESS) { /*
*** 5962,6011 **** * reattached. */ if (!ndi_dev_is_persistent_node(dip)) flags |= NDI_DEVI_REMOVE; ! if (flags & NDI_DEVI_REMOVE) { ! /* ! * NOTE: If there is a consumer of LDI events, ! * ddi_uninitchild above would have failed ! * because of active devi_ref from ldi_open(). ! */ ! ! if (DEVI_EVREMOVE(dip)) { ! path = i_ddi_strdup( ! DEVI(dip)->devi_ev_path, ! KM_SLEEP); ! class = ! i_ddi_strdup(i_ddi_devi_class(dip), ! KM_SLEEP); ! driver = ! i_ddi_strdup( ! (char *)ddi_driver_name(dip), ! KM_SLEEP); ! instance = DEVI(dip)->devi_ev_instance; ! post_event = 1; } ! ret = ddi_remove_child(dip, 0); ! if (post_event && ret == NDI_SUCCESS) { ! /* Generate EC_DEVFS_DEVI_REMOVE */ (void) i_log_devfs_remove_devinfo(path, class, driver, instance, flags); } - } ! } ! } ! ! if (path) ! strfree(path); ! if (class) strfree(class); ! if (driver) strfree(driver); return (ret); } /* * unconfigure immediate children of bus nexus device --- 5964,5995 ---- * reattached. */ if (!ndi_dev_is_persistent_node(dip)) flags |= NDI_DEVI_REMOVE; ! if (flags & NDI_DEVI_REMOVE) ! ret = ddi_remove_child(dip, 0); } + } ! if (ret == NDI_SUCCESS && post_event) { ! /* Generate EC_DEVFS/ESC_DEVFS_DEVI_REMOVE */ (void) i_log_devfs_remove_devinfo(path, class, driver, instance, flags); } ! if (path != NULL) ! kmem_free(path, MAXPATHLEN); ! if (class != NULL) strfree(class); ! if (driver != NULL) strfree(driver); + /* Clean the flag on successful detach */ + if (ret == NDI_SUCCESS) + DEVI_UNSET_GONE(dip); + return (ret); } /* * unconfigure immediate children of bus nexus device
*** 6577,6586 **** --- 6561,6573 ---- ASSERT(pdip); flags |= NDI_DEVI_OFFLINE; + if (flags & NDI_DEVI_GONE) + DEVI_SET_GONE(dip); + /* * If child is pHCI and vHCI and pHCI are not siblings then enter vHCI * before parent(pHCI) to avoid deadlock with mpxio Client power * management operations. */
*** 8098,8108 **** LOCK_DEV_OPS(&dnp->dn_lock); dnp->dn_flags |= DN_DRIVER_HELD; dnp->dn_head = dip; UNLOCK_DEV_OPS(&dnp->dn_lock); ! i_ndi_devi_report_status_change(dip, NULL); return (dip); } /* --- 8085,8095 ---- LOCK_DEV_OPS(&dnp->dn_lock); dnp->dn_flags |= DN_DRIVER_HELD; dnp->dn_head = dip; UNLOCK_DEV_OPS(&dnp->dn_lock); ! i_ndi_devi_report_status_change(dip); return (dip); } /*
*** 8145,8155 **** DEVI_SET_DEVICE_REMOVED(dip); DEVI_SET_EVREMOVE(dip); /* this clears EVADD too */ mutex_exit(&(DEVI(dip)->devi_lock)); /* report remove (as 'removed') */ ! i_ndi_devi_report_status_change(dip, NULL); /* * Invalidate the cache to ensure accurate * (di_state() & DI_DEVICE_REMOVED). */ --- 8132,8142 ---- DEVI_SET_DEVICE_REMOVED(dip); DEVI_SET_EVREMOVE(dip); /* this clears EVADD too */ mutex_exit(&(DEVI(dip)->devi_lock)); /* report remove (as 'removed') */ ! i_ndi_devi_report_status_change(dip); /* * Invalidate the cache to ensure accurate * (di_state() & DI_DEVICE_REMOVED). */
*** 8182,8192 **** DEVI_SET_DEVICE_REINSERTED(dip); DEVI_SET_EVADD(dip); /* this clears EVREMOVE too */ mutex_exit(&(DEVI(dip)->devi_lock)); /* report insert (as 'online') */ ! i_ndi_devi_report_status_change(dip, NULL); /* * Invalidate the cache to ensure accurate * (di_state() & DI_DEVICE_REMOVED). */ --- 8169,8179 ---- DEVI_SET_DEVICE_REINSERTED(dip); DEVI_SET_EVADD(dip); /* this clears EVREMOVE too */ mutex_exit(&(DEVI(dip)->devi_lock)); /* report insert (as 'online') */ ! i_ndi_devi_report_status_change(dip); /* * Invalidate the cache to ensure accurate * (di_state() & DI_DEVICE_REMOVED). */