From e22f3c70af4c67210535f4d9fdc7ff7e77b078df Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Thu, 29 Mar 2018 16:11:54 +0300 Subject: [PATCH] loader: zfs_bootfs() needs to use config pool txg for boot device illumos issue #9423 --- usr/src/boot/Makefile.version | 2 +- usr/src/boot/sys/boot/zfs/zfs.c | 41 +++++++------------------------- usr/src/boot/sys/boot/zfs/zfsimpl.c | 4 ++++ usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h | 1 + 4 files changed, 14 insertions(+), 34 deletions(-) diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version index 6b7ed90fc4..4b2bde6131 100644 --- a/usr/src/boot/Makefile.version +++ b/usr/src/boot/Makefile.version @@ -33,4 +33,4 @@ LOADER_VERSION = 1.1 # Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes. # The version is processed from left to right, the version number can only # be increased. -BOOT_VERSION = $(LOADER_VERSION)-2018.2.24.1 +BOOT_VERSION = $(LOADER_VERSION)-2018.3.29.1 diff --git a/usr/src/boot/sys/boot/zfs/zfs.c b/usr/src/boot/sys/boot/zfs/zfs.c index 3efd491431..9a4b944178 100644 --- a/usr/src/boot/sys/boot/zfs/zfs.c +++ b/usr/src/boot/sys/boot/zfs/zfs.c @@ -704,8 +704,6 @@ zfs_bootfs(void *zdev) struct zfs_devdesc *dev = (struct zfs_devdesc *)zdev; uint64_t objnum; spa_t *spa; - vdev_t *vdev; - vdev_t *kid; int n; buf[0] = '\0'; @@ -726,37 +724,14 @@ zfs_bootfs(void *zdev) return (buf); } - STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink) { - STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) { - /* use this kid? */ - if (kid->v_state == VDEV_STATE_HEALTHY && - kid->v_phys_path != NULL) { - break; - } - } - if (kid != NULL) { - vdev = kid; - break; - } - if (vdev->v_state == VDEV_STATE_HEALTHY && - vdev->v_phys_path != NULL) { - break; - } - } - - /* - * since this pool was used to read in the kernel and boot archive, - * there has to be at least one healthy vdev, therefore vdev - * can not be NULL. - */ /* Set the environment. */ snprintf(buf, sizeof (buf), "%s/%llu", spa->spa_name, (unsigned long long)objnum); setenv("zfs-bootfs", buf, 1); - if (vdev->v_phys_path != NULL) - setenv("bootpath", vdev->v_phys_path, 1); - if (vdev->v_devid != NULL) - setenv("diskdevid", vdev->v_devid, 1); + if (spa->spa_boot_vdev->v_phys_path != NULL) + setenv("bootpath", spa->spa_boot_vdev->v_phys_path, 1); + if (spa->spa_boot_vdev->v_devid != NULL) + setenv("diskdevid", spa->spa_boot_vdev->v_devid, 1); /* * Build the command line string. Once our kernel will read @@ -766,14 +741,14 @@ zfs_bootfs(void *zdev) snprintf(buf, sizeof(buf), "zfs-bootfs=%s/%llu", spa->spa_name, (unsigned long long)objnum); n = strlen(buf); - if (vdev->v_phys_path != NULL) { + if (spa->spa_boot_vdev->v_phys_path != NULL) { snprintf(buf+n, sizeof (buf) - n, ",bootpath=\"%s\"", - vdev->v_phys_path); + spa->spa_boot_vdev->v_phys_path); n = strlen(buf); } - if (vdev->v_devid != NULL) { + if (spa->spa_boot_vdev->v_devid != NULL) { snprintf(buf+n, sizeof (buf) - n, ",diskdevid=\"%s\"", - vdev->v_devid); + spa->spa_boot_vdev->v_devid); } return (buf); } diff --git a/usr/src/boot/sys/boot/zfs/zfsimpl.c b/usr/src/boot/sys/boot/zfs/zfsimpl.c index 26654c0469..73c9d52e0a 100644 --- a/usr/src/boot/sys/boot/zfs/zfsimpl.c +++ b/usr/src/boot/sys/boot/zfs/zfsimpl.c @@ -1108,6 +1108,10 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap) return (EIO); } + /* Record boot vdev for spa. */ + if (is_newer == 1) + spa->spa_boot_vdev = vdev; + /* * Re-evaluate top-level vdev state. */ diff --git a/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h b/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h index d0cdbf61d8..331b984bd4 100644 --- a/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h +++ b/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h @@ -1551,6 +1551,7 @@ typedef struct spa { vdev_list_t spa_vdevs; /* list of all toplevel vdevs */ objset_phys_t spa_mos; /* MOS for this pool */ int spa_inited; /* initialized */ + vdev_t *spa_boot_vdev; /* boot device for kernel */ } spa_t; static void decode_embedded_bp_compressed(const blkptr_t *, void *); -- 2.11.4.GIT