/[42-fs]/42.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /42.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (hide annotations)
Sun Jul 19 13:33:51 2009 UTC (10 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 3151 byte(s)
added --skip to skip over existing files (useful for re-runs)
minor size calculation tweaks (still incorrect)

1 dpavlin 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 dpavlin 3 use Data::Dump qw/dump/;
10 dpavlin 1
11 dpavlin 3 my $dev = '/dev/sdb';
12 dpavlin 1 my $mnt = '/mnt/42';
13    
14 dpavlin 5 my ( $verbose, $skip, $init, $debug ) = ( 0, 1 );
15 dpavlin 1
16     GetOptions(
17 dpavlin 5 'verbose!' => \$verbose,
18     'skip!' => \$skip,
19     'init!' => \$init,
20     'debug!' => \$debug,
21 dpavlin 1 ) or die "unknown options: $!";
22    
23    
24 dpavlin 4 sub size {
25     my $size = shift;
26     $size =~ s{MB}{};
27     $size;
28     }
29    
30 dpavlin 3 my @part;
31 dpavlin 1
32 dpavlin 3 sub partitions {
33 dpavlin 4 @part = ();
34 dpavlin 3 open(my $parted, '-|', "parted -s $dev unit mb print free") || die "parted: $!";
35     while(<$parted>) {
36 dpavlin 4 chomp;
37     s{^\s+}{};
38     next unless $_;
39     my @p = map { size($_) } split(/\s+/, $_ );
40     warn "## $_ ",dump( @p ) if $debug;
41     if ( $p[3] && $p[3] eq 'Free' ) {
42     $part[0] = [ @p ];
43     } elsif ( $p[0] =~ m{^\d+$} ) {
44     my $nr = shift @p;
45     $part[$nr] = [ @p ];
46     } else {
47     warn "SKIP ",dump( @p ) if $debug;
48 dpavlin 3 }
49     }
50 dpavlin 4 warn "# part = ",dump( @part ) if $verbose;
51 dpavlin 3 return @part;
52     }
53 dpavlin 1
54 dpavlin 4 sub mount_42 {
55     my $node = $dev . '1';
56     if ( ! -e $node ) {
57     print STDERR "wait for $node";
58     sleep 1;
59     while ( ! -e $node ) {
60     print STDERR ".";
61     sleep 1;
62     }
63     }
64 dpavlin 5 warn " ready\n+ mount $node $mnt\n";
65 dpavlin 4 system("mount $node $mnt") == 0 or die "can't mount: $!";
66     }
67    
68     my $remount_on = qr/(mkpart|rm)/;
69    
70 dpavlin 3 sub parted {
71     my $command = shift;
72 dpavlin 4 my @before = partitions();
73    
74     system "umount $mnt" if $command =~ $remount_on;
75    
76 dpavlin 3 warn "+ $command\n";
77 dpavlin 4 system("parted -s $dev unit mb $command") == 0 or die "parted: $?";
78     if ( $command =~ $remount_on ) {
79     my @part = partitions();
80     while ( $#before == $#part ) {
81     warn "re-read partition table\n";
82     sleep 1;
83     @part = partitions();
84     }
85     mount_42 if $part[1];
86     }
87 dpavlin 3 }
88 dpavlin 1
89 dpavlin 4 partitions();
90 dpavlin 1
91 dpavlin 3 if ( $init ) {
92 dpavlin 4 parted("rm $_") foreach grep { defined $part[$_] } map { $#part - $_ + 1 } ( 1 .. $#part );
93 dpavlin 3 parted("mkpartfs primary ext2 0 42MB");
94     parted("mkpart extended 42MB " . $part[0]->[1] . 'MB');
95     my $cmd = read_file($0);
96     write_file( "$mnt/42.pl", $cmd );
97     chmod 0755, "$mnt/42.pl";
98     exit;
99 dpavlin 1 }
100    
101 dpavlin 3 map { mkdir $_ unless -e $_ } map { "$mnt/$_" } ( 'log', 'fs', 'stat' );
102 dpavlin 1
103 dpavlin 3 my $path = shift @ARGV || die "usage: $0 /path/to/file\n";
104 dpavlin 1
105 dpavlin 3 my ($dir,$file) = ($1,$2) if $path =~ m{^(?:(.+)/)?([^/]+)};
106 dpavlin 1
107     my $fs = "$mnt/fs/$dir";
108 dpavlin 2 mkpath $fs unless -e $fs;
109 dpavlin 1
110     $fs .= '/' . $file;
111 dpavlin 5 if ( -e $fs ) {
112     if ( $skip ) {
113     warn "SKIP $fs\n";
114     exit 0;
115     } else {
116     die "$fs exists! re-run with --skip\n";
117     }
118     }
119 dpavlin 2
120 dpavlin 3 my @stat = stat($path);
121     die "can't stat $path: $!" unless @stat;
122     warn "# $path ",$stat[7],$/;
123 dpavlin 2
124 dpavlin 5 my $size_mb = $stat[7] / 1000 / 1000; # FIXME correctly round to something?
125 dpavlin 3 my ( $free_start, undef, $free_size ) = @{$part[0]};
126 dpavlin 2
127 dpavlin 5 my $part_end = int( $free_start + $size_mb + 1 );
128 dpavlin 3
129     my $last_part = $#part;
130    
131 dpavlin 4 parted("mkpart logical ${free_start}MB ${part_end}MB ");
132 dpavlin 3
133     my $part_size = $part[$#part]->[2] || die "can't get size of new partition";
134    
135     die "not enough space on $dev $size_mb > $part_size" if $size_mb > $part_size;
136    
137     my $part_nr = $#part;
138    
139     write_file( "$mnt/stat/$part_nr", join("\n",@stat) );
140    
141     my $log = "$mnt/log/$part_nr";
142    
143     my $to_dev = $dev . $part_nr;
144    
145     symlink( $to_dev ,$fs) || die "can't create $fs: $!";
146    
147     my $cmd = "dd_rescue -w -l $log $path $to_dev";
148     print "+ $cmd\n";
149     exec $cmd;

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26