Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Say you want to zero-out a failing hard disk. You want to overwrite as much as possible with zeros. What you don't want is: the process aborts on the first write-error. How to do that?

AFAICS, plain dd only provides an option for ignoring read errors. Thus, something like

dd if=/dev/zero of=/dev/disk/by-id/lousy-vendor-123 bs=128k

is not enough.

ddrescue seems to be better at ignoring errors - but what would be the optimal command line with it?

My try with GNU ddrescue:

ddrescue --verbose --force --no-split /dev/zero /dev/disk/by-id/lousy-vendor-123
share|improve this question
    
dd conv=noerror might be a GNU extension, I'm not sure. In any case, it should do the trick. The SATA tell-the-drive-to-erase-itself answer is worth looking into for erasing entire drives, though. –  Peter Cordes 18 hours ago
    
@PeterCordes, the man page of GNU dd documents noerror as 'continue after read errors' ... –  maxschlepzig 17 hours ago
1  
dd conv=noerror ist POSIX standard but it may be really slow –  schily 17 hours ago
    
dd conv=noerror must be for reading errors (according to the manpage), not writing errors. There is nothing bad in combining it with conv=notrunc, which did the trick with ignoring the write errors for me. unix.stackexchange.com/a/229379/4319 –  imz -- Ivan Zakharyaschev 17 hours ago

4 Answers 4

up vote 3 down vote accepted

I prefer badblocks in destructive write mode for this. It writes, it continues doing so when it hits errors, and finally it tells you where those errors were, and this information may help you decide what to do next (Will It Blend?).

# badblocks -v -b 4096 -t random -o badblocks.txt -w /dev/destroyme
Checking for bad blocks in read-write mode
From block 0 to 2097151
Testing with random pattern: done
Reading and comparing: done
Pass completed, 52105 bad blocks found. (0/52105/0 errors)

And the block list:

# head badblocks.txt
2097000
2097001
2097002
2097003
2097004

And what's left on the disk afterwards:

# hexdump -C /dev/destroyme
00000000  be e9 2e a5 87 1d 9e 61  e5 3c 98 7e b6 96 c6 ed  |.......a.<.~....|
00000010  2c fe db 06 bf 10 d0 c3  52 52 b8 a1 55 62 6c 13  |,.......RR..Ubl.|
00000020  4b 9a b8 d3 b7 57 34 9c  93 cc 1a 49 62 e0 36 8e  |K....W4....Ib.6.|

Note it's not really random data - the pattern is repetitive, so if you skipped 1MiB you'd see the same output again.

It will also try to verify by reading the data back in, so if you have a disk that claims to be writing successfully but returns wrong data on readback, it will find those errors too. (Make sure no other processes write to the disk while badblocks is running to avoid false positives.)

Of course with a badly broken disk this may take too long: there is no code that would make it skip over defective areas entirely. The only way you could achieve that with badblocks would be using a much larger blocksize.

I'm not sure if ddrescue does this any better; it's supposed to do that in the other direction (recover as much data as fast as possible). You can do it manually for dd/ddrescue/badblocks by specifying first/last block...

share|improve this answer
    
If I use -t random or -t 0 - does badblocks then just do one write pass? Looking at the man page - it seems that without -t it does 4 passes (for '0xaa, 0x55, 0xff, 0x00'). –  maxschlepzig 19 hours ago
    
It does one pass for each -t you provide on the command line. The default is 4 passes as you say. –  frostschutz 19 hours ago

If the disk is not connected by USB, then consider using hdparm (version > 9.31) to carry out an ATA Secure Erase of the disk. This command causes the drive's firmware to wipe the contents of the disk, including bad blocks.

Warning: Use the correct drive letter - I've shown /dev/sdX as an example - don't just copy/paste.

First, check that it understands the ATA commands (most drives manufactured this last decade or more should):

$ sudo hdparm -I /dev/sdX
.
# lots of other info here...
.
Security: 
    Master password revision code = 65534
        supported
    not enabled
    not locked
    not frozen
    not expired: security count
        supported: enhanced erase
    202min for SECURITY ERASE UNIT. 202min for ENHANCED SECURITY ERASE UNIT.

The last two lines of the extract shows that it is supported.

Therefore add a password to the drive (a requirement apparently):

$sudo hdparm --user-master u --security-set-pass p /dev/sdX
security_password="p"

and erase:

$sudo hdparm --user-master u --security-erase p /dev/sdX
security_password="p"

/dev/sdX:
Issuing SECURITY_ERASE command, password="p", user=user

More info on this procedure is available here.

share|improve this answer
    
This can work over USB if you're lucky, and your USB <-> SATA bridge can pass through non-standard SATA commands (and the Linux driver + hdparm know how to do so on that model). Also, for writing examples, /dev/sdX is good, because then if someone misses an occurrence of it when pasting and customizing, there won't be a problem. –  Peter Cordes 18 hours ago
    
@Peter Cordes - Unless you have 24 disks... No, silly me! Thanks, I've changed it to sdX, that'll teach me to rush an answer! –  garethTheRed 18 hours ago
    
The linked page lists so many hardware/firmware related caveats with this method ... kind of scary –  maxschlepzig 17 hours ago
    
It does indeed show quite a few caveats! All I can say is that it worked for me without any trouble. –  garethTheRed 17 hours ago
dd conv=notrunc

probably did the trick for me.

The mentioned

dd conv=noerror

must be for reading errors (according to the manpage). There is nothing bad in combining the two.

My complete command for zeroing a disk looked like:

dd iflag=fullblock oflag=direct conv=noerror,notrunc if=/dev/zero of=/dev/sda

Adding a custom bs= may also be wanted for some case.

share|improve this answer

A fast and mature method is to use sdd.

If you just like to destroy all content, call:

sdd -inull bs=1m of=/dev/rdsk/cXdXtXp0 -noerror

Always use the "raw" disk driver interface.

If you like to repair a disk and keep as much of the old content as possible, call:

sdd if=/dev/rdsk/cXdXtXp0 of=/dev/rdsk/cXdXtXp0 bs=1m -noerror

This will replace all unreadable blocks with zeroes at 512 byte level. You may like to modify the retry count via try=#, the default is 2.

Note that sdd is faster than dd in case of errors as it first tries to read with the supplied blocksize and in case of errors, it reads with 512 bytes. If there are read errors, sdd makes random seeks and dummy reads to calm down the firmware of the drive.

The enhanced error recovery features have been developed in the 1980s while I was working for the second biggest Sun-Microsystems OEM.

Sdd sourcecode is included in the schily tools:

http://sourceforge.net/projects/schilytools/files/

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.