summaryrefslogtreecommitdiffstats
path: root/perl-install/fsedit.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/fsedit.pm')
-rw-r--r--perl-install/fsedit.pm171
1 files changed, 104 insertions, 67 deletions
diff --git a/perl-install/fsedit.pm b/perl-install/fsedit.pm
index 55efecddd..d209b0196 100644
--- a/perl-install/fsedit.pm
+++ b/perl-install/fsedit.pm
@@ -1,8 +1,9 @@
-package fsedit; # $Id: fsedit.pm 269284 2010-05-24 15:36:50Z pterjan $
+package fsedit;
use diagnostics;
use strict;
use vars qw(%suggestions);
+use feature 'state';
#-######################################################################################
#- misc imports
@@ -22,32 +23,53 @@ use fs;
# min_hd_size: only suggest this partition if the hd size is bigger than that
%suggestions = (
N_("simple") => [
- { mntpoint => "/", size => MB(300), fs_type => defaultFS(), ratio => 10, maxsize => MB(12300) },
- { mntpoint => "swap", size => MB(128), fs_type => 'swap', ratio => 1, maxsize => MB(4000) },
- { mntpoint => "/home", size => MB(300), fs_type => defaultFS(), ratio => 8, min_hd_size => MB(8000) },
+ { mntpoint => "/", size => MB(300), fs_type => defaultFS(), ratio => 6, maxsize => MB(51500) },
+ { mntpoint => "swap", size => MB(256), fs_type => 'swap', ratio => 1, maxsize => MB(4096) },
+ { mntpoint => "/home", size => MB(300), fs_type => defaultFS(), ratio => 12, min_hd_size => MB(51200) },
], N_("with /usr") => [
{ mntpoint => "/", size => MB(250), fs_type => defaultFS(), ratio => 1, maxsize => MB(8000) },
{ mntpoint => "swap", size => MB(64), fs_type => 'swap', ratio => 1, maxsize => MB(4000) },
{ mntpoint => "/usr", size => MB(300), fs_type => defaultFS(), ratio => 4, maxsize => MB(8000) },
- { mntpoint => "/home", size => MB(100), fs_type => defaultFS(), ratio => 3, min_hd_size => MB(7000) },
+ { mntpoint => "/home", size => MB(100), fs_type => defaultFS(), ratio => 3, min_hd_size => MB(10000) },
], N_("server") => [
{ mntpoint => "/", size => MB(150), fs_type => defaultFS(), ratio => 1, maxsize => MB(8000) },
{ mntpoint => "swap", size => MB(64), fs_type => 'swap', ratio => 2, maxsize => MB(4000) },
{ mntpoint => "/usr", size => MB(300), fs_type => defaultFS(), ratio => 4, maxsize => MB(8000) },
{ mntpoint => "/var", size => MB(200), fs_type => defaultFS(), ratio => 3 },
- { mntpoint => "/home", size => MB(150), fs_type => defaultFS(), ratio => 3, min_hd_size => MB(7000) },
+ { mntpoint => "/home", size => MB(150), fs_type => defaultFS(), ratio => 3, min_hd_size => MB(10000) },
{ mntpoint => "/tmp", size => MB(150), fs_type => defaultFS(), ratio => 2, maxsize => MB(4000) },
],
);
-foreach (values %suggestions) {
- if (arch() =~ /ia64/) {
- @$_ = ({ mntpoint => "/boot/efi", size => MB(50), pt_type => 0xef, ratio => 1, maxsize => MB(150) }, @$_);
+my %bck_suggestions = %suggestions;
+
+sub init_mntpnt_suggestions {
+ my ($all_hds, $o_target, $o_force) = @_;
+
+ my $device = $o_target ? $o_target->{device} : 'all';
+ state $last_device;
+ return if $device eq $last_device && !$o_force;
+ $last_device = $device;
+
+ #- If installing on a removable device, assume that the user wants that device to be self-bootable.
+ my $is_removable = $o_target && $o_target->{is_removable};
+ my @fstab = $is_removable ? partition_table::get_normal_parts($o_target) : fs::get::fstab($all_hds);
+
+ my $mntpoint;
+ # only suggests /boot/EFI if there's not already one:
+ require fs::any;
+ if (is_uefi()) {
+ if (!any { isESP($_) } @fstab) {
+ $mntpoint = { mntpoint => "/boot/EFI", size => MB(100), pt_type => 0xef, ratio => 1, maxsize => MB(300) };
+ }
+ }
+ foreach (keys %suggestions) {
+ $suggestions{$_} = [ if_($mntpoint, $mntpoint), @{$bck_suggestions{$_}} ];
}
}
my @suggestions_mntpoints = (
"/var/ftp", "/var/www", "/boot", '/usr/local', '/opt',
- arch() =~ /sparc/ ? "/mnt/sunos" : arch() =~ /ppc/ ? "/mnt/macos" : "/mnt/windows",
+ "/mnt/windows",
);
#-######################################################################################
@@ -60,11 +82,11 @@ sub recompute_loopbacks {
}
sub raids {
- my ($hds) = @_;
+ my ($hds, $raw_hds) = @_;
my @parts = fs::get::hds_fstab(@$hds);
- my @l = grep { isRawRAID($_) } @parts or return [];
+ my @l = grep { isRawRAID($_) } ( @parts, @$raw_hds ) or return [];
log::l("looking for raids in " . join(' ', map { $_->{device} } @l));
@@ -175,6 +197,20 @@ sub get_hds {
foreach my $hd (@drives) {
$hd->{readonly} = $flags->{readonly};
+ #- We only create RAID components in disk partitions, but users may have used
+ #- mdadm directly to create them on raw disk devices. Detect that now, before
+ #- looking for a partition table (which is likely to fail badly - mga#26707).
+ if (my $type = fs::type::type_subpart_from_magic($hd)) {
+ if (isRawRAID($type)) {
+ #- Add the necessary information to the raw device to allow the RAID
+ #- array to be properly characterised in diskdrake.
+ put_in_hash($hd, $type);
+ $hd->{size} = $hd->{totalsectors};
+ push @raw_hds, $hd;
+ next;
+ }
+ }
+
eval { partition_table::raw::test_for_bad_drives($hd) if !$flags->{no_bad_drives} };
if (my $err = $@) {
log::l("test_for_bad_drives returned $err");
@@ -191,7 +227,7 @@ sub get_hds {
if ($flags->{clearall} || member($hd->{device}, @{$flags->{clear} || []})) {
my $lvms = []; #- temporary one, will be re-created later in get_hds()
- partition_table_initialize($lvms, $hd, $o_in);
+ partition_table_clear_and_initialize($lvms, $hd, $o_in);
} else {
my $handle_die_and_cdie = sub {
if (my $type = fs::type::type_subpart_from_magic($hd)) {
@@ -226,7 +262,7 @@ sub get_hds {
die sprintf(q(bad dmraid (missing partition %s), you may try rebooting install with option "nodmraid"), $p->{device});
}
} else {
- fs::proc_partitions::compare($hd) if !detect_devices::is_xbox() && arch() ne 'ppc';
+ fs::proc_partitions::compare($hd) if !detect_devices::is_xbox();
}
}
} sub {
@@ -266,6 +302,9 @@ Do you agree to lose all the partitions?
my @parts = partition_table::get_normal_parts($hd);
+ # fix installer failures due to udev's race when run too early:
+ run_program::run('udevadm', 'settle');
+
# checking the magic of the filesystem, do not rely on pt_type
foreach (@parts) {
if (my $type = fs::type::type_subpart_from_magic($_)) {
@@ -285,7 +324,7 @@ Do you agree to lose all the partitions?
}
#- detect raids before LVM allowing LVM on raid
- my $raids = raids(\@hds);
+ my $raids = raids(\@hds, \@raw_hds);
my $all_hds = { %{ fs::get::empty_all_hds() }, hds => \@hds, raw_hds => \@raw_hds, lvms => [], raids => $raids };
$all_hds->{lvms} = [ lvms($all_hds) ];
@@ -321,7 +360,7 @@ sub is_one_big_fat_or_NT {
sub computeSize {
- my ($part, $best, $all_hds, $suggestions) = @_;
+ my ($part, $best, $all_hds, $suggestions, $o_target) = @_;
my $max = $part->{maxsize} || $part->{size};
return min($max, $best->{size}) unless $best->{ratio};
@@ -336,7 +375,7 @@ sub computeSize {
1;
} else { 0 } } @$suggestions;
- my $free_space = $best->{hd} && $free_space{$best->{hd}} || sum(values %free_space);
+ my $free_space = $o_target && $free_space{$o_target->{device}} || $best->{hd} && $free_space{$best->{hd}} || sum(values %free_space);
my $cylinder_size_maxsize_adjusted;
my $tot_ratios = 0;
@@ -367,7 +406,7 @@ sub computeSize {
}
sub suggest_part {
- my ($part, $all_hds, $o_suggestions) = @_;
+ my ($part, $all_hds, $o_suggestions, $o_target) = @_;
my $suggestions = $o_suggestions || $suggestions{server} || $suggestions{simple};
#- suggestions now use {fs_type}, but still keep compatibility
@@ -377,10 +416,11 @@ sub suggest_part {
my $hd = fs::get::part2hd($part, $all_hds);
my $hd_size = $hd && $hd->{totalsectors}; # nb: no $hd if $part is /dev/mdX
- my $has_swap = any { isSwap($_) } fs::get::fstab($all_hds);
+ my @fstab = $hd->{is_removable} ? partition_table::get_normal_parts($hd) : fs::get::fstab($all_hds);
+ my $has_swap = any { isSwap($_) } @fstab;
my @local_suggestions =
- grep { !$_->{mntpoint} && !$_->{VG_name} || !fs::get::has_mntpoint($_->{mntpoint}, $all_hds) || isSwap($_) && !$has_swap }
+ grep { $::auto_install || !$_->{mntpoint} && !$_->{VG_name} || !fs::get::has_mntpoint($_->{mntpoint}, $all_hds) || isSwap($_) && !$has_swap }
grep { !$_->{min_hd_size} || !$hd_size || $_->{min_hd_size} <= $hd_size }
grep { !$_->{hd} || $_->{hd} eq $part->{rootDevice} }
@$suggestions;
@@ -404,7 +444,7 @@ sub suggest_part {
$part->{mntpoint} = $best->{mntpoint};
fs::type::set_type_subpart($part, $best) if !isTrueFS($best) || !isTrueFS($part);
- $part->{size} = computeSize($part, $best, $all_hds, \@local_suggestions);
+ $part->{size} = computeSize($part, $best, $all_hds, \@local_suggestions, $o_target);
foreach ('options', 'lv_name', 'encrypt_key', 'primaryOrExtended',
'device_LABEL', 'prefer_device_LABEL', 'device_UUID', 'prefer_device_UUID', 'prefer_device') {
$part->{$_} = $best->{$_} if $best->{$_};
@@ -428,33 +468,6 @@ sub check_mntpoint {
$mntpoint =~ m|[\x7f-\xff]| and cdie N("Mount points should contain only alphanumerical characters");
fs::get::mntpoint2part($mntpoint, [ grep { $_ ne $part } fs::get::really_all_fstab($all_hds) ]) and die N("There is already a partition with mount point %s\n", $mntpoint);
- if ($mntpoint eq "/" && isRAID($part) && !fs::get::has_mntpoint("/boot", $all_hds)) {
- # lilo handles / on RAID1
- if ($part->{level} ne '1') {
- cdie N("You've selected a software RAID partition as root (/).
-No bootloader is able to handle this without a /boot partition.
-Please be sure to add a separate /boot partition");
- } else {
- # LILO only handles 0.90 metadata
- if ($part->{isFormatted} && $part->{metadata} && $part->{metadata} ne '0.90') {
- cdie N("Metadata version unsupported for a boot partition. Please be sure to add a separate /boot partition.");
- } else {
- $part->{metadata} = '0.90';
- }
- }
- }
-
- if ($mntpoint eq "/boot" && isRAID($part)) {
- die N("You've selected a software RAID partition as /boot.
-No bootloader is able to handle this.") if $part->{level} ne '1'; # lilo handles /boot on RAID1
- # LILO only handles 0.90 metadata
- if ($part->{isFormatted} && $part->{metadata} && $part->{metadata} ne '0.90') {
- die N("Metadata version unsupported for a boot partition.");
- } else {
- $part->{metadata} = '0.90';
- }
- }
-
if ($mntpoint eq "/" && (isLUKS($part) || isRawLUKS($part)) && !fs::get::has_mntpoint("/boot", $all_hds)) {
cdie N("You've selected an encrypted partition as root (/).
No bootloader is able to handle this without a /boot partition.
@@ -465,21 +478,14 @@ Please be sure to add a separate /boot partition");
die N("You cannot use an encrypted filesystem for mount point %s", "/boot");
}
- #- NB: if the LV doesn't exist, lv_nb_pvs returns 0
- die N("You cannot use the LVM Logical Volume for mount point %s since it spans physical volumes", $mntpoint)
- if $mntpoint eq '/boot' && isLVM($part) && lvm::lv_nb_pvs($part) > 1;
- cdie N("You've selected the LVM Logical Volume as root (/).
-The bootloader is not able to handle this when the volume spans physical volumes.
-You should create a separate /boot partition first") if $mntpoint eq "/" && isLVM($part) && lvm::lv_nb_pvs($part) != 1 && !fs::get::has_mntpoint("/boot", $all_hds);
-
cdie N("This directory should remain within the root filesystem")
if member($mntpoint, qw(/root));
die N("This directory should remain within the root filesystem")
if member($mntpoint, qw(/bin /dev /etc /lib /sbin /mnt /media));
die N("You need a true filesystem (ext2/3/4, reiserfs, xfs, or jfs) for this mount point\n")
if !isTrueLocalFS($part) && $mntpoint eq '/';
- die N("You need a true filesystem (ext2/3/4, reiserfs, xfs, or jfs) for this mount point\n")
- if !isTrueFS($part) && member($mntpoint, '/home', fs::type::directories_needed_to_boot());
+ die N("You need a true filesystem (ext2/3/4, reiserfs, xfs, or jfs) for this mount point\n") . $mntpoint
+ if !isTrueFS($part) && member($mntpoint, '/home', fs::type::directories_needed_to_boot_not_ESP());
die N("You cannot use an encrypted filesystem for mount point %s", $mntpoint)
if $part->{options} =~ /encrypted/ && member($mntpoint, qw(/ /usr /var /boot));
@@ -505,15 +511,16 @@ sub add {
}
sub allocatePartitions {
- my ($all_hds, $to_add) = @_;
+ my ($all_hds, $to_add, $o_hd) = @_;
my @to_add = @$to_add;
foreach my $part_ (fs::get::holes($all_hds, 'non_readonly')) {
my ($start, $size, $dev) = @$part_{"start", "size", "rootDevice"};
+ next if $o_hd && (($o_hd->{device} || $o_hd->{VG_name}) ne $dev);
my ($part, $suggested);
while ($suggested = suggest_part($part = { start => $start, size => 0, maxsize => $size, rootDevice => $dev },
- $all_hds, \@to_add)) {
+ $all_hds, \@to_add, $o_hd)) {
my $hd = fs::get::part2hd($part, $all_hds);
add($hd, $part, $all_hds, { primaryOrExtended => $part->{primaryOrExtended} });
$size -= $part->{size} + $part->{start} - $start;
@@ -524,11 +531,18 @@ sub allocatePartitions {
}
sub auto_allocate {
- my ($all_hds, $o_suggestions) = @_;
+ my ($all_hds, $o_suggestions, $o_target) = @_;
my $before = listlength(fs::get::fstab($all_hds));
+ #- Make sure we don't finish with more than one /boot/EFI mount point
+ if (is_uefi()) {
+ delete $_->{mntpoint} foreach grep { $_->{mntpoint} eq '/boot/EFI' } fs::get::fstab($all_hds);
+ }
+
+ auto_allocate_bios_boot_parts($all_hds, $o_target) if !is_uefi();
+
my $suggestions = $o_suggestions || $suggestions{simple};
- allocatePartitions($all_hds, $suggestions);
+ allocatePartitions($all_hds, $suggestions, $o_target);
if ($o_suggestions) {
auto_allocate_raids($all_hds, $suggestions);
@@ -550,6 +564,28 @@ sub auto_allocate {
die N("Nothing to do");
}
}
+
+ #- Don't suggest mount points on other drives when installing on a removable disk
+ return if $o_target && $o_target->{is_removable};
+
+ my @fstab = fs::get::fstab($all_hds);
+ fs::mount_point::suggest_mount_points_always(\@fstab);
+}
+
+sub auto_allocate_bios_boot_parts {
+ my ($all_hds, $o_hd) = @_;
+ foreach my $hd (@{$all_hds->{hds}}) {
+ # skip if not the selected device
+ next if $o_hd && ($o_hd->{device} ne $hd->{device});
+ # skip non-GPT disks
+ next if ($hd->{pt_table_type} || partition_table::default_type($hd)) ne 'gpt';
+ # check if a BIOS boot partition already exists
+ my @parts = map { partition_table::get_normal_parts($_) } $hd;
+ next if any { isBIOS_GRUB($_) } @parts;
+ # try to allocate a BIOS boot partition
+ my $suggest = { mntpoint => "", size => MB(1), pt_type => 'BIOS_GRUB', ratio => 1, maxsize => MB(2) };
+ allocatePartitions($all_hds, [ $suggest ], $hd);
+ }
}
sub auto_allocate_raids {
@@ -618,13 +654,14 @@ sub change_type {
1;
}
-sub partition_table_clear_and_initialize {
- my ($lvms, $hd, $o_in, $o_type, $b_warn) = @_;
- $hd->clear_existing;
- partition_table_initialize($lvms, $hd, $o_in, $o_type, $b_warn);
-}
+=item partition_table_clear_and_initialize($lvms, $hd, $o_in, $o_type, $b_warn) = @_;
+
+wrapper around partition_table::initialize() but which also create a singleton VG
+automatically (so that it's easier for the user)
-sub partition_table_initialize {
+=cut
+
+sub partition_table_clear_and_initialize {
my ($lvms, $hd, $o_in, $o_type, $b_warn) = @_;
partition_table::initialize($hd, $o_type);
if ($hd->isa('partition_table::lvm')) {