* Recursively copy vdev paths from one vdev to another. Source and destination * vdev trees must have same geometry otherwise return error. Intended to copy * paths from userland config into MOS config. */
| 2256 | * paths from userland config into MOS config. |
| 2257 | */ |
| 2258 | int |
| 2259 | vdev_copy_path_strict(vdev_t *svd, vdev_t *dvd) |
| 2260 | { |
| 2261 | if ((svd->vdev_ops == &vdev_missing_ops) || |
| 2262 | (svd->vdev_ishole && dvd->vdev_ishole) || |
| 2263 | (dvd->vdev_ops == &vdev_indirect_ops)) |
| 2264 | return (0); |
| 2265 | |
| 2266 | if (svd->vdev_ops != dvd->vdev_ops) { |
| 2267 | vdev_dbgmsg(svd, "vdev_copy_path: vdev type mismatch: %s != %s", |
| 2268 | svd->vdev_ops->vdev_op_type, dvd->vdev_ops->vdev_op_type); |
| 2269 | return (SET_ERROR(EINVAL)); |
| 2270 | } |
| 2271 | |
| 2272 | if (svd->vdev_guid != dvd->vdev_guid) { |
| 2273 | vdev_dbgmsg(svd, "vdev_copy_path: guids mismatch (%llu != " |
| 2274 | "%llu)", (u_longlong_t)svd->vdev_guid, |
| 2275 | (u_longlong_t)dvd->vdev_guid); |
| 2276 | return (SET_ERROR(EINVAL)); |
| 2277 | } |
| 2278 | |
| 2279 | if (svd->vdev_children != dvd->vdev_children) { |
| 2280 | vdev_dbgmsg(svd, "vdev_copy_path: children count mismatch: " |
| 2281 | "%llu != %llu", (u_longlong_t)svd->vdev_children, |
| 2282 | (u_longlong_t)dvd->vdev_children); |
| 2283 | return (SET_ERROR(EINVAL)); |
| 2284 | } |
| 2285 | |
| 2286 | for (uint64_t i = 0; i < svd->vdev_children; i++) { |
| 2287 | int error = vdev_copy_path_strict(svd->vdev_child[i], |
| 2288 | dvd->vdev_child[i]); |
| 2289 | if (error != 0) |
| 2290 | return (error); |
| 2291 | } |
| 2292 | |
| 2293 | if (svd->vdev_ops->vdev_op_leaf) |
| 2294 | vdev_copy_path_impl(svd, dvd); |
| 2295 | |
| 2296 | return (0); |
| 2297 | } |
| 2298 | |
| 2299 | static void |
| 2300 | vdev_copy_path_search(vdev_t *stvd, vdev_t *dvd) |
no test coverage detected