aboutsummaryrefslogtreecommitdiff
path: root/stand/libsa
diff options
context:
space:
mode:
authorToomas Soome <tsoome@FreeBSD.org>2020-06-26 21:21:35 +0000
committerToomas Soome <tsoome@FreeBSD.org>2020-06-26 21:21:35 +0000
commitb93b14dc756861d543249f3d04b80809055fdd61 (patch)
tree937b97de7d5c6c7a06f161b415d5e4b88636340f /stand/libsa
parent4cee4598e7d7819ccc10eb353a33623fcbf84e09 (diff)
downloadsrc-b93b14dc756861d543249f3d04b80809055fdd61.tar.gz
src-b93b14dc756861d543249f3d04b80809055fdd61.zip
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. Obtained from: illumos MFC after: 1 week
Notes
Notes: svn path=/head/; revision=362663
Diffstat (limited to 'stand/libsa')
-rw-r--r--stand/libsa/zfs/zfsimpl.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c
index ad746148e38d..1e11ba9daf61 100644
--- a/stand/libsa/zfs/zfsimpl.c
+++ b/stand/libsa/zfs/zfsimpl.c
@@ -765,6 +765,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);
}