diff options
author | Chmouel Boudjnah <chmouel@mandriva.org> | 1999-07-01 12:29:54 +0000 |
---|---|---|
committer | Chmouel Boudjnah <chmouel@mandriva.org> | 1999-07-01 12:29:54 +0000 |
commit | e1729dfdb9c341fe0b9fed7d7b0a80691a547d82 (patch) | |
tree | b72fd8f59af166fe944ebcf114d648ed5644f752 /perl-install/fsedit.pm | |
parent | b50e655e352e2524fb3fb84b2bb4bc96e6a04cf0 (diff) | |
download | drakx-e1729dfdb9c341fe0b9fed7d7b0a80691a547d82.tar drakx-e1729dfdb9c341fe0b9fed7d7b0a80691a547d82.tar.gz drakx-e1729dfdb9c341fe0b9fed7d7b0a80691a547d82.tar.bz2 drakx-e1729dfdb9c341fe0b9fed7d7b0a80691a547d82.tar.xz drakx-e1729dfdb9c341fe0b9fed7d7b0a80691a547d82.zip |
"See_The_Changelog"
Diffstat (limited to 'perl-install/fsedit.pm')
-rw-r--r-- | perl-install/fsedit.pm | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/perl-install/fsedit.pm b/perl-install/fsedit.pm new file mode 100644 index 000000000..fb2703e8f --- /dev/null +++ b/perl-install/fsedit.pm @@ -0,0 +1,187 @@ +package fsedit; + +use diagnostics; +use strict; + +use common qw(:common); +use partition_table qw(:types); +use partition_table_raw; +use devices; +use log; + +1; + +my @suggestions = ( + { mntpoint => "/boot", minsize => 10 << 11, size => 16 << 11, type => 0x83 }, + { mntpoint => "/", minsize => 50 << 11, size => 100 << 11, type => 0x83 }, + { mntpoint => "swap", minsize => 30 << 11, size => 60 << 11, type => 0x82 }, + { mntpoint => "/usr", minsize => 200 << 11, size => 500 << 11, type => 0x83 }, + { mntpoint => "/home", minsize => 50 << 11, size => 200 << 11, type => 0x83 }, + { mntpoint => "/var", minsize => 200 << 11, size => 250 << 11, type => 0x83 }, + { mntpoint => "/tmp", minsize => 50 << 11, size => 100 << 11, type => 0x83 }, + { mntpoint => "/mnt/iso", minsize => 700 << 11, size => 800 << 11, type => 0x83 }, +); + + +1; + +sub hds($$) { + my ($drives, $flags) = @_; + my @hds; + my $rc; + + foreach (@$drives) { + my $file = devices::make($_->{device}); + + my $hd = partition_table_raw::get_geometry($file) or die "An error occurred while getting the geometry of block device $file: $!"; + $hd->{file} = $file; + $hd->{prefix} = $hd->{device} = $_->{device}; + # for RAID arrays of format c0d0p1 + $hd->{prefix} .= "p" if $hd->{prefix} =~ m,(rd|ida)/,; + + eval { $rc = partition_table::read($hd, $flags->{clearall}) }; + if ($@) { + $@ =~ /bad magic number/ or die; + $flags->{forcezero} && !$::testing ? partition_table_raw::zero_MBR($hd) : die; + } + $rc ? push @hds, $hd : log::l("An error occurred reading the partition table for the block device $_->{device}"); + } + [ @hds ]; +} + +sub get_fstab(@) { + map { partition_table::get_normal_parts($_) } @_; +} + +sub suggest_part($$$;$) { + my ($hd, $part, $hds, $suggestions) = @_; + $suggestions ||= \@suggestions; + foreach (@$suggestions) { $_->{minsize} ||= $_->{size} } + + my $has_swap; + my @mntpoints = map { $has_swap ||= isSwap($_); $_->{mntpoint} } get_fstab(@$hds); + my %mntpoints; @mntpoints{@mntpoints} = undef; + + my ($best, $second) = + grep { $part->{size} >= $_->{minsize} } + grep { !exists $mntpoints{$_->{mntpoint}} || isSwap($_) && !$has_swap } + @$suggestions or return; + + $best = $second if + $best->{mntpoint} eq '/boot' && + $part->{start} + $best->{minsize} > 1024 * partition_table::cylinder_size($hd); # if the empty slot is beyond the 1024th cylinder, no use having /boot + + defined $best or return; # sorry no suggestion :( + + $part->{mntpoint} = $best->{mntpoint}; + $part->{type} = $best->{type}; + $part->{size} = min($part->{size}, $best->{size}); + 1; +} + + +#sub partitionDrives { +# +# my $cmd = "/sbin/fdisk"; +# -x $cmd or $cmd = "/usr/bin/fdisk"; +# +# my $drives = findDrivesPresent() or die "You don't have any hard drives available! You probably forgot to configure a SCSI controller."; +# +# foreach (@$drives) { +# my $text = "/dev/" . $_->{device}; +# $text .= " - SCSI ID " . $_->{id} if $_->{device} =~ /^sd/; +# $text .= " - Model " . $_->{info}; +# $text .= " array" if $_->{device} =~ /^c.d/; +# +# # truncate at 50 columns for now +# $text = substr $text, 0, 50; +# } +# #TODO TODO +#} + + + +sub checkMountPoint($$) { +# my $type = shift; +# local $_ = shift; +# +# m|^/| or die "The mount point $_ is illegal.\nMount points must begin with a leading /"; +# m|(.)/$| and die "The mount point $_ is illegal.\nMount points may not end with a /"; +# c::isprint($_) or die "The mount point $_ is illegal.\nMount points must be made of printable characters (no accents...)"; +# +# foreach my $dev (qw(/dev /bin /sbin /etc /lib)) { +# /^$dev/ and die "The $_ directory must be on the root filesystem.", +# } +# +# if ($type eq 'linux_native') { +# $_ eq '/'; and return 1; +# foreach my $r (qw(/var /tmp /boot /root)) { +# /^$r/ and return 1; +# } +# die "The mount point $_ is illegal.\nSystem partitions must be on Linux Native partitions"; +# } +# 1; +} + +sub removeFromList($$$) { + my ($start, $end, $list) = @_; + my $err = "error in removeFromList: removing an non-free block"; + + for (my $i = 0; $i < @$list; $i += 2) { + $start < $list->[$i] and die $err; + $start > $list->[$i + 1] and next; + + if ($start == $list->[$i]) { + $end > $list->[$i + 1] and die $err; + if ($end == $list->[$i + 1]) { + # the free block is just the same size, removing it + splice(@$list, 0, 2); + } else { + # the free block now start just after this block + $list->[$i] = $end; + } + } else { + $end <= $list->[$i + 1] or die $err; + if ($end < $list->[$i + 1]) { + splice(@$list, $i + 2, 0, $end, $list->[$i + 1]); + } + $list->[$i + 1] = $start; # shorten the free block + } + return; + } +} + + +sub allocatePartitions($$) { + my ($hds, $to_add) = @_; + my %free_sectors = map { $_->{device} => [1, $_->{totalsectors} ] } @$hds; # first sector is always occupied by the MBR + my $remove = sub { removeFromList($_->{start}, $_->{start} + $_->{size}, $free_sectors{$_->{rootDevice}}) }; + my $success = 0; + + foreach (get_fstab(@$hds)) { &$remove(); } + + FSTAB: foreach (@$to_add) { + foreach my $hd (@$hds) { + my $v = $free_sectors{$hd->{device}}; + for (my $i = 0; $i < @$v; $i += 2) { + my $size = $v->[$i + 1] - $v->[$i]; + $_->{size} > $size and next; + $_->{start} = $v->[$i]; + $_->{rootDevice} = $hd->{device}; + partition_table::adjustStartAndEnd($hd, $_); + &$remove(); + partition_table::add($hd, $_); + $success++; + next FSTAB; + } + } + log::ld("can't allocate partition $_->{mntpoint} of size $_->{size}, not enough room"); + } + $success; +} + +sub auto_allocate($;$) { + my ($hds, $suggestions) = @_; + allocatePartitions($hds, $suggestions || \@suggestions); + map { partition_table::assign_device_numbers($_) } @$hds; +} |