1 |
#!/usr/bin/perl |
2 |
|
3 |
use warnings; |
4 |
use strict; |
5 |
|
6 |
use File::Slurp; |
7 |
use File::Path; |
8 |
use Getopt::Long; |
9 |
use Data::Dump qw/dump/; |
10 |
|
11 |
my $dev = '/dev/sdb'; |
12 |
my $mnt = '/mnt/42'; |
13 |
|
14 |
my ( $verbose, $skip, $init, $debug ) = ( 0, 1 ); |
15 |
|
16 |
GetOptions( |
17 |
'verbose!' => \$verbose, |
18 |
'skip!' => \$skip, |
19 |
'init!' => \$init, |
20 |
'debug!' => \$debug, |
21 |
) or die "unknown options: $!"; |
22 |
|
23 |
my $vg = '42'; |
24 |
|
25 |
sub mount_42 { |
26 |
my $node = "/dev/$vg/_meta"; |
27 |
if ( ! -e $node ) { |
28 |
print STDERR "wait for $node"; |
29 |
sleep 1; |
30 |
while ( ! -e $node ) { |
31 |
print STDERR "."; |
32 |
sleep 1; |
33 |
} |
34 |
print STDERR " ready\n"; |
35 |
} |
36 |
warn "+ mount $node $mnt\n"; |
37 |
system("mount $node $mnt") == 0 or die "can't mount: $!"; |
38 |
} |
39 |
|
40 |
if ( $init ) { |
41 |
system("umount $mnt"); |
42 |
system("pvcreate $dev"); |
43 |
system("vgcreate $vg $dev"); |
44 |
system("lvcreate -n _meta -L 42M $vg"); |
45 |
system("mkfs.ext2 /dev/$vg/_meta"); |
46 |
mount_42; |
47 |
|
48 |
my $cmd = read_file($0); |
49 |
my $path = "$mnt/42.pl"; |
50 |
write_file( $path, $cmd ); |
51 |
chmod 0755, $path; |
52 |
print "created $path ",-s $path, " bytes\n"; |
53 |
exit; |
54 |
} |
55 |
|
56 |
map { mkdir $_ unless -e $_ } map { "$mnt/$_" } ( 'log', 'fs', 'stat' ); |
57 |
|
58 |
my $path = shift @ARGV || die "usage: $0 /path/to/file\n"; |
59 |
|
60 |
my ($dir,$file) = ($1,$2) if $path =~ m{^(?:(.+)/)?([^/]+)}; |
61 |
|
62 |
my $fs = "$mnt/fs/$dir"; |
63 |
mkpath $fs unless -e $fs; |
64 |
|
65 |
my $lv = $file; |
66 |
$lv =~ s{\W+}{_}g; |
67 |
|
68 |
$fs .= '/' . $file; |
69 |
if ( -e $fs || -e "/dev/$vg/$lv" ) { |
70 |
if ( $skip ) { |
71 |
warn "SKIP $fs\n"; |
72 |
exit 0; |
73 |
} else { |
74 |
die "$fs exists! re-run with --skip\n"; |
75 |
} |
76 |
} |
77 |
|
78 |
my @stat = stat($path); |
79 |
die "can't stat $path: $!" unless @stat; |
80 |
warn "# $path ",$stat[7],$/; |
81 |
|
82 |
my $size = $stat[7] / 1024; |
83 |
$size .= 'k'; |
84 |
|
85 |
system("lvcreate -n $lv -L $size $vg"); |
86 |
|
87 |
write_file( "$mnt/stat/$file", join("\n",@stat) ); |
88 |
|
89 |
my $log = "$mnt/log/$file"; |
90 |
|
91 |
my $to = "/dev/$vg/$lv"; |
92 |
symlink( $to , $fs ) || die "can't create $fs: $!"; |
93 |
|
94 |
my $cmd = "dd_rescue -w -l \"$log\" \"$path\" $to"; |
95 |
print "+ $cmd\n"; |
96 |
exec $cmd; |