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.30'; # VERSION
6              
7              
8 2     2   589148 use strict;
  2         4  
  2         48  
9 2     2   9 use warnings;
  2         3  
  2         41  
10 2     2   28 use 5.010;
  2         6  
11 2     2   259 use Clustericious::Config;
  2         206220  
  2         59  
12 2     2   269 use Clustericious::Log::CommandLine qw/:all/;
  2         3363  
  2         10  
13 2     2   2822 use Clustericious::Log;
  2         12378  
  2         15  
14 2     2   2267 use File::Find::Rule;
  2         15426  
  2         19  
15 2     2   527 use Digest::file qw/digest_file_hex/;
  2         2743  
  2         152  
16 2     2   19 use Getopt::Long qw( GetOptions );
  2         5  
  2         17  
17 2     2   339 use Pod::Usage qw( pod2usage );
  2         5  
  2         132  
18 2     2   14 use Fcntl ':flock';
  2         5  
  2         576  
19              
20             sub main {
21 4     4 0 12952 my $class = shift;
22 4         12 my $status = 0;
23 4         31 my $conf = Clustericious::Config->new("Yars");
24 4         912 my $opt_all = 0;
25 4         9 my $opt_lock;
26 4         17 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       47 ) || pod2usage(1);
36 4 100       1765 my @disks = $opt_all ? (map $_->{root}, map @{ $_->{disks} }, $conf->servers) : (@ARGV);
  3         81  
37 4 50       14 LOGDIE "Usage : $0 [-a] [disk1] [disk2] ...\n" unless @disks;
38            
39 4 50       12 if($opt_lock) {
40 2     2   17 use autodie;
  2         5  
  2         20  
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         10 for my $root (@disks) {
50 4 50       60 -d $root or next;
51 4 50       28 -r $root or next;
52 4         11 my $found_bad = 0;
53 4         25 INFO "Checking disk $root";
54             File::Find::Rule->new->file->exec(sub {
55 6     6   9025 my $md5 = $File::Find::dir;
56 6         15 my $root_re = quotemeta $root;
57 6         45 $md5 =~ s/^$root_re//;
58 6         42 $md5 =~ s[/][]g;
59 6 50       22 if ($md5 =~ /^tmp/) {
60 0         0 DEBUG "Skipping tmp file in $File::Find::dir";
61 0         0 return;
62             }
63 6         37 TRACE "Checking $_ $md5";
64 6         59 my $computed = digest_file_hex($_,'MD5');
65 6 100       583 if ($computed eq $md5) {
66 4         23 DEBUG "ok $md5 $_";
67             } else {
68 2         13 DEBUG "not ok $md5 $_ (got $computed)";
69 2 50       77 print "Found bad files on $root :\n" unless $found_bad++;
70 2         22 print "$md5 $_\n";
71 2         58 $status = 2;
72             }
73 4         64 })->in($root);
74             }
75 4         963 $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