Why does dd give me an error at the end of zero-writing a disk?

1

1

I'm running Cygwin on Windows 7.

I was using the following dd command to securely erase a 1TB mechanical disk:

dd if=/dev/zero of=/dev/sde bs=4M status=progress

About 2 and a half hours into the wipe, around the time I was expecting it to complete and after successfully writing about 930GB (or GiB, more likely) to the disk, I got the error:

dd: error writing '/dev/sde': Input/output error

I ran the command again with seek to try and reproduce the error by zero-writing the last few gigabytes of the file:

dd if=/dev/zero of=/dev/sde bs=4M status=progress seek=231100

...and sure enough I got the same error:

dd: error writing '/dev/sde': Input/output error
7368+0 records in
7367+0 records out
35196174335 bytes (35 GB, 33 GiB) copied, 405.703 s, 86.8 MB/s

It seems that the wipe ran successfully, but if that was the case, then why is the error being generated?

Is it normal? If not, how can I avoid it?

Hashim

Posted 2019-11-27T23:43:08.930

Reputation: 6 967

Sounds like a bad sector to me. – Tom Yan – 2019-11-28T06:43:56.260

@TomYan If that is the case, shouldn't dd just fill it with zeroes? Or shouldn't ddrescue at least be able to deal with it? I also tried running ddrescue --force /dev/zero /dev/sdX but got the exact same "Input/output error". – Hashim – 2019-11-29T01:39:33.917

Why would they? At least that's not what they would/could do when they bump into a bad sector. (For the ddrescue case, you are talking about writing to a disk with bad sector, not reading / recovering from it.) – Tom Yan – 2019-11-29T01:49:51.640

1Your dd command does not specify a termination, e.g. a count= parameter. The /dev/zero pseudo-device for input has infinite length. The only way for the command to terminate is when it tries to write past the end of the device. Hence the "error". Look at the statistics that dd reports. Is the "number of bytes copied" represent the entire HDD? – sawdust – 2019-11-30T03:02:40.680

1What does dd if=/dev/zero of=/dev/sda count=1 give when run with seek=1953525119, seek=1953525120 and seek=1953525121 respectively? – Tom Yan – 2019-12-02T11:27:28.060

Answers

1

My guess would be a bad sector. AFAIK that's one of the cases that could lead to I/O error.

Anyway, it is unlikely that the error is given is because dd was trying to write past the end of the drive. Even with my answer to your another question, you should still see No space left on device instead:

enter image description here

For the record, because of the Cygwin bug, 35196174335 is unlikely the actual number of bytes that have been written. Instead, it should be 35196174335 - 4294967295 = 30901207040. (You can try to "mod" these numbers against 512.)

In that case, the number of bytes / sectors that have been successfully written should be 231100 * 4 * 1024 ^ 2 + 30901207040 = 1000204861440 / 1953525120. Base on other information that you have given in your questions, this is unlikely the size of the entire drive anyway. (It might be worth mentioning that 30901207040 bytes is not "4M" (4 * 1024 ^ 2) divisible either.)

Tom Yan

Posted 2019-11-27T23:43:08.930

Reputation: 4 744

With regards to your last paragraph, the figures in the question are based on overwriting only the last 35GB of the disk as I didn't have the time to wipe the entire drive to reproduce the output I initially got. – Hashim – 2019-12-02T23:45:56.947

Based on your answer from my other question, I did badblocks -b 512 -vws /dev/sda 1953525167 1953525167 and got no errors or reported bad blocks. Doesn't this confirm that there is no bad sector on that (last) block of the drive?

– Hashim – 2019-12-02T23:46:41.477

As I suggested in the last comment from me under this question (and calculated in the last paragraph), the last block wasn't the block that triggered the I/O error. Note that the calculation included the part you seeked through. I suggest that you check again 1953525120 (1953525120 blocks was written hence block 0 to block 1953525119 was written), and maybe a block before and after it as "controls", preferably with both dd and badblocks. – Tom Yan – 2019-12-03T01:29:36.440

Note that it is possible that the bad block was relocated after the repeated failure of write attempts, or that it "isn't always bad" anyway (i.e. in the state of "dying"), as far as I know about conventional hard drives (I might be wrong though). – Tom Yan – 2019-12-03T01:30:59.620

