| 1305 | } |
| 1306 | |
| 1307 | int |
| 1308 | vdev_label_write_bootenv(vdev_t *vd, nvlist_t *env) |
| 1309 | { |
| 1310 | zio_t *zio; |
| 1311 | spa_t *spa = vd->vdev_spa; |
| 1312 | vdev_boot_envblock_t *bootenv; |
| 1313 | int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL; |
| 1314 | int error; |
| 1315 | size_t nvsize; |
| 1316 | char *nvbuf; |
| 1317 | |
| 1318 | error = nvlist_size(env, &nvsize, NV_ENCODE_XDR); |
| 1319 | if (error != 0) |
| 1320 | return (SET_ERROR(error)); |
| 1321 | |
| 1322 | if (nvsize >= sizeof (bootenv->vbe_bootenv)) { |
| 1323 | return (SET_ERROR(E2BIG)); |
| 1324 | } |
| 1325 | |
| 1326 | ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); |
| 1327 | |
| 1328 | error = ENXIO; |
| 1329 | for (int c = 0; c < vd->vdev_children; c++) { |
| 1330 | int child_err; |
| 1331 | |
| 1332 | child_err = vdev_label_write_bootenv(vd->vdev_child[c], env); |
| 1333 | /* |
| 1334 | * As long as any of the disks managed to write all of their |
| 1335 | * labels successfully, return success. |
| 1336 | */ |
| 1337 | if (child_err == 0) |
| 1338 | error = child_err; |
| 1339 | } |
| 1340 | |
| 1341 | if (!vd->vdev_ops->vdev_op_leaf || vdev_is_dead(vd) || |
| 1342 | !vdev_writeable(vd)) { |
| 1343 | return (error); |
| 1344 | } |
| 1345 | ASSERT3U(sizeof (*bootenv), ==, VDEV_PAD_SIZE); |
| 1346 | abd_t *abd = abd_alloc_for_io(VDEV_PAD_SIZE, B_TRUE); |
| 1347 | abd_zero(abd, VDEV_PAD_SIZE); |
| 1348 | |
| 1349 | bootenv = abd_borrow_buf_copy(abd, VDEV_PAD_SIZE); |
| 1350 | nvbuf = bootenv->vbe_bootenv; |
| 1351 | nvsize = sizeof (bootenv->vbe_bootenv); |
| 1352 | |
| 1353 | bootenv->vbe_version = fnvlist_lookup_uint64(env, BOOTENV_VERSION); |
| 1354 | switch (bootenv->vbe_version) { |
| 1355 | case VB_RAW: |
| 1356 | if (nvlist_lookup_string(env, GRUB_ENVMAP, &nvbuf) == 0) { |
| 1357 | (void) strlcpy(bootenv->vbe_bootenv, nvbuf, nvsize); |
| 1358 | } |
| 1359 | error = 0; |
| 1360 | break; |
| 1361 | |
| 1362 | case VB_NVLIST: |
| 1363 | error = nvlist_pack(env, &nvbuf, &nvsize, NV_ENCODE_XDR, |
| 1364 | KM_SLEEP); |
no test coverage detected