/[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

Contents of /42.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (show annotations)
Sun Jul 19 14:31:08 2009 UTC (14 years, 8 months 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 #!/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 $unit = 'MB';
15
16 my ( $verbose, $skip, $init, $debug ) = ( 0, 1 );
17
18 GetOptions(
19 'verbose!' => \$verbose,
20 'skip!' => \$skip,
21 'init!' => \$init,
22 'debug!' => \$debug,
23 ) or die "unknown options: $!";
24
25
26 sub size {
27 my $size = shift;
28 $size =~ s{$unit}{};
29 $size;
30 }
31
32 my @part;
33
34 sub partitions {
35 @part = ();
36 open(my $parted, '-|', "parted -s $dev unit $unit print free") || die "parted: $!";
37 while(<$parted>) {
38 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 }
51 }
52 warn "# part = ",dump( @part ) if $verbose;
53 return @part;
54 }
55
56 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 print STDERR " ready\n";
66 }
67 warn "+ mount $node $mnt\n";
68 system("mount $node $mnt") == 0 or die "can't mount: $!";
69 }
70
71 my $remount_on = qr/(mkpart|rm)/;
72
73 sub parted {
74 my $command = shift;
75 my @before = partitions();
76
77 system "umount $mnt" if $command =~ $remount_on;
78
79 warn "+ $command\n";
80 system("parted -s $dev unit $unit $command") == 0 or die "parted: $?";
81 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 }
91
92 partitions();
93
94 if ( $init ) {
95 #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 my $cmd = read_file($0);
103 my $path = "$mnt/42.pl";
104 write_file( $path, $cmd );
105 chmod 0755, $path;
106 print "created $path ",-s $path, " bytes\n";
107 exit;
108 }
109
110 map { mkdir $_ unless -e $_ } map { "$mnt/$_" } ( 'log', 'fs', 'stat' );
111
112 my $path = shift @ARGV || die "usage: $0 /path/to/file\n";
113
114 my ($dir,$file) = ($1,$2) if $path =~ m{^(?:(.+)/)?([^/]+)};
115
116 my $fs = "$mnt/fs/$dir";
117 mkpath $fs unless -e $fs;
118
119 $fs .= '/' . $file;
120 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
129 my @stat = stat($path);
130 die "can't stat $path: $!" unless @stat;
131 warn "# $path ",$stat[7],$/;
132
133 my $size = int( ( $stat[7] + 1024 ) / 1024 / 1024 );
134 $size += $size % 64; # 16k allocation cluster
135 my ( $free_start, undef, $free_size ) = @{$part[0]};
136
137 my $part_end = $free_start + $size;
138
139 parted("mkpart logical $free_start$unit $part_end$unit ");
140
141 my $part_size = $part[$#part]->[2] || die "can't get size of new partition";
142 die "not enough space on $dev $size > $part_size" if $size > $part_size;
143
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