Mercurial > illumos > git > illumos-joyent
changeset 25179:774e1bce00ad
12924 blkdev needs to be better at handling attach failures
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Paul Winder <paul@winders.demon.co.uk>
Approved by: Dan McDonald <danmcd@joyent.com>
author | Jason King <jason.king@joyent.com> |
---|---|
date | Fri, 03 Jul 2020 00:42:14 -0500 |
parents | e3294d77da91 |
children | 8e476c6cec39 |
files | usr/src/uts/common/io/blkdev/blkdev.c |
diffstat | 1 files changed, 32 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/blkdev/blkdev.c Tue Jan 31 01:33:09 2017 +0000 +++ b/usr/src/uts/common/io/blkdev/blkdev.c Fri Jul 03 00:42:14 2020 -0500 @@ -25,6 +25,7 @@ * Copyright 2016 Nexenta Systems, Inc. All rights reserved. * Copyright 2017 The MathWorks, Inc. All rights reserved. * Copyright 2019 Western Digital Corporation. + * Copyright 2020 Joyent, Inc. */ #include <sys/types.h> @@ -228,8 +229,10 @@ static void bd_prop_update_inqstring(dev_info_t *, char *, char *, size_t); static void bd_create_inquiry_props(dev_info_t *, bd_drive_t *); static void bd_create_errstats(bd_t *, int, bd_drive_t *); +static void bd_destroy_errstats(bd_t *); static void bd_errstats_setstr(kstat_named_t *, char *, size_t, char *); static void bd_init_errstats(bd_t *, bd_drive_t *); +static void bd_fini_errstats(bd_t *); static int bd_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); static int bd_attach(dev_info_t *, ddi_attach_cmd_t); @@ -490,6 +493,21 @@ bd->d_errstats->ks_private = bd; kstat_install(bd->d_errstats); + bd_init_errstats(bd, drive); +} + +static void +bd_destroy_errstats(bd_t *bd) +{ + if (bd->d_errstats != NULL) { + bd_fini_errstats(bd); + kstat_delete(bd->d_errstats); + bd->d_errstats = NULL; + } else { + kmem_free(bd->d_kerr, sizeof (struct bd_errstats)); + bd->d_kerr = NULL; + mutex_destroy(&bd->d_errmutex); + } } static void @@ -707,7 +725,6 @@ bd_create_inquiry_props(dip, &drive); bd_create_errstats(bd, inst, &drive); - bd_init_errstats(bd, &drive); bd_update_state(bd); bd->d_queues = kmem_alloc(sizeof (*bd->d_queues) * bd->d_qcount, @@ -732,19 +749,23 @@ drive.d_lun >= 0 ? DDI_NT_BLOCK_CHAN : DDI_NT_BLOCK, CMLB_FAKE_LABEL_ONE_PARTITION, bd->d_cmlbh, 0); if (rv != 0) { + bd_queues_free(bd); + bd_destroy_errstats(bd); cmlb_free_handle(&bd->d_cmlbh); - kmem_cache_destroy(bd->d_cache); - mutex_destroy(&bd->d_ksmutex); - mutex_destroy(&bd->d_ocmutex); - mutex_destroy(&bd->d_statemutex); - cv_destroy(&bd->d_statecv); - bd_queues_free(bd); + if (bd->d_ksp != NULL) { kstat_delete(bd->d_ksp); bd->d_ksp = NULL; } else { kmem_free(bd->d_kiop, sizeof (kstat_io_t)); + bd->d_kiop = NULL; } + + kmem_cache_destroy(bd->d_cache); + cv_destroy(&bd->d_statecv); + mutex_destroy(&bd->d_statemutex); + mutex_destroy(&bd->d_ocmutex); + mutex_destroy(&bd->d_ksmutex); ddi_soft_state_free(bd_state, inst); return (DDI_FAILURE); } @@ -797,6 +818,7 @@ default: return (DDI_FAILURE); } + if (bd->d_ksp != NULL) { kstat_delete(bd->d_ksp); bd->d_ksp = NULL; @@ -804,15 +826,7 @@ kmem_free(bd->d_kiop, sizeof (kstat_io_t)); } - if (bd->d_errstats != NULL) { - bd_fini_errstats(bd); - kstat_delete(bd->d_errstats); - bd->d_errstats = NULL; - } else { - kmem_free(bd->d_kerr, sizeof (struct bd_errstats)); - mutex_destroy(&bd->d_errmutex); - } - + bd_destroy_errstats(bd); cmlb_detach(bd->d_cmlbh, 0); cmlb_free_handle(&bd->d_cmlbh); if (bd->d_devid) @@ -2052,11 +2066,12 @@ ddi_set_parent_data(child, hdl); hdl->h_child = child; - if (ndi_devi_online(child, 0) == NDI_FAILURE) { + if (ndi_devi_online(child, 0) != NDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: failed bringing node %s@%s online", ddi_driver_name(dip), ddi_get_instance(dip), hdl->h_name, hdl->h_addr); (void) ndi_devi_free(child); + hdl->h_child = NULL; return (DDI_FAILURE); }