Blog version of provoke_ZFS_corruption
- Original bug: https://github.com/openzfs/zfs/issues/12014
- Github: https://github.com/HankB/provoke_ZFS_corruption/tree/main
- Blog: https://HankB.github.io/provoke_ZFS_corruption/
- Update on methodology
Preliminary results of the bisect are below. There has been discussion during the testing at https://github.com/openzfs/zfs/discussions/17203 and per suggestion, I will be repeating the test on 30af21b02569ac192f52ce6e6511015f8a8d5729. I have also add some further verification to the results for the final "good" test.
Directory of tests starting with preliminary exploration.
started | completed | results | ZFS ver | OS | kernel ver | notes |
---|---|---|---|---|---|---|
2025-02-03 | 2025-02-04 | corruption | zfs-2.1.11-1+deb12u1 | Debian 12 | 6.1.0-30-amd64 | methodology exploration |
2025-02-05 | 2025-02-05 | corruption in 15 minutes | zfs-2.1.11-1+deb12u1 | Debian 12 | 6.1.0-30-amd64 | methodology exploration |
2025-02-07 | 2025-02-07 | corruption in 10 hours | zfs-2.3.99-170-FreeBSD_g34205715e | 15.0-CURRENT FreeBSD | main-n275087-cdacb12065e4 | FreeBSD on Pi 4B |
2025-02-11 | 2025-02-11 | corruption in 2 hours | zfs-2.1.11-1+deb12u1 | Debian 12 | 6.1.0-30-amd64 | repeat methodology exploration, test FreeBSD tweaks |
2025-02-12 | 2025-02-12 | corruption instantly [1] | zfs-2.0.3-9~bpo10+1 | Debian 10 | 5.10.0-0.deb10.24-amd64 | repeat previous tests using new methodology |
2025-02-11 | 2025-02-22 | no corruption | zfs-0.8.6-1 | Debian 10 | 4.19.0-27-amd64 | demonstrate no corruption with 0.8.6 |
2025-02-22 | 2025-02-23 | corruption in 2 hours | zfs-2.0.0-1 | Debian 10 | 4.19.0-27-amd64 | first image restore test |
2025-02-22 | deferred | zfs-2.0.0-1 | Debian 10 | 4.19.0-27-amd64 | unable to resolve symbol issue | |
2025-02-24 | corruption in 2 hours | 2.3.0-1 | Debian Trixie | 6.12.12-amd64 | ||
2025-02-24 | corruption in 2 hours | 2.3.0-1+patch | Debian Trixie | 6.12.12-amd64 | ||
2025-02-25 | set aside | 2.3.0-1 | Debian Trixie | 6.12.12-amd64 | ||
2025-04-02 | 2025-04-02 | corruption in 2 hours | 2.0.0-1 | Debian 10 | 4.19.0-27-amd64 | Confirm that 4.19 + 2.0.0 results in corruption |
2025-04-02 | 2025-04-03 | no corruption after 12 hours | 0.8.6 | Debian 10 | 4.19.0-27-amd64 | Confirm that 4.19 + 0.8.6 does not cause corruption |
2025-04-03 | 2025-04-04 | no corruption after 20 hours | 78fac8d925fdd64584292fbda4ed9e3e2bbaae66 | Debian 10 | 4.19.0-27-amd64 | first bisect between 2.0.0 and 0.8.6, |
2025-04-03 | 2025-04-04 | corruption after 2 1/2 hours | 327000ce04b4243f140a38647dca59683d39b8e7 | Debian 10 | 4.19.0-27-amd64 | 2nd bisect |
2025-04-04 | 2025-04-04 | corruption after 2:50 | eedb3a62b9f16b989aa02d00db63de5dff200572 | Debian 10 | 4.19.0-27-amd64 | 3rd bisect |
2025-04-04 | 2025-04-05 | corruption after 2 1/2 hours | 1e620c98727a5a5cff1af70fef9bc25626b4e9d8 | Debian 10 | 4.19.0-27-amd64 | 4th bisect |
2025-04-05 | 2025-04-05 | corruption after 3+ hours | a64f8276c7c2e121f438866d2f91ddff22031e7f | Debian 10 | 4.19.0-27-amd64 | 5th bisect |
2025-04-05 | 2025-04-06 | no corruption after 12+ hours | 8e91c5ba6a1b2c607a1ed4a0a42b2d07eca13091 | Debian 10 | 4.19.0-27-amd64 | 6th bisect |
2025-04-06 | 2025-04-06 | no corruption after 11:30 hours | d9cd66e45f285356624d26eb92e10e2baf2738ee | Debian 10 | 4.19.0-27-amd64 | 7th bisect |
2025-04-06 | 2025-04-07 | no corruption during flawed test | b1b4ac27082aede8522e479c87897026519f1dd7 | Debian 10 | 4.19.0-27-amd64 | 8th bisect |
2025-04-07 | 2025-04-07 | corruption after 3 hours | 0b755ec3d5ba531d2662da54fb9ac62627ce2c66 | Debian 10 | 4.19.0-27-amd64 | 9th bisect |
2025-04-07 | 2025-04-08 | corruption after about 2 1/2 hours | 30af21b02569ac192f52ce6e6511015f8a8d5729 | Debian 10 | 4.19.0-27-amd64 | 10th bisect |
2025-04-07 | 2025-04-08 | no corruption after 12 hours | c1b5801bb5af0055e5f3d263beaa07026103e212 | Debian 10 | 4.19.0-27-amd64 | 11th bisect |
2025-04-07 | 2025-04-08 | corruption after 3 hours | 30af21b02569ac192f52ce6e6511015f8a8d5729 | Debian 10 | 4.19.0-27-amd64 | repeat 10th bisect |
2025-04-07 | 2025-04-08 | corruption after 3 hours | 30af21b02569ac192f52ce6e6511015f8a8d5729 | Debian 10 | 4.19.0-27-amd64 | modified pool settings |
2025-04-08 bisect conclusion
Assuming the tests have successfully identified corruption, the result of the bisect is:
hbarta@orion:~/zfs$ git bisect good
30af21b02569ac192f52ce6e6511015f8a8d5729 is the first bad commit
commit 30af21b02569ac192f52ce6e6511015f8a8d5729
Author: Paul Dagnelie <pcd@delphix.com>
Date: Wed Jun 19 09:48:13 2019 -0700
Implement Redacted Send/Receive
Redacted send/receive allows users to send subsets of their data to
a target system. One possible use case for this feature is to not
transmit sensitive information to a data warehousing, test/dev, or
analytics environment. Another is to save space by not replicating
unimportant data within a given dataset, for example in backup tools
like zrepl.
Redacted send/receive is a three-stage process. First, a clone (or
clones) is made of the snapshot to be sent to the target. In this
clone (or clones), all unnecessary or unwanted data is removed or
modified. This clone is then snapshotted to create the "redaction
snapshot" (or snapshots). Second, the new zfs redact command is used
to create a redaction bookmark. The redaction bookmark stores the
list of blocks in a snapshot that were modified by the redaction
snapshot(s). Finally, the redaction bookmark is passed as a parameter
to zfs send. When sending to the snapshot that was redacted, the
redaction bookmark is used to filter out blocks that contain sensitive
or unwanted information, and those blocks are not included in the send
stream. When sending from the redaction bookmark, the blocks it
contains are considered as candidate blocks in addition to those
blocks in the destination snapshot that were modified since the
creation_txg of the redaction bookmark. This step is necessary to
allow the target to rehydrate data in the case where some blocks are
accidentally or unnecessarily modified in the redaction snapshot.
The changes to bookmarks to enable fast space estimation involve
adding deadlists to bookmarks. There is also logic to manage the
life cycles of these deadlists.
The new size estimation process operates in cases where previously
an accurate estimate could not be provided. In those cases, a send
is performed where no data blocks are read, reducing the runtime
significantly and providing a byte-accurate size estimate.
Reviewed-by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed-by: Matt Ahrens <mahrens@delphix.com>
Reviewed-by: Prashanth Sreenivasa <pks@delphix.com>
Reviewed-by: John Kennedy <john.kennedy@delphix.com>
Reviewed-by: George Wilson <george.wilson@delphix.com>
Reviewed-by: Chris Williamson <chris.williamson@delphix.com>
Reviewed-by: Pavel Zhakarov <pavel.zakharov@delphix.com>
Reviewed-by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed-by: Prakash Surya <prakash.surya@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Dagnelie <pcd@delphix.com>
Closes #7958
:040000 040000 22bddd232c24007744e929e18259e69cc01be8da 603ec1aaef6c1a7fab80168a9b5309f89fe13c5d M cmd
:100644 100644 db614084e37e3edbeef28f0430e85f41a0b46ac8 e0349a18219a5d12b0f1fdcb9b13ad079083d741 M configure.ac
:040000 040000 13ca95901c67684f0cdc178dc08e4e2c4f8a0f21 a31bf2b7324d52a429c7accfd2d482edbc9f742d M include
:040000 040000 f82837df7ff2132fcc3bb39c6ef925776cce2dcc a90467d84951a2c93f5bf0c02c12108855d995e6 M lib
:040000 040000 45d76cb23df175339c0624121e17b4a30f85ad41 3e3a905736d37756b766573b876c75b66084923b M man
:040000 040000 6ab2cf3acb56bf25c7b5762d8e7d205b1d9d47f7 ce8fe30aac453c96dc5875839b67d49a4ea63f0f M module
:040000 040000 9c3cc75a332d4b006ceb5a7b282a298ac8ecd704 937acde4124386561528a96e2869a98d9dea0aaa M tests
hbarta@orion:~/zfs$
[1]
Test ran for hours w/ wrong ownership and the stir process changed nothing. When file ownership was fixed, corruption was nearly instant.
2025-02-04 process improvements
These have worked, producing corruption in less than a day. This should shorten testing time and also proves that the H/W in use will produce corruption using current Debian kernel and ZFS. More details In addition, the scripts have been tweaked to work on FreeBSD (with bash
) and corruption was produced on a FreeBSD host.
2025-02-11 Test instructions
Configure a host and two pools send
and recv
. Review the scripts that will be used as my user name hbarta
has been hard coded in too many places. (PRs to corract that gratefully accepted.)
- Run the
populate_pool.sh
script asroot
to populate the send pool. It does not terminate when there is sufficient data and will need to be killed when thesend
pool reaches about 50% capacity. The easiest way to kill it is to find the PID of the script andkill <PID>
as root. - Run
syncoid
asroot
manually once to mirrorsend
torecv
. Set permissions or ownership on the resulting files insend
to allow user modification. - Execute
zfs allow
asroot
to provide appropriate permissions so thatsyncoid
can run as your user. - Create a directory
~/logs
where the scripts will write logs. -
Start the following three scripts. (I hard link them to the user
~/bin
directory for convenience but it is left to the user to make them available in the PATH.) -
thrash_stir.sh
- This script will modify random files in the pool continuously and also capture recursive snapshots. thrash_syncoid.sh
- This script will invokesyncoid
continuously.manage_snaps.sh
- This script will manage snapshots every minute to limit retained snapshots to 100 for each dataset.
All three scripts will check for and exit when corruption is detected. In addition I add a cron job as root
to zpool scrub
both pools several times/day.
For details on the exact commands used to prepare the test, please see the methodology exploration.