File Coverage

blib/lib/Yars/Command/yars_disk_scan.pm
Criterion Covered Total %
statement 66 76 86.8
branch 11 20 55.0
condition 0 2 0.0
subroutine 14 16 87.5
pod 0 1 0.0
total 91 115 79.1


line stmt bran cond sub pod time code
1             package Yars::Command::yars_disk_scan;
2              
3             # PODNAME: yars_disk_scan
4             # ABSTRACT: scan a disk for corruption and report corrupt files to stdout
5             our $VERSION = '1.28'; # VERSION
6              
7              
8 2     2   443951 use strict;
  2         7  
  2         52  
9 2     2   12 use warnings;
  2         4  
  2         46  
10 2     2   34 use 5.010;
  2         7  
11 2     2   438 use Clustericious::Config;
  2         189245  
  2         58  
12 2     2   434 use Clustericious::Log::CommandLine qw/:all/;
  2         3599  
  2         15  
13 2     2   3149 use Clustericious::Log;
  2         10828  
  2         16  
14 2     2   1946 use File::Find::Rule;
  2         12861  
  2         17  
15 2     2   544 use Digest::file qw/digest_file_hex/;
  2         2695  
  2         117  
16 2     2   20 use Getopt::Long qw( GetOptions );
  2         6  
  2         26  
17 2     2   296 use Pod::Usage qw( pod2usage );
  2         6  
  2         111  
18 2     2   12 use Fcntl ':flock';
  2         4  
  2         483  
19              
20             sub main {
21 4     4 0 17110 my $class = shift;
22 4         17 my $status = 0;
23 4         40 my $conf = Clustericious::Config->new("Yars");
24 4         969 my $opt_all = 0;
25 4         13 my $opt_lock;
26 4         23 local @ARGV = @_;
27             GetOptions(
28             'all|a' => \$opt_all,
29 0     0   0 'help|h' => sub { pod2usage({ -verbose => 2}) },
30             'lock=s' => \$opt_lock,
31             'version' => sub {
32 0   0 0   0 say 'Yars version ', ($Yars::Command::yars_disk_scan::VERSION // 'dev');
33 0         0 exit 1;
34             },
35 4 50       54 ) || pod2usage(1);
36 4 100       2342 my @disks = $opt_all ? (map $_->{root}, map @{ $_->{disks} }, $conf->servers) : (@ARGV);
  3         107  
37 4 50       21 LOGDIE "Usage : $0 [-a] [disk1] [disk2] ...\n" unless @disks;
38            
39 4 50       17 if($opt_lock) {
40 2     2   12 use autodie;
  2         4  
  2         19  
41 0         0 state $fh;
42 0         0 open $fh, '>', $opt_lock;
43 0 0       0 unless(flock $fh, LOCK_EX | LOCK_NB) {
44 0         0 INFO "There is already a scan in process...";
45 0         0 return 0;
46             }
47             }
48            
49 4         12 for my $root (@disks) {
50 4 50       114 -d $root or next;
51 4 50       43 -r $root or next;
52 4         12 my $found_bad = 0;
53 4         28 INFO "Checking disk $root";
54             File::Find::Rule->new->file->exec(sub {
55 6     6   10441 my $md5 = $File::Find::dir;
56 6         19 my $root_re = quotemeta $root;
57 6         44 $md5 =~ s/^$root_re//;
58 6         46 $md5 =~ s[/][]g;
59 6 50       29 if ($md5 =~ /^tmp/) {
60 0         0 DEBUG "Skipping tmp file in $File::Find::dir";
61 0         0 return;
62             }
63 6         41 TRACE "Checking $_ $md5";
64 6         78 my $computed = digest_file_hex($_,'MD5');
65 6 100       690 if ($computed eq $md5) {
66 4         25 DEBUG "ok $md5 $_";
67             } else {
68 2         21 DEBUG "not ok $md5 $_ (got $computed)";
69 2 50       126 print "Found bad files on $root :\n" unless $found_bad++;
70 2         32 print "$md5 $_\n";
71 2         62 $status = 2;
72             }
73 4         100 })->in($root);
74             }
75 4         1346 $status;
76             }
77              
78             1;
79              
80             __END__
81              
82             =pod
83              
84             =head1 NAME
85              
86             Yars::Command::yars_disk_scan - code for yars_disk_scan
87              
88             =head1 DESCRIPTION
89              
90             This module contains the machinery for the command line program L<yars_disk_scan>
91              
92             =head1 SEE ALSO
93              
94             L<yars_disk_scan>
95              
96             =cut