diff options
author | George Melikov <[email protected]> | 2017-01-26 23:34:29 +0300 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-01-26 12:34:29 -0800 |
commit | 2014c09f64a484b8fc3690f1a4c1e749f5fdda48 (patch) | |
tree | 97106ed3cdc8616e84118e300ad9b9d4f72c38ed /cmd | |
parent | dc1fbc43be19d69a39b3e5374b106d6b0474958f (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')
-rw-r--r-- | cmd/ztest/ztest.c | 26 |
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); |