* Add a device to a storage pool. */
| 6428 | * Add a device to a storage pool. |
| 6429 | */ |
| 6430 | int |
| 6431 | spa_vdev_add(spa_t *spa, nvlist_t *nvroot) |
| 6432 | { |
| 6433 | uint64_t txg, ndraid = 0; |
| 6434 | int error; |
| 6435 | vdev_t *rvd = spa->spa_root_vdev; |
| 6436 | vdev_t *vd, *tvd; |
| 6437 | nvlist_t **spares, **l2cache; |
| 6438 | uint_t nspares, nl2cache; |
| 6439 | |
| 6440 | ASSERT(spa_writeable(spa)); |
| 6441 | |
| 6442 | txg = spa_vdev_enter(spa); |
| 6443 | |
| 6444 | if ((error = spa_config_parse(spa, &vd, nvroot, NULL, 0, |
| 6445 | VDEV_ALLOC_ADD)) != 0) |
| 6446 | return (spa_vdev_exit(spa, NULL, txg, error)); |
| 6447 | |
| 6448 | spa->spa_pending_vdev = vd; /* spa_vdev_exit() will clear this */ |
| 6449 | |
| 6450 | if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, &spares, |
| 6451 | &nspares) != 0) |
| 6452 | nspares = 0; |
| 6453 | |
| 6454 | if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, &l2cache, |
| 6455 | &nl2cache) != 0) |
| 6456 | nl2cache = 0; |
| 6457 | |
| 6458 | if (vd->vdev_children == 0 && nspares == 0 && nl2cache == 0) |
| 6459 | return (spa_vdev_exit(spa, vd, txg, EINVAL)); |
| 6460 | |
| 6461 | if (vd->vdev_children != 0 && |
| 6462 | (error = vdev_create(vd, txg, B_FALSE)) != 0) { |
| 6463 | return (spa_vdev_exit(spa, vd, txg, error)); |
| 6464 | } |
| 6465 | |
| 6466 | /* |
| 6467 | * The virtual dRAID spares must be added after vdev tree is created |
| 6468 | * and the vdev guids are generated. The guid of their assoicated |
| 6469 | * dRAID is stored in the config and used when opening the spare. |
| 6470 | */ |
| 6471 | if ((error = vdev_draid_spare_create(nvroot, vd, &ndraid, |
| 6472 | rvd->vdev_children)) == 0) { |
| 6473 | if (ndraid > 0 && nvlist_lookup_nvlist_array(nvroot, |
| 6474 | ZPOOL_CONFIG_SPARES, &spares, &nspares) != 0) |
| 6475 | nspares = 0; |
| 6476 | } else { |
| 6477 | return (spa_vdev_exit(spa, vd, txg, error)); |
| 6478 | } |
| 6479 | |
| 6480 | /* |
| 6481 | * We must validate the spares and l2cache devices after checking the |
| 6482 | * children. Otherwise, vdev_inuse() will blindly overwrite the spare. |
| 6483 | */ |
| 6484 | if ((error = spa_validate_aux(spa, nvroot, txg, VDEV_ALLOC_ADD)) != 0) |
| 6485 | return (spa_vdev_exit(spa, vd, txg, error)); |
| 6486 | |
| 6487 | /* |