* The special vdev case is used for hot spares and l2cache devices. Its * sole purpose it to set the vdev state for the associated vdev. To do this, * we make sure that we can open the underlying device, then try to read the * label, and make sure that the label is sane and that it hasn't been * repurposed to another pool. */
| 3414 | * repurposed to another pool. |
| 3415 | */ |
| 3416 | int |
| 3417 | vdev_validate_aux(vdev_t *vd) |
| 3418 | { |
| 3419 | nvlist_t *label; |
| 3420 | uint64_t guid, version; |
| 3421 | uint64_t state; |
| 3422 | |
| 3423 | if (!vdev_readable(vd)) |
| 3424 | return (0); |
| 3425 | |
| 3426 | if ((label = vdev_label_read_config(vd, -1ULL)) == NULL) { |
| 3427 | vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN, |
| 3428 | VDEV_AUX_CORRUPT_DATA); |
| 3429 | return (-1); |
| 3430 | } |
| 3431 | |
| 3432 | if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_VERSION, &version) != 0 || |
| 3433 | !SPA_VERSION_IS_SUPPORTED(version) || |
| 3434 | nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &guid) != 0 || |
| 3435 | guid != vd->vdev_guid || |
| 3436 | nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE, &state) != 0) { |
| 3437 | vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN, |
| 3438 | VDEV_AUX_CORRUPT_DATA); |
| 3439 | nvlist_free(label); |
| 3440 | return (-1); |
| 3441 | } |
| 3442 | |
| 3443 | /* |
| 3444 | * We don't actually check the pool state here. If it's in fact in |
| 3445 | * use by another pool, we update this fact on the fly when requested. |
| 3446 | */ |
| 3447 | nvlist_free(label); |
| 3448 | return (0); |
| 3449 | } |
| 3450 | |
| 3451 | static void |
| 3452 | vdev_destroy_ms_flush_data(vdev_t *vd, dmu_tx_t *tx) |
no test coverage detected