/[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 4 - (show annotations)
Sun Jul 19 13:08:33 2009 UTC (14 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 2986 byte(s)
refactor partition manipulation to correctly refresh
partition table and (u)mount /mnt/42 file system

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26