`scrub(1)`, but resumable from an offset

dd can be coerced into producing a progress report (by signalling it with SIGUSR1) and can be told to start writing part way through (using seek)

You then just need a source of random bytes, such as /dev/urandom


You could use ddrescue and cryptsetup:

truncate -s $(blockdev --getsize64 /dev/sdx) sdx-zero
cryptsetup open --type plain --cipher aes-xts-plain64 sdx-zero sdx-random
ddrescue /dev/mapper/sdx-random /dev/sdx sdx-scrub.map

To resume, preserve sdx-scrub.map and then just repeat the same commands again.

If you use the same passphrase every time, this method also allows verification:

cmp /dev/mapper/sdx-random /dev/sdx && echo OK || echo FAIL

However, to make this resumable, you'd have to use cmp -i SKIP -n LIMIT.

With verification, the process will take twice as long. Without verification, you have a Schroedinger's scrub.


In the above example, /dev/sdx is the drive to be scrubbed.

sdx-zero is a sparse file containing only zeroes, same size as /dev/sdx. It must be backed by a filesystem that supports sparse files properly, ext4/xfs/btrfs works, tmpfs/fat/ntfs does not.

cryptsetup encrypts zeroes to random data, so /dev/mapper/sdx-random is a seekable block device full of random data (unlike /dev/urandom which is not seekable).

ddrescue reads random data from sdx-random and writes it to /dev/sdx, thereby scrubbing it while tracking progress in sdx-scrub.map. It will also show you a progress bar as well as errors if any.

If you prefer not typing a passphrase every time, you can also create a keyfile instead:

printf "%s" $(uuidgen) > sdx-scrub.key

Generate the keyfile only once and preserve it between calls, then just add --key-file sdx-scrub.key to the cryptsetup command.


See also https://unix.stackexchange.com/a/352378/30851

Tags:

Scrub