* Mark the given vdev faulted. A faulted vdev behaves as if the device could * not be opened, and no I/O is attempted. */
| 3604 | * not be opened, and no I/O is attempted. |
| 3605 | */ |
| 3606 | int |
| 3607 | vdev_fault(spa_t *spa, uint64_t guid, vdev_aux_t aux) |
| 3608 | { |
| 3609 | vdev_t *vd, *tvd; |
| 3610 | |
| 3611 | spa_vdev_state_enter(spa, SCL_NONE); |
| 3612 | |
| 3613 | if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) |
| 3614 | return (spa_vdev_state_exit(spa, NULL, SET_ERROR(ENODEV))); |
| 3615 | |
| 3616 | if (!vd->vdev_ops->vdev_op_leaf) |
| 3617 | return (spa_vdev_state_exit(spa, NULL, SET_ERROR(ENOTSUP))); |
| 3618 | |
| 3619 | tvd = vd->vdev_top; |
| 3620 | |
| 3621 | /* |
| 3622 | * If user did a 'zpool offline -f' then make the fault persist across |
| 3623 | * reboots. |
| 3624 | */ |
| 3625 | if (aux == VDEV_AUX_EXTERNAL_PERSIST) { |
| 3626 | /* |
| 3627 | * There are two kinds of forced faults: temporary and |
| 3628 | * persistent. Temporary faults go away at pool import, while |
| 3629 | * persistent faults stay set. Both types of faults can be |
| 3630 | * cleared with a zpool clear. |
| 3631 | * |
| 3632 | * We tell if a vdev is persistently faulted by looking at the |
| 3633 | * ZPOOL_CONFIG_AUX_STATE nvpair. If it's set to "external" at |
| 3634 | * import then it's a persistent fault. Otherwise, it's |
| 3635 | * temporary. We get ZPOOL_CONFIG_AUX_STATE set to "external" |
| 3636 | * by setting vd.vdev_stat.vs_aux to VDEV_AUX_EXTERNAL. This |
| 3637 | * tells vdev_config_generate() (which gets run later) to set |
| 3638 | * ZPOOL_CONFIG_AUX_STATE to "external" in the nvlist. |
| 3639 | */ |
| 3640 | vd->vdev_stat.vs_aux = VDEV_AUX_EXTERNAL; |
| 3641 | vd->vdev_tmpoffline = B_FALSE; |
| 3642 | aux = VDEV_AUX_EXTERNAL; |
| 3643 | } else { |
| 3644 | vd->vdev_tmpoffline = B_TRUE; |
| 3645 | } |
| 3646 | |
| 3647 | /* |
| 3648 | * We don't directly use the aux state here, but if we do a |
| 3649 | * vdev_reopen(), we need this value to be present to remember why we |
| 3650 | * were faulted. |
| 3651 | */ |
| 3652 | vd->vdev_label_aux = aux; |
| 3653 | |
| 3654 | /* |
| 3655 | * Faulted state takes precedence over degraded. |
| 3656 | */ |
| 3657 | vd->vdev_delayed_close = B_FALSE; |
| 3658 | vd->vdev_faulted = 1ULL; |
| 3659 | vd->vdev_degraded = 0ULL; |
| 3660 | vdev_set_state(vd, B_FALSE, VDEV_STATE_FAULTED, aux); |
| 3661 | |
| 3662 | /* |
| 3663 | * If this device has the only valid copy of the data, then |
no test coverage detected