diff options
author | Eric Taylor <Eric.Taylor@Sun.COM> | 2008-10-20 08:51:30 -0600 |
---|---|---|
committer | Eric Taylor <Eric.Taylor@Sun.COM> | 2008-10-20 08:51:30 -0600 |
commit | 4d04273f2ee96d881d072f95c50570e17dc3a635 (patch) | |
tree | 6a11e2bbfe141eb12a6ffa3387b306b9b27e4bcb /usr/src/uts/common/fs/zfs/vdev.c | |
parent | 5b17e9bd2e8746f9025fdb928568a44b58c45dbf (diff) | |
download | illumos-gate-4d04273f2ee96d881d072f95c50570e17dc3a635.tar.gz |
6752810 deadlock when trying to online missing boot drive
Diffstat (limited to 'usr/src/uts/common/fs/zfs/vdev.c')
-rw-r--r-- | usr/src/uts/common/fs/zfs/vdev.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/usr/src/uts/common/fs/zfs/vdev.c b/usr/src/uts/common/fs/zfs/vdev.c index 2b0ad52561..240f955ea2 100644 --- a/usr/src/uts/common/fs/zfs/vdev.c +++ b/usr/src/uts/common/fs/zfs/vdev.c @@ -1642,7 +1642,7 @@ vdev_fault(spa_t *spa, uint64_t guid) vdev_set_state(vd, B_FALSE, VDEV_STATE_FAULTED, VDEV_AUX_ERR_EXCEEDED); /* - * If marking the vdev as faulted cause the top-level vdev to become + * If marking the vdev as faulted causes the top-level vdev to become * unavailable, then back off and simply mark the vdev as degraded * instead. */ @@ -1708,6 +1708,27 @@ vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *newstate) { vdev_t *vd; + if (spa_is_root(spa)) { + /* + * if we're trying to online a device that's part of + * the root pool, trigger an attach (if any) with only + * the SCL_STATE lock held in order to avoid a deadlock + * where modload tries to read from the disk + */ + spa_config_enter(spa, SCL_STATE, FTAG, RW_WRITER); + if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) { + spa_config_exit(spa, SCL_STATE, FTAG); + return (ENODEV); + } + if (!vd->vdev_ops->vdev_op_leaf) { + spa_config_exit(spa, SCL_STATE, FTAG); + return (ENOTSUP); + } + vdev_close(vd); + vdev_open(vd); + spa_config_exit(spa, SCL_STATE, FTAG); + } + spa_vdev_state_enter(spa); if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) |