You could do a simple write/read test with a test pattern. A good test pattern is a byte with binary '01010101' = 0x55 hex and a byte '10101010' = 0xaa. Writing both will toggle every bit.
As I had realized by the comments the real problem is that the hardware of the storage does not report any error if it does not accept data. So even sync
does not help. The operating system writes the buffered data (synchronize) to the storage and assumes buffer and storage content are identical when no error occurs. It continues reading data from the buffer it just has written and the error is not checked.
So we have to use unbuffered IO to check this. Python can do this with Raw I/O:
Raw I/O (also called unbuffered I/O) is generally used as a low-level building-block for binary and text streams; it is rarely useful to directly manipulate a raw stream from user code. Nevertheless, you can create a raw stream by opening a file in binary mode with buffering disabled.
Here is my example code. I write 64 bit (8 byte) test pattern and compare it. I open the test file only once and seek to the beginning for new comparison. Because we read and write direct to the storage there is no need to close and open always I think.
#!/usr/bin/python3
testpattern_55 = bytes( [0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55] )
f = open("/tmp/rwtst.raw", "w+b", buffering=0)
f.write(testpattern_55)
f.seek(0)
testpattern_read = f.read(8)
if testpattern_read != testpattern_55:
print("ERROR writing test pattern!")
f.close()
exit(1)
testpattern_aa = bytes( [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa] )
f.seek(0)
f.write(testpattern_aa)
f.seek(0)
testpattern_read = f.read(8)
if testpattern_read != testpattern_aa:
print("ERROR writing test pattern!")
f.close()
exit(1)
f.close()
You can call it in a cron job to check automatically from time to time.
sudo sdtool /dev/mmcblk0 lock
and see how long it takes for Raspbian to report IO errors. Unless you run a torrent client, it will take days.sdtool
@DmitryGrigoryev