Using dd to repeatedly erase a specific range of sectors on the hard disk

Using dd to repeatedly erase a specific range of sectors on the hard disk

I recently needed to erase a specific range of sectors on a hard disk that had developed bad sectors. And I needed to erase them repeatedly, to make sure the remaining sectors in that area are stable.

This is were the dd tool comes in handy.
dd if=/dev/zero of=/dev/sdX seek=START count=SIZE bs=1M

  • if – is the input (in our case, the zero number generator)
  • of – is the output, the hard disk in this case; make sure you specify the right device here, otherwise you will lose data!
  • seek – skips the specified number of blocks (this number is dependent on the specified block size)
  • count – specifies the number of blocks to process (this number is also dependent on the specified block size)
  • bs – is the block size; we will use 1M (1 Megabyte) since the default block size is 512 bytes which is painfully slow to write to a hard disk

For example:

I needed to write sectors 359.000.000 to 367.000.000. Since sectors are 512 bytes each*, sector 359.000.000 means kilobit 179.500.000 (divided by 1024 that equals 175292 MB).  So we will be skipping the first 175292 blocks of size 1MB (or 1M).

The size of the area to wipe is 8.000.000 sectors, that is 4.000.000 kilobits, meaning 3904MB. This, in 1M blocks is 3904 blocks.

To make all these calculations work, we are using a block size of 1M(egabyte). You can use any block size more adequate for your drive, as long as you use it in the seek and count numbers computation.

And to run everything multiple times, why not use a for?…

for f in `seq 20`; \
     do dd if=/dev/zero of=/dev/sdX seek=175292 count=3904 bs=1M; \
     done

One can combine the write with a read of the same area for an ever more thorough test

for f in `seq 20`; \
     do dd if=/dev/zero of=/dev/sdX seek=175292 count=3904 bs=1M; \
     dd if=/dev/sdX of=/dev/zero seek=175292 count=3904 bs=1M; \
     done

 

If only a certain sector needs to be targeted, using a blocksize of 512 (bytes) is more appropriate. For example, to repeatedly erase and read sector 1920126864, use

for f in `seq 1000`; \
     do dd if=/dev/zero of=/dev/sdX seek=1920126864 count=1 bs=512; \
     hdparm -F /dev/sdX; \
     dd if=/dev/sdX of=/dev/zero seek=1920126864 count=1 bs=512; \
     done

Also include a flush to make sure the writes are not cached and the data actually goes on disk (actual sector write).

*This is the older (still general) standard for hard disks sector size. Newer/bigger drives use 4K(ilobytes) sectors instead (see Advanced Format)

One comment

  1. Very good. I decided I needed to learn how to do this when I read it in the Cryptonomicon, and Randy (the hacker character) did it remotely to his hard drive to thwart a search and seizure by the Dentist who was trying to get at his email logs to find the location of the buried treasure 😉

Leave a Reply