git: af3c16f3421e - stable/12 - loader: can not read zfs pool with slog removed

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Fri, 08 Oct 2021 06:10:53 UTC
The branch stable/12 has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=af3c16f3421e36a5f97cabcbb23efa51505622c2

commit af3c16f3421e36a5f97cabcbb23efa51505622c2
Author:     Toomas Soome <tsoome@FreeBSD.org>
AuthorDate: 2020-06-26 21:21:35 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2021-10-08 05:24:26 +0000

    loader: can not read zfs pool with slog removed
    
    The vdev_init() does check for "known" vdev types, the [log] device removal will create "hole"
    device, but vdev_init() does not allow it.
    
    (cherry picked from commit b93b14dc756861d543249f3d04b80809055fdd61)
---
 stand/libsa/zfs/zfsimpl.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c
index a33d2bdf8db6..fe04d3b1db21 100644
--- a/stand/libsa/zfs/zfsimpl.c
+++ b/stand/libsa/zfs/zfsimpl.c
@@ -766,6 +766,13 @@ vdev_disk_read(vdev_t *vdev, const blkptr_t *bp, void *buf,
 	    offset + VDEV_LABEL_START_SIZE, bytes));
 }
 
+static int
+vdev_missing_read(vdev_t *vdev __unused, const blkptr_t *bp __unused,
+    void *buf __unused, off_t offset __unused, size_t bytes __unused)
+{
+
+	return (ENOTSUP);
+}
 
 static int
 vdev_mirror_read(vdev_t *vdev, const blkptr_t *bp, void *buf,
@@ -904,9 +911,10 @@ vdev_init(uint64_t guid, const nvlist_t *nvlist, vdev_t **vdevp)
 #endif
 	    memcmp(type, VDEV_TYPE_RAIDZ, len) != 0 &&
 	    memcmp(type, VDEV_TYPE_INDIRECT, len) != 0 &&
-	    memcmp(type, VDEV_TYPE_REPLACING, len) != 0) {
+	    memcmp(type, VDEV_TYPE_REPLACING, len) != 0 &&
+	    memcmp(type, VDEV_TYPE_HOLE, len) != 0) {
 		printf("ZFS: can only boot from disk, mirror, raidz1, "
-		    "raidz2 and raidz3 vdevs\n");
+		    "raidz2 and raidz3 vdevs, got: %.*s\n", len, type);
 		return (EIO);
 	}
 
@@ -937,6 +945,8 @@ vdev_init(uint64_t guid, const nvlist_t *nvlist, vdev_t **vdevp)
 			    DATA_TYPE_UINT64,
 			    NULL, &vic->vic_prev_indirect_vdev, NULL);
 		}
+	} else if (memcmp(type, VDEV_TYPE_HOLE, len) == 0) {
+		vdev = vdev_create(guid, vdev_missing_read);
 	} else {
 		vdev = vdev_create(guid, vdev_disk_read);
 	}