/[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 6 - (hide annotations)
Sun Jul 19 14:31:08 2009 UTC (10 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 3289 byte(s)
configuratble unit, but now we fail on maximum of 16 extended partitions
on scsi disk (sigh!)

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26