[OT] Testing an SD card

Josef Wolf jw at raven.inka.de
Wed Aug 17 17:49:58 UTC 2016


On Wed, Aug 17, 2016 at 05:26:45PM +0100, Colin Law wrote:
> On 17 August 2016 at 16:31, Volker Wysk <post at volker-wysk.de> wrote:
> >
> > I have an SD card for my smartphone which I suspect to be defect. Is there a
> > command to test this? (I can copy it with dd to a file, so far it works.)
> 
> If you suspect it to be faulty (which presumably means it has done
> something odd) then just chuck it and get a new one. Even if it
> appears to be ok then if it has failed in some way once then it will
> fail again. Get a good make, it is false economy to get cheap ones. I
> generally use Sandisk.

I'm not sure whether the SD card is to blame for every failure. I have the
feeling that (at least when connected via USB), there are multiple layers of
buffering and the traditional "sync" command won't flush all of those levels.
The same applies to USB sticks, of course.

Here's a script I wrote a long time ago to check whether a stick is as big as
advertised. About 10 years ago, there were many sticks on the market which did
not have the advertised capacity. This script will fill the whole stick with
random data and check whether it can read back exactly the same data.

Make sure, you specify the CORRECT device name, or you will loose all of your
data. Double check! The script doesn't contain any safety nets. It assumes you
know EXACTLY what you do.
The script won't backup the data on the stick, either.

Have fun! But beware to specify the correct name!



#! /usr/bin/perl

use strict;
use warnings;

my $dev=shift;
my $wc=0;
my $rc=0;
my $wt=time;
my $d;

die "usage: $0 <dev>" unless defined $dev;

open ($d, ">", $dev) or die;
srand $wt;
select $d; $|=1; select STDOUT;
while (1) {
    print $d &randblock or last;
    print $d &randblock or last;
    $wc++;
    &log ("w", $wc, $wt) if ($wc%1024)==0;
}
close $d;

system ("sync");
&log ("wlog", $wc, $wt);

print "remove/plug stick and press ENTER\n";
<STDIN>;

my $rt=time;
open ($d, "<", $dev) or die;
srand $wt;
while (1) {
    my $data;
    sysread ($d, $data, 512); last unless $data eq &randblock;
    sysread ($d, $data, 512); last unless $data eq &randblock;
    $rc++;
    &log ("r", $rc, $rt) if ($rc%1024)==0;
}
close $d;

print "write: $wc(", $wc*1024, " bytes) ", $wc / ($rt-$wt), "\n";
print "read:  $rc(", $rc*1024, " bytes) ", $rc / (time-$rt), "\n";

sub randblock {
    my $block = "";
    my $rv = 256**4;
    my @ary = (1..128);
    $block .= pack "L*", map { rand($rv) } @ary;
    $block;
}

sub log {
    my ($head, $cnt, $tim) = @_;
    my $now = time;
    return if $tim==$now;
    printf "$head %d %d %d\n", $cnt, $now-$tim, $cnt/($now-$tim);
}


-- 
Josef Wolf
jw at raven.inka.de




More information about the ubuntu-users mailing list