11 |
my $dev = '/dev/sdb'; |
my $dev = '/dev/sdb'; |
12 |
my $mnt = '/mnt/42'; |
my $mnt = '/mnt/42'; |
13 |
|
|
14 |
my ( $init, $debug ); |
my ( $verbose, $skip, $init, $debug ) = ( 0, 1 ); |
15 |
|
|
16 |
GetOptions( |
GetOptions( |
17 |
'init!' => \$init, |
'verbose!' => \$verbose, |
18 |
'debug!' => \$debug, |
'skip!' => \$skip, |
19 |
|
'init!' => \$init, |
20 |
|
'debug!' => \$debug, |
21 |
) or die "unknown options: $!"; |
) or die "unknown options: $!"; |
22 |
|
|
23 |
|
|
24 |
|
sub size { |
25 |
|
my $size = shift; |
26 |
|
$size =~ s{MB}{}; |
27 |
|
$size; |
28 |
|
} |
29 |
|
|
30 |
my @part; |
my @part; |
31 |
|
|
32 |
sub partitions { |
sub partitions { |
33 |
|
@part = (); |
34 |
open(my $parted, '-|', "parted -s $dev unit mb print free") || die "parted: $!"; |
open(my $parted, '-|', "parted -s $dev unit mb print free") || die "parted: $!"; |
35 |
while(<$parted>) { |
while(<$parted>) { |
36 |
warn "## $_" if $debug; |
chomp; |
|
if ( m{^\s+([\d\.]+)MB\s+([\d\.]+)MB\s+([\d\.]+)MB\s+Free Space} ) { |
|
|
$part[0] = [ $1, $2, $3, 'free' ]; |
|
|
} |
|
|
next unless m{^\s+\d+\s+}; |
|
37 |
s{^\s+}{}; |
s{^\s+}{}; |
38 |
s{([\d\.]+)MB}{$1}g; |
next unless $_; |
39 |
my ( $nr, $start, $end, $size, undef ) = split(/\s+/, $_, 5); |
my @p = map { size($_) } split(/\s+/, $_ ); |
40 |
$part[$nr] = [ $start, $end, $size ]; |
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 |
|
} |
49 |
} |
} |
50 |
warn "## part = ",dump( @part ) if $debug; |
warn "# part = ",dump( @part ) if $verbose; |
51 |
return @part; |
return @part; |
52 |
} |
} |
53 |
|
|
54 |
|
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 |
|
warn " ready\n+ mount $node $mnt\n"; |
65 |
|
system("mount $node $mnt") == 0 or die "can't mount: $!"; |
66 |
|
} |
67 |
|
|
68 |
|
my $remount_on = qr/(mkpart|rm)/; |
69 |
|
|
70 |
sub parted { |
sub parted { |
71 |
my $command = shift; |
my $command = shift; |
72 |
|
my @before = partitions(); |
73 |
|
|
74 |
|
system "umount $mnt" if $command =~ $remount_on; |
75 |
|
|
76 |
warn "+ $command\n"; |
warn "+ $command\n"; |
77 |
system("parted -s $dev unit mb $command") == 0 or die "parted: $!"; |
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 |
} |
} |
88 |
|
|
89 |
|
partitions(); |
90 |
|
|
91 |
if ( $init ) { |
if ( $init ) { |
92 |
system("umount $mnt"); |
parted("rm $_") foreach grep { defined $part[$_] } map { $#part - $_ + 1 } ( 1 .. $#part ); |
|
partitions(); |
|
|
parted("rm $_") foreach grep { defined $part[$_] } ( 1 .. 4 ); |
|
93 |
parted("mkpartfs primary ext2 0 42MB"); |
parted("mkpartfs primary ext2 0 42MB"); |
|
partitions(); |
|
94 |
parted("mkpart extended 42MB " . $part[0]->[1] . 'MB'); |
parted("mkpart extended 42MB " . $part[0]->[1] . 'MB'); |
|
system "sync;sync"; |
|
|
partitions(); |
|
|
system("mount ${dev}1 $mnt") == 0 or die "can't mount: $!"; |
|
95 |
my $cmd = read_file($0); |
my $cmd = read_file($0); |
96 |
write_file( "$mnt/42.pl", $cmd ); |
write_file( "$mnt/42.pl", $cmd ); |
97 |
chmod 0755, "$mnt/42.pl"; |
chmod 0755, "$mnt/42.pl"; |
108 |
mkpath $fs unless -e $fs; |
mkpath $fs unless -e $fs; |
109 |
|
|
110 |
$fs .= '/' . $file; |
$fs .= '/' . $file; |
111 |
die "$fs exists!" if -e $fs; |
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 |
|
|
120 |
my @stat = stat($path); |
my @stat = stat($path); |
121 |
die "can't stat $path: $!" unless @stat; |
die "can't stat $path: $!" unless @stat; |
122 |
warn "# $path ",$stat[7],$/; |
warn "# $path ",$stat[7],$/; |
123 |
|
|
124 |
partitions(); |
my $size_mb = $stat[7] / 1000 / 1000; # FIXME correctly round to something? |
|
|
|
|
my $size_mb = int( $stat[7] / 1000 / 1000 ) + 1; |
|
125 |
my ( $free_start, undef, $free_size ) = @{$part[0]}; |
my ( $free_start, undef, $free_size ) = @{$part[0]}; |
126 |
|
|
127 |
my $part_end = $free_start + $size_mb; |
my $part_end = int( $free_start + $size_mb + 1 ); |
128 |
|
|
129 |
my $last_part = $#part; |
my $last_part = $#part; |
130 |
|
|
131 |
system("umount $mnt"); |
parted("mkpart logical ${free_start}MB ${part_end}MB "); |
|
parted("mkpart logical ${free_start}MB ${part_end}MB"); |
|
|
partitions(); |
|
|
system("mount ${dev}1 $mnt") == 0 or die "can't mount $mnt: $!"; |
|
132 |
|
|
133 |
my $part_size = $part[$#part]->[2] || die "can't get size of new partition"; |
my $part_size = $part[$#part]->[2] || die "can't get size of new partition"; |
134 |
|
|
136 |
|
|
137 |
my $part_nr = $#part; |
my $part_nr = $#part; |
138 |
|
|
|
die "can't create partition $last_part == $part_nr" if $last_part == $part_nr; |
|
|
|
|
139 |
write_file( "$mnt/stat/$part_nr", join("\n",@stat) ); |
write_file( "$mnt/stat/$part_nr", join("\n",@stat) ); |
140 |
|
|
141 |
my $log = "$mnt/log/$part_nr"; |
my $log = "$mnt/log/$part_nr"; |