Getting dd's skip and seek straight once and for all

August 17, 2015

Earlier today I wanted to lightly damage a disk in a test ZFS pool in order to make sure that some of our status monitoring code was working right when ZFS was recovering from checksum failures. The reason I wanted to do light damage is that under normal circumstances, if you do too much damage to a disk, ZFS declares the disk bad and ejects it from your pool entirely; I didn't want this to happen.

So I did something like this:

for i in $(seq 128 256 10240); do
    dd if=/dev/urandom of=<disk> bs=128k count=4 skip=$i
done

The intent was to poke 512 KB of random data into the disk at a number of different places, with the goal of both hopefully overwriting space that was actually in use and not overwriting too much of it. This turned out to actually not do very much and I spent some time scratching my head before the penny dropped.

I've used skip before and honestly, I wasn't thinking clearly here. What I actually wanted to use was seek. The difference is this:

skip skips over initial data in the input, while seek skips over initial data in the output.

(Technically I think skip usually silently consumes the initial input data you asked it to skip over, although dd may try to lseek() on inputs that seem to support it. seek definitely must lseek() and dd will error out if you ask it to seek on something that doesn't support lseek(), like a pipe.)

What I was really doing with my dd command was throwing away increasing amounts of data from /dev/urandom and then repeatedly writing 512 KB (of random data) over the start of the disk. This was nowhere near what I intended and certainly didn't have the effects on ZFS that I wanted.

I guess the way for me to remember this is 'skip initial data from the input, seek over space in the output'. Hopefully it will stick after this experience in toe stubbing.

Sidebar: the other thing I initially did wrong

The test pool was full of test files, which I had created by copying /dev/zero into files. My initial dd was also using /dev/zero to overwrite disk blocks. It struck me that I was likely to be mostly overwriting file data blocks full of zeroes with more zeroes, which probably wasn't going to cause checksum failures.


Comments on this page:

By Anon at 2015-08-18 10:19:33:

If you're on a BSD you might find you have iseek/oseek available...

SKIP ends in IP = InPut

Written on 17 August 2015.
« Why languages like 'declare before use' for variables and functions
Linux's abstract namespace for Unix domain sockets »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Aug 17 22:34:17 2015
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.