I understand you now. I checked those sectors with dd and badblocks and they don't appear to be bad either, while a final full wipe with dd shows that the error still appears at the end: https://pastebin.com/qjb5Wpge. I also checked the SMART info via CrystalDiskInfo again, and based on the drive's general health and the fact that it still doesn't see any bad sectors after all this writing, it seems unlikely that it's dying: https://imgur.com/a/BZyQZCk.

– Hashim – 2019-12-04T02:42:48.483

Hmm. Was the final full wipe done with 64-bit Cygwin? And in any case, does dd if=/dev/zero of=/dev/sda bs=4M seek=238467 fail and always fail? (Maybe even in Linux?) – Tom Yan – 2019-12-04T03:17:19.437

Yep, 64-bit Cygwin. Here are some more tests: https://pastebin.com/4J4byJ11. I can't restart my computer atm but as soon as I can I'll try to run the same commands on a Manjaro LiveCD and see whether it makes any difference.

– Hashim – 2019-12-04T23:43:09.707

1Could you test dd if=/dev/zero of=/dev/sda oflag=seek_bytes seek=1000204861440 with bs=1k, 2k, 4k and 8k? – Tom Yan – 2019-12-05T01:53:16.587

Coincidentally enough I stumbled upon oflag=seek_bytes in the documentation at last night and wondered whether it would work here. More tests, via both Cygwin and a LiveUSB running Manjaro Linux: https://pastebin.com/HrRaP7ZP. Note that Manjaro outputs a different error to the usual Input/output, but always on the same block.

– Hashim – 2019-12-06T00:23:49.297

1Well, there's no "same block". dd in Linux finishes writing you disk in every sample and stops with ENOSPC properly. So most likely again this is a Windows/Cygwin issue. So do you even get "no space left" if you seek the entire drive (1953525168 512-byte blocks) like I do in the screenshot above? I don't know why it wrote 3456 out of 3504 block at the end when you have bs=4M. Maybe you can try dd if=/dev/zero of=/dev/sda oflag=seek_bytes seek=1000203091968 with bs= from 16k to 2M and see if it gives you any hint (if you want to dig further). (Note that it's a different seek.) – Tom Yan – 2019-12-06T04:20:56.710

1You may also want to see if dd if=/dev/zero of=/dev/sda bs=4M seek=238467 gives you I/O error as well in 32-bit Cygwin. – Tom Yan – 2019-12-06T04:24:12.600

Just added some more conclusive information in an answer. – Hashim – 2019-12-13T23:14:00.147

1

On further investigation this appears to be a Cygwin bug that prevents the last X sectors of a drive from wiped, although it's possible that this bug is entirely unrelated to the error message.

I tested by first writing a single pass of ones to the entire disk with:

badblocks -t "1" -vws /dev/sda

I verified that this was successful on the disk by running:

od /dev/sda

I then did:

dd if=/dev/zero of=/dev/sda bs=4M status=progress

...on the entire disk. This failed with the typical I/O error. Inspecting the disk using a hex editor shows that the entire drive was successfully zeroed apart from the last 48 sectors:

enter image description here

I worked out that 1953525168 sectors - 48 = 1953525120 sectors, and used this figure in combination with seek to wipe the last 48 sectors of the disk:

$ dd if=/dev/zero of=/dev/sda seek=1953525120
dd: writing to '/dev/sda': Input/output error
49+0 records in
48+1 records out
4294991871 bytes (4.3 GB, 4.0 GiB) copied, 0.230269 s, 18.7 GB/s

This successfuly zeroes the disk from sector 48 all the way until the end, which I again confirmed using a hex editor and od /dev/sda. Note the I/O error still exists when it reaches the end, indicating that the error does not necessarily indicate a bad wipe.

Finally, I booted Linux Kali from a bootable USB and wiped the entire disk with the same command:

dd if=/dev/zero of=/dev/sda bs=4M status=progress

Checking the wiped disk with a hex editor again confirms that the command wipes the entirety of the disk with no non-zero characters remaining.

In conclusion:

  • Running dd on the entire disk in Cygwin prevents the last 48 sectors from being wiped

  • Using seek to selectively wipe the disk wipes the full disk, but still causes the I/O error

  • Wiping the entire disk from a bootable Linux system wipes the whole disk without the I/O error

For confirmation of this bug, I also ran the same dd command on the only other spare drive I have available, a 128GB SSD, and here it also wipes all but the last 48 sectors:

enter image description here

Hashim

Posted 2019-11-27T23:43:08.930

Reputation: 6 967