* Add virtual dRAID spares to the list of valid spares. In order to accomplish * this the existing array must be freed and reallocated with the additional * entries. */
| 1864 | * entries. |
| 1865 | */ |
| 1866 | int |
| 1867 | vdev_draid_spare_create(nvlist_t *nvroot, vdev_t *vd, uint64_t *ndraidp, |
| 1868 | uint64_t next_vdev_id) |
| 1869 | { |
| 1870 | uint64_t draid_nspares = 0; |
| 1871 | uint64_t ndraid = 0; |
| 1872 | int error; |
| 1873 | |
| 1874 | for (uint64_t i = 0; i < vd->vdev_children; i++) { |
| 1875 | vdev_t *cvd = vd->vdev_child[i]; |
| 1876 | |
| 1877 | if (cvd->vdev_ops == &vdev_draid_ops) { |
| 1878 | vdev_draid_config_t *vdc = cvd->vdev_tsd; |
| 1879 | draid_nspares += vdc->vdc_nspares; |
| 1880 | ndraid++; |
| 1881 | } |
| 1882 | } |
| 1883 | |
| 1884 | if (draid_nspares == 0) { |
| 1885 | *ndraidp = ndraid; |
| 1886 | return (0); |
| 1887 | } |
| 1888 | |
| 1889 | nvlist_t **old_spares, **new_spares; |
| 1890 | uint_t old_nspares; |
| 1891 | error = nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, |
| 1892 | &old_spares, &old_nspares); |
| 1893 | if (error) |
| 1894 | old_nspares = 0; |
| 1895 | |
| 1896 | /* Allocate memory and copy of the existing spares. */ |
| 1897 | new_spares = kmem_alloc(sizeof (nvlist_t *) * |
| 1898 | (draid_nspares + old_nspares), KM_SLEEP); |
| 1899 | for (uint_t i = 0; i < old_nspares; i++) |
| 1900 | new_spares[i] = fnvlist_dup(old_spares[i]); |
| 1901 | |
| 1902 | /* Add new distributed spares to ZPOOL_CONFIG_SPARES. */ |
| 1903 | uint64_t n = old_nspares; |
| 1904 | for (uint64_t vdev_id = 0; vdev_id < vd->vdev_children; vdev_id++) { |
| 1905 | vdev_t *cvd = vd->vdev_child[vdev_id]; |
| 1906 | char path[64]; |
| 1907 | |
| 1908 | if (cvd->vdev_ops != &vdev_draid_ops) |
| 1909 | continue; |
| 1910 | |
| 1911 | vdev_draid_config_t *vdc = cvd->vdev_tsd; |
| 1912 | uint64_t nspares = vdc->vdc_nspares; |
| 1913 | uint64_t nparity = vdc->vdc_nparity; |
| 1914 | |
| 1915 | for (uint64_t spare_id = 0; spare_id < nspares; spare_id++) { |
| 1916 | bzero(path, sizeof (path)); |
| 1917 | (void) snprintf(path, sizeof (path) - 1, |
| 1918 | "%s%llu-%llu-%llu", VDEV_TYPE_DRAID, |
| 1919 | (u_longlong_t)nparity, |
| 1920 | (u_longlong_t)next_vdev_id + vdev_id, |
| 1921 | (u_longlong_t)spare_id); |
| 1922 | |
| 1923 | nvlist_t *spare = fnvlist_alloc(); |
no test coverage detected