start from last known error
authorDobrica Pavlinusic <dpavlin@rot13.org>
Sun, 24 Nov 2013 21:03:59 +0000 (21:03 +0000)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Sun, 24 Nov 2013 21:03:59 +0000 (21:03 +0000)
git-svn-id: svn://svn.rot13.org/sysadmin-cookbook@304 191e9f34-6774-4a6d-acfc-7664dacd4a2a

recepies/smart/smart-test-relocate.pl

index c1acdbb..a9289cd 100755 (executable)
@@ -9,6 +9,11 @@ my $rewrite_sectors = 16;
 
 my $test_started = 0;
 
+sub write_sector {
+       my $s = shift;
+       system "hdparm --write-sector $s --yes-i-know-what-i-am-doing $drive";
+}
+
 sub smart_test {
        my $sector = shift;
        my $cmd = "smartctl -t select,$sector-max $drive";
@@ -28,7 +33,7 @@ sub smart {
                        my $sector = $1;
                        print "rewrite sector: $sector\n";
                        foreach my $s ( $sector .. $sector + $rewrite_sectors ) {
-                               system "hdparm --write-sector $s --yes-i-know-what-i-am-doing $drive";
+                               write_sector $s;
                        }
                        smart_test $sector;
                        return 1;
@@ -36,13 +41,33 @@ sub smart {
                        $test_started = 1;
                        return 1;
                } elsif ( m/Not_testing/ ) {
-                       return 1 if $test_started;
+                       if ( $test_started ) {
+                               smart_last_error();
+                               return 1 if $test_started;
+                       }
                        smart_test 0; # first-time invocation
                }
        }
        return 0;
 }
 
+sub smart_last_error {
+       my $cmd = "smartctl -l selftest $drive";
+       warn "$cmd\n";
+       open(my $fh, '-|', $cmd);
+       while(<$fh>) {
+               chomp;
+               print "# $_\n";
+               if (/^#\s+1.+Completed: read failure\s+\S+\s+\S+\s+(\d+)/) {
+                       write_sector $1;
+                       smart_test $1;
+                       return;
+               }
+       }
+}
+
+smart_last_error;
+
 while ( smart ) {
        warn "sleep $delay s", ( $test_started ? " smart test running..." : "idle" ), "\n";
        sleep $delay;