1 |
dpavlin |
7 |
#!/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 |
dpavlin |
9 |
my $lv = $file; |
66 |
|
|
$lv =~ s{\W+}{_}g; |
67 |
|
|
|
68 |
dpavlin |
7 |
$fs .= '/' . $file; |
69 |
dpavlin |
9 |
if ( -e $fs || -e "/dev/$vg/$lv" ) { |
70 |
dpavlin |
7 |
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; |