aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/ztest/ztest.c
diff options
context:
space:
mode:
authorGeorge Melikov <[email protected]>2017-01-26 23:34:29 +0300
committerBrian Behlendorf <[email protected]>2017-01-26 12:34:29 -0800
commit2014c09f64a484b8fc3690f1a4c1e749f5fdda48 (patch)
tree97106ed3cdc8616e84118e300ad9b9d4f72c38ed /cmd/ztest/ztest.c
parentdc1fbc43be19d69a39b3e5374b106d6b0474958f (diff)
OpenZFS 7163 - ztest failures due to excess error injection
Authored by: Matthew Ahrens <[email protected]> Reviewed by: George Wilson <[email protected]> Reviewed by: Paul Dagnelie <[email protected]> Approved by: Robert Mustacchi <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Ported-by: George Melikov <[email protected]> OpenZFS-issue: https://www.illumos.org/issues/7163 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/f34284d Closes #4484 Closes #5661
Diffstat (limited to 'cmd/ztest/ztest.c')
-rw-r--r--cmd/ztest/ztest.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c
index 3b504e791..1f5afe4af 100644
--- a/cmd/ztest/ztest.c
+++ b/cmd/ztest/ztest.c
@@ -5214,7 +5214,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
char *path0;
char *pathrand;
size_t fsize;
- int bshift = SPA_MAXBLOCKSHIFT + 2; /* don't scrog all labels */
+ int bshift = SPA_MAXBLOCKSHIFT + 2;
int iters = 1000;
int maxfaults;
int mirror_save;
@@ -5407,7 +5407,29 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
(leaves << bshift) + (leaf << bshift) +
(ztest_random(1ULL << (bshift - 1)) & -8ULL);
- if (offset >= fsize)
+ /*
+ * Only allow damage to the labels at one end of the vdev.
+ *
+ * If all labels are damaged, the device will be totally
+ * inaccessible, which will result in loss of data,
+ * because we also damage (parts of) the other side of
+ * the mirror/raidz.
+ *
+ * Additionally, we will always have both an even and an
+ * odd label, so that we can handle crashes in the
+ * middle of vdev_config_sync().
+ */
+ if ((leaf & 1) == 0 && offset < VDEV_LABEL_START_SIZE)
+ continue;
+
+ /*
+ * The two end labels are stored at the "end" of the disk, but
+ * the end of the disk (vdev_psize) is aligned to
+ * sizeof (vdev_label_t).
+ */
+ uint64_t psize = P2ALIGN(fsize, sizeof (vdev_label_t));
+ if ((leaf & 1) == 1 &&
+ offset + sizeof (bad) > psize - VDEV_LABEL_END_SIZE)
continue;
mutex_enter(&ztest_vdev_lock);