diff options
Diffstat (limited to 'usr/src/lib/libzfs/common/libzfs_pool.c')
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_pool.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c index bdb7f93cab..b7c95489c8 100644 --- a/usr/src/lib/libzfs/common/libzfs_pool.c +++ b/usr/src/lib/libzfs/common/libzfs_pool.c @@ -3046,7 +3046,7 @@ zpool_vdev_attach(zpool_handle_t *zhp, zfs_cmd_t zc = { 0 }; char msg[1024]; int ret; - nvlist_t *tgt; + nvlist_t *tgt, *newvd; boolean_t avail_spare, l2cache, islog; uint64_t val; char *newname; @@ -3090,14 +3090,14 @@ zpool_vdev_attach(zpool_handle_t *zhp, if ((newname = zpool_vdev_name(NULL, NULL, child[0], 0)) == NULL) return (-1); + newvd = zpool_find_vdev(zhp, newname, &avail_spare, &l2cache, NULL); /* * If the target is a hot spare that has been swapped in, we can only * replace it with another hot spare. */ if (replacing && nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 && - (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache, - NULL) == NULL || !avail_spare) && + (newvd == NULL || !avail_spare) && is_replacing_spare(config_root, tgt, 1)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "can only be replaced by another hot spare")); @@ -3107,6 +3107,11 @@ zpool_vdev_attach(zpool_handle_t *zhp, free(newname); + if (replacing && avail_spare && !vdev_is_online(newvd)) { + (void) zpool_standard_error(hdl, ENXIO, msg); + return (-1); + } + if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0) return (-1); |