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.31'; # VERSION
6              
7              
8 2     2   427054 use strict;
  2         5  
  2         52  
9 2     2   8 use warnings;
  2         3  
  2         42  
10 2     2   29 use 5.010;
  2         7  
11 2     2   369 use Clustericious::Config;
  2         204619  
  2         51  
12 2     2   275 use Clustericious::Log::CommandLine qw/:all/;
  2         3281  
  2         13  
13 2     2   2599 use Clustericious::Log;
  2         9471  
  2         12  
14 2     2   1529 use File::Find::Rule;
  2         12171  
  2         13  
15 2     2   337 use Digest::file qw/digest_file_hex/;
  2         2348  
  2         107  
16 2     2   14 use Getopt::Long qw( GetOptions );
  2         4  
  2         14  
17 2     2   223 use Pod::Usage qw( pod2usage );
  2         3  
  2         92  
18 2     2   10 use Fcntl ':flock';
  2         3  
  2         444  
19              
20             sub main {
21 4     4 0 12158 my $class = shift;
22 4         8 my $status = 0;
23 4         23 my $conf = Clustericious::Config->new("Yars");
24 4         752 my $opt_all = 0;
25 4         8 my $opt_lock;
26 4         13 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       40 ) || pod2usage(1);
36 4 100       1552 my @disks = $opt_all ? (map $_->{root}, map @{ $_->{disks} }, $conf->servers) : (@ARGV);
  3         71  
37 4 50       14 LOGDIE "Usage : $0 [-a] [disk1] [disk2] ...\n" unless @disks;
38            
39 4 50       12 if($opt_lock) {
40 2     2   13 use autodie;
  2         4  
  2         12  
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         11 for my $root (@disks) {
50 4 50       61 -d $root or next;
51 4 50       25 -r $root or next;
52 4         10 my $found_bad = 0;
53 4         21 INFO "Checking disk $root";
54             File::Find::Rule->new->file->exec(sub {
55 6     6   8003 my $md5 = $File::Find::dir;
56 6         14 my $root_re = quotemeta $root;
57 6         33 $md5 =~ s/^$root_re//;
58 6         33 $md5 =~ s[/][]g;
59 6 50       17 if ($md5 =~ /^tmp/) {
60 0         0 DEBUG "Skipping tmp file in $File::Find::dir";
61 0         0 return;
62             }
63 6         30 TRACE "Checking $_ $md5";
64 6         54 my $computed = digest_file_hex($_,'MD5');
65 6 100       479 if ($computed eq $md5) {
66 4         19 DEBUG "ok $md5 $_";
67             } else {
68 2         14 DEBUG "not ok $md5 $_ (got $computed)";
69 2 50       97 print "Found bad files on $root :\n" unless $found_bad++;
70 2         15 print "$md5 $_\n";
71 2         43 $status = 2;
72             }
73 4         66 })->in($root);
74             }
75 4         905 $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