NoPaste

bb-test.pl

von linuxCowboy

SNIPPET_TEXT:
  1. #!/usr/bin/perl -w
  2. #
  3. # badblocks test    [LxC]
  4. use 5.010;
  5.  
  6. ##### start adjust block #####
  7.  
  8. $device = "/dev/sdb";
  9. $blocksize = 4096;
  10. $blocks_total = 732_566_646; # 3TB
  11. $percent_to_check = 10;
  12. $blocks_at_once = 4000; # HDD-Cache
  13. $reads_total = 100; # 0 to disable
  14. $blocks_to_check_start_end = 250_000; # 0 to disable
  15. $randomize_reads = 1; # boolean
  16. $sleep_between_reads = 60; # seconds, 0 to disable
  17.  
  18. # overheat protection: adjust get_temp() for your drive!
  19. $overheat_protection = 0; # boolean
  20. $max_temp = 46;
  21. $cooldown_time = 60;
  22.  
  23. #$test = ""; # read-only mode (badblocks default)
  24. $test = "-w -t 0xff"; # read-write mode
  25. #$test = "-n -t 0xff"; # non-destructive read-write mode
  26.  
  27. $logfile = "/var/log/bb-test.log"; # "" to disable
  28.  
  29. ##### end adjust block #####
  30.  
  31. die "you're not root!\n" if ( $< != 0 );
  32.  
  33. if ( $test =~ /w/ ) {
  34.         print STDERR "Okay to WRITE on $device? {yes} ";
  35.         die "Abort!\n" if  ( <STDIN> !~ /yes/ );
  36. }
  37.  
  38. if ( $logfile ) {
  39.         open( STDOUT, "| tee $logfile" ) or die "cannot dup STDOUT to $logfile: $!";
  40. }
  41.  
  42. $blocks_per_check = $reads_total ? int( $blocks_total / $reads_total ) : 0;
  43. $to_check = int( $blocks_per_check / 100 * $percent_to_check );
  44. $start_range = $blocks_per_check - $to_check;
  45. $time_total = time;
  46.  
  47. print "\n$device: ",sep_point( $to_check * $reads_total )." of ",sep_point( $blocks_total )." blocks ($percent_to_check%)  ",`date`;
  48.  
  49. if ( $blocks_to_check_start_end ) {
  50.         do_scan( 0, $blocks_to_check_start_end, 1, 1 ); # first blocks
  51.  
  52.         do_scan( ($blocks_total - $blocks_to_check_start_end), ($blocks_total - 1), 1, 1 ); # last blocks
  53. }
  54.  
  55. for ( $start = 0, $read = 0; $read++ < $reads_total; $start += $blocks_per_check ) {
  56.         $rand_start = $randomize_reads ? int( rand($start_range) ) : 0;
  57.  
  58.         do_scan( ($start + $rand_start), ($start + $rand_start + $to_check), $read, $reads_total );
  59. }
  60.  
  61. say "\n",`date`;
  62.  
  63. sub do_scan {
  64.         ( $first, $last, $counter, $total ) = @_;
  65.         $size = ($last - $first + 1) * $blocksize / 1024 / 1024;
  66.         $time = time;
  67.  
  68.         say " " x 20; # kick artifacts
  69.         system( "badblocks -b $blocksize -sv $test -c $blocks_at_once $device $last $first 2>&1" );
  70.         exit if ( $? != 0 ); # i.a. SIGINT
  71.        
  72.         $time = time - $time;
  73.         $t = time - $time_total;
  74.  
  75.         printf "%d/%d: %dMB in %ds ==> %dMB/s  [%d:%02d:%02d]\n",
  76.                 $counter, $total, $size, $time, ($time ? $size / $time : 0), $t/60/60, $t/60%60, $t%60;
  77.  
  78.         binmode( STDOUT, ":unix" ); # flush
  79.         foreach $cooler (reverse( 1 .. $sleep_between_reads )) {
  80.                 last if ( $counter == $total );
  81.  
  82.                 printf STDERR "cooling down... %d \r", $cooler;
  83.                 sleep( 1 );
  84.         }
  85.         check_temp() if ( $overheat_protection );
  86. }
  87.  
  88. sub check_temp {
  89.         $curr_temp = get_temp();
  90.  
  91.         if ( $max_temp ) {
  92.                 while ( $curr_temp > $max_temp ) {
  93.                         say "$curr_temp degrees Celsius - Overheat!";
  94.  
  95.                         foreach $cooler (reverse( 1 .. $cooldown_time )) {
  96.                                 printf STDERR "cooling down... %d \r", $cooler;
  97.                                 sleep( 1 );
  98.                         }
  99.                         $curr_temp = get_temp();
  100.                 }
  101.         }
  102.         say "$curr_temp degrees Celsius";
  103. }
  104.  
  105. sub get_temp { # find a way to read your drive!
  106.         for ( `hdparm -H $device 2>/dev/null` ) { # Hitachi only, but fast
  107.                 return $1 if ( /.*temperature.*celsius.*([0-9]{2})$/ );
  108.         }
  109.         for ( 0..2 ) {
  110.                 for ( `smartctl -a -T permissive $device` ) {
  111.                         return $1 if ( m|.*Temperature_Celsius.*([0-9]{2}) \(Min/Max.*| );
  112.                 }
  113.                 sleep $_ if ( ! /2/ ); # "Unknown_Attribute"
  114.         }
  115.         die "No temperature!\n";
  116. }
  117.  
  118. sub sep_point {
  119.         ( $par = shift ) =~ s/(?<=\d)(?=(\d\d\d)+\b)/./g;
  120.         $par;
  121. }

Quellcode

Hier kannst du den Code kopieren und ihn in deinen bevorzugten Editor einfügen. PASTEBIN_DOWNLOAD_SNIPPET_EXPLAIN