run smart test incrementally and relocate batch of sectors
authorDobrica Pavlinusic <dpavlin@rot13.org>
Wed, 25 Jan 2012 16:53:11 +0000 (16:53 +0000)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Wed, 25 Jan 2012 16:53:11 +0000 (16:53 +0000)
git-svn-id: svn://svn.rot13.org/sysadmin-cookbook@287 191e9f34-6774-4a6d-acfc-7664dacd4a2a

recepies/smart/smart-test-relocate.pl [new file with mode: 0755]

diff --git a/recepies/smart/smart-test-relocate.pl b/recepies/smart/smart-test-relocate.pl
new file mode 100755 (executable)
index 0000000..0dc992a
--- /dev/null
@@ -0,0 +1,46 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+my $drive = $ARGV[0] || die "usage: $0 /dev/sda\n";
+my $delay = 15;
+my $rewrite_sectors = 16;
+
+my $test_started = 0;
+
+sub smart_test {
+       my $sector = shift;
+       my $cmd = "smartctl -t select,$sector-max $drive";
+       warn "$cmd\n";
+       system $cmd;
+       $test_started = 1;
+}
+
+sub smart {
+       open(my $fh, '-|', "smartctl -l selective $drive");
+       while(<$fh>) {
+               chomp;
+               print "# $_\n";
+               if ( m/Completed_read_failure.*\((\d+)-\d+\)/ ) {
+                       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";
+                       }
+                       smart_test $sector;
+                       return 1;
+               } elsif ( m/Self_test_in_progress/ ) {
+                       return 1;
+               } elsif ( m/Not_testing/ ) {
+                       return 1 if $test_started;
+                       smart_test 0; # first-time invocation
+               }
+       }
+       return 0;
+}
+
+while ( smart ) {
+       warn "# sleep $delay s\n";
+       sleep $delay;
+}