--- 42.pl 2009/07/19 11:55:06 3 +++ 42.pl 2009/07/19 13:08:33 4 @@ -11,7 +11,7 @@ my $dev = '/dev/sdb'; my $mnt = '/mnt/42'; -my ( $init, $debug ); +my ( $verbose, $init, $debug ) = ( 1 ); GetOptions( 'init!' => \$init, @@ -19,42 +19,77 @@ ) or die "unknown options: $!"; +sub size { + my $size = shift; + $size =~ s{MB}{}; + $size; +} + my @part; sub partitions { + @part = (); open(my $parted, '-|', "parted -s $dev unit mb print free") || die "parted: $!"; while(<$parted>) { - warn "## $_" if $debug; - 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+}; + chomp; s{^\s+}{}; - s{([\d\.]+)MB}{$1}g; - my ( $nr, $start, $end, $size, undef ) = split(/\s+/, $_, 5); - $part[$nr] = [ $start, $end, $size ]; + next unless $_; + my @p = map { size($_) } split(/\s+/, $_ ); + warn "## $_ ",dump( @p ) if $debug; + if ( $p[3] && $p[3] eq 'Free' ) { + $part[0] = [ @p ]; + } elsif ( $p[0] =~ m{^\d+$} ) { + my $nr = shift @p; + $part[$nr] = [ @p ]; + } else { + warn "SKIP ",dump( @p ) if $debug; + } } - warn "## part = ",dump( @part ) if $debug; + warn "# part = ",dump( @part ) if $verbose; return @part; } +sub mount_42 { + my $node = $dev . '1'; + if ( ! -e $node ) { + print STDERR "wait for $node"; + sleep 1; + while ( ! -e $node ) { + print STDERR "."; + sleep 1; + } + } + warn "+ mount $node $mnt"; + system("mount $node $mnt") == 0 or die "can't mount: $!"; +} + +my $remount_on = qr/(mkpart|rm)/; + sub parted { my $command = shift; + my @before = partitions(); + + system "umount $mnt" if $command =~ $remount_on; + warn "+ $command\n"; - system("parted -s $dev unit mb $command") == 0 or die "parted: $!"; + system("parted -s $dev unit mb $command") == 0 or die "parted: $?"; + if ( $command =~ $remount_on ) { + my @part = partitions(); + while ( $#before == $#part ) { + warn "re-read partition table\n"; + sleep 1; + @part = partitions(); + } + mount_42 if $part[1]; + } } +partitions(); if ( $init ) { - system("umount $mnt"); - partitions(); - parted("rm $_") foreach grep { defined $part[$_] } ( 1 .. 4 ); + parted("rm $_") foreach grep { defined $part[$_] } map { $#part - $_ + 1 } ( 1 .. $#part ); parted("mkpartfs primary ext2 0 42MB"); - partitions(); parted("mkpart extended 42MB " . $part[0]->[1] . 'MB'); - system "sync;sync"; - partitions(); - system("mount ${dev}1 $mnt") == 0 or die "can't mount: $!"; my $cmd = read_file($0); write_file( "$mnt/42.pl", $cmd ); chmod 0755, "$mnt/42.pl"; @@ -77,19 +112,14 @@ die "can't stat $path: $!" unless @stat; warn "# $path ",$stat[7],$/; -partitions(); - -my $size_mb = int( $stat[7] / 1000 / 1000 ) + 1; +my $size_mb = int( $stat[7] / 1000 / 1000 ) + 1; # FIXME correctly round to something? my ( $free_start, undef, $free_size ) = @{$part[0]}; my $part_end = $free_start + $size_mb; my $last_part = $#part; -system("umount $mnt"); -parted("mkpart logical ${free_start}MB ${part_end}MB"); -partitions(); -system("mount ${dev}1 $mnt") == 0 or die "can't mount $mnt: $!"; +parted("mkpart logical ${free_start}MB ${part_end}MB "); my $part_size = $part[$#part]->[2] || die "can't get size of new partition"; @@ -97,8 +127,6 @@ my $part_nr = $#part; -die "can't create partition $last_part == $part_nr" if $last_part == $part_nr; - write_file( "$mnt/stat/$part_nr", join("\n",@stat) ); my $log = "$mnt/log/$part_nr";