diff options
Diffstat (limited to 'perl-install/partition_table.pm')
| -rw-r--r-- | perl-install/partition_table.pm | 85 |
1 files changed, 34 insertions, 51 deletions
diff --git a/perl-install/partition_table.pm b/perl-install/partition_table.pm index 3bca46d89..39c029899 100644 --- a/perl-install/partition_table.pm +++ b/perl-install/partition_table.pm @@ -1,4 +1,4 @@ -package partition_table; # $Id: partition_table.pm 268438 2010-05-10 14:25:50Z pterjan $ +package partition_table; use diagnostics; use strict; @@ -18,7 +18,7 @@ sub hd2minimal_part { }; } -#- works for both hard drives and partitions ;p +#- works for both hard disk drives and partitions ;p sub description { my ($hd) = @_; my $win = $hd->{device_windobe}; @@ -32,9 +32,22 @@ sub description { $hd->{info}, $hd->{mntpoint}, $hd->{fs_type}); } +#- align partition start to the next MB boundary +sub align_to_MB_boundaries { + my ($part) = @_; + + my $end = $part->{start} + $part->{size}; + $part->{start} = round_up($part->{start}, MB(1)); + $part->{size} = $end - $part->{start}; +} + sub adjustStartAndEnd { my ($hd, $part) = @_; + # always align partition start to MB boundaries + # (this accounts for devices with non-512 physical sector sizes): + align_to_MB_boundaries($part); + $hd->adjustStart($part); $hd->adjustEnd($part); } @@ -51,12 +64,8 @@ sub verifyInside { sub verifyParts_ { foreach my $i (@_) { foreach (@_) { - next if !$i || !$_ || $i == $_ || isWholedisk($i) || isExtended($i); #- avoid testing twice for simplicity :-) - if (isWholedisk($_)) { - verifyInside($i, $_) or - cdie sprintf("partition sector #$i->{start} (%s) is not inside whole disk (%s)!", - formatXiB($i->{size}, 512), formatXiB($_->{size}, 512)); - } elsif (isExtended($_)) { + next if !$i || !$_ || $i == $_ || isExtended($i); #- avoid testing twice for simplicity :-) + if (isExtended($_)) { verifyNotOverlap($i, $_) or log::l(sprintf("warning partition sector #$i->{start} (%s) is overlapping with extended partition!", formatXiB($i->{size}, 512))); #- only warning for this one is acceptable @@ -74,7 +83,7 @@ sub verifyParts { } sub verifyPrimary { my ($pt) = @_; - $_->{start} > 0 || arch() =~ /^sparc/ || die "partition must NOT start at sector 0" foreach @{$pt->{normal}}; + $_->{start} > 0 || die "partition must NOT start at sector 0" foreach @{$pt->{normal}}; verifyParts_(@{$pt->{normal}}, $pt->{extended}); } @@ -95,24 +104,7 @@ sub assign_device_numbers { my $i = 1; my $start = 1; - #- on PPC we need to assign device numbers to the holes too - big FUN! - #- not if it's an IBM machine using a DOS partition table though - if (arch() =~ /ppc/ && detect_devices::get_mac_model() !~ /^IBM/) { - #- first sort the normal parts - $hd->{primary}{normal} = [ sort { $a->{start} <=> $b->{start} } @{$hd->{primary}{normal}} ]; - - #- now loop through them, assigning partition numbers - reserve one for the holes - foreach (@{$hd->{primary}{normal}}) { - if ($_->{start} > $start) { - log::l("PPC: found a hole on $hd->{device} before $_->{start}, skipping device..."); - $i++; - } - $_->{part_number} = $i; - compute_device_name($_, $hd); - $start = $_->{start} + $_->{size}; - $i++; - } - } else { + { foreach (@{$hd->{primary}{raw}}) { $_->{part_number} = $i; compute_device_name($_, $hd); @@ -141,11 +133,11 @@ sub assign_device_numbers { #- first verify there's at least one primary dos partition, otherwise it #- means it is a secondary disk and all will be false :( #- - my ($c, @others) = grep { isFat_or_NTFS($_) } @{$hd->{primary}{normal}}; + my ($c, @others) = grep { isnormal_Fat_or_NTFS($_) } @{$hd->{primary}{normal}}; $i = ord 'C'; $c->{device_windobe} = chr($i++) if $c; - $_->{device_windobe} = chr($i++) foreach grep { isFat_or_NTFS($_) } map { $_->{normal} } @{$hd->{extended}}; + $_->{device_windobe} = chr($i++) foreach grep { isnormal_Fat_or_NTFS($_) } map { $_->{normal} } @{$hd->{extended}}; $_->{device_windobe} = chr($i++) foreach @others; } @@ -221,7 +213,7 @@ sub get_normal_parts_and_holes { my $hole = { start => $current, size => $_->{start} - $current, %$minimal_hole }; put_in_hash($hole, hd2minimal_part($hd)); $hole, $_; - } sort { $a->{start} <=> $b->{start} } grep { !isWholedisk($_) } get_normal_parts($hd); + } sort { $a->{start} <=> $b->{start} } get_normal_parts($hd); push @l, { start => $start, size => min($last - $start, $hd->max_partition_size), %$minimal_hole } if $start < $hd->max_partition_start; grep { !isEmpty($_) || $_->{size} >= $hd->cylinder_size } @l; @@ -230,11 +222,8 @@ sub get_normal_parts_and_holes { sub _default_type { my ($hd) = @_; - arch() =~ /ia64/ ? 'gpt' : - arch() eq "alpha" ? "bsd" : - arch() =~ /^sparc/ ? "sun" : - arch() eq "ppc" && detect_devices::get_mac_model() !~ /^IBM/ ? "mac" : - $hd->{totalsectors} > 4 * 1024 * 1024 * 2048 ? 'lvm' : "dos"; #- default to LVM on full disk when >4TB + # default to GPT on UEFI systems and disks > 4TB + is_uefi() || $hd->{totalsectors} > 4 * 1024 * 1024 * 2048 ? 'gpt' : "dos"; } sub initialize { @@ -259,9 +248,8 @@ sub read_primary { #- it can be safely considered that the first sector is used to probe the partition table #- but other sectors (typically for extended partition ones) have to match this type! my @parttype = ( - if_(arch() =~ /^ia64/, 'gpt'), # gpt must be tried before dos as it presents a fake compatibility mbr - arch() =~ /^sparc/ ? ('sun', 'bsd') : ('gpt', 'lvm', 'dmcrypt', 'dos', 'bsd', 'sun', 'mac'), + 'gpt', 'lvm', 'dmcrypt', 'dos', 'bsd', 'sun', 'mac', ); foreach ('empty', @parttype, 'unknown') { /unknown/ and die "unknown partition table format on disk " . $hd->{file}; @@ -384,7 +372,7 @@ sub tell_kernel { my $F = partition_table::raw::openit($hd); - run_program::run('udevadm', 'control', '--stop-exec-queue') unless $::isInstall; + run_program::run('udevadm', 'control', '--stop-exec-queue'); my $force_reboot = any { $_->[0] eq 'force_reboot' } @$tell_kernel; if (!$force_reboot) { @@ -392,15 +380,15 @@ sub tell_kernel { my ($action, $part_number, $o_start, $o_size) = @$_; if ($action eq 'add') { - $force_reboot ||= !c::add_partition(fileno $F, $part_number, $o_start, $o_size); + $force_reboot ||= !c::add_partition(fileno($F), $part_number, $o_start, $o_size); } elsif ($action eq 'del') { - $force_reboot ||= !c::del_partition(fileno $F, $part_number); + $force_reboot ||= !c::del_partition(fileno($F), $part_number); } log::l("tell kernel $action ($hd->{device} $part_number $o_start $o_size) force_reboot=$force_reboot rebootNeeded=$hd->{rebootNeeded}"); } } - run_program::run('udevadm', 'control', '--start-exec-queue') unless $::isInstall; + run_program::run('udevadm', 'control', '--start-exec-queue'); if ($force_reboot) { # FIXME Handle LVM/dmcrypt/RAID @@ -408,7 +396,7 @@ sub tell_kernel { foreach (@magic_parts) { syscall_('umount', $_->{real_mntpoint}) or log::l(N("error unmounting %s: %s", $_->{real_mntpoint}, $!)); } - $hd->{rebootNeeded} = !ioctl($F, c::BLKRRPART(), 0); + $hd->{rebootNeeded} = !c::tell_kernel_to_reread_partition_table($hd->{file}); log::l("tell kernel force_reboot ($hd->{device}), rebootNeeded=$hd->{rebootNeeded}"); foreach (@magic_parts) { @@ -439,7 +427,6 @@ sub write { $hd->write(0, $hd->{primary}{raw}, $hd->{primary}{info}) or die "writing of partition table failed"; #- should be fixed but a extended exist with no real extended partition, that blanks mbr! - if (arch() !~ /^sparc/) { foreach (@{$hd->{extended}}) { # in case of extended partitions, the start sector must be local to the partition $_->{normal}{local_start} = $_->{normal}{start} - $_->{start}; @@ -447,7 +434,6 @@ sub write { $hd->write($_->{start}, $_->{raw}) or die "writing of partition table failed"; } - } $hd->{isDirty} = 0; if (my $tell_kernel = delete $hd->{will_tell_kernel}) { @@ -472,7 +458,7 @@ sub active { } -# remove a normal partition from hard drive hd +# remove a normal partition from hard disk drive hd sub remove { my ($hd, $part) = @_; my $i; @@ -524,8 +510,6 @@ sub add_primary { } sub add_extended { - arch() =~ /^sparc|ppc/ and die N("Extended partition not supported on this platform"); - my ($hd, $part, $extended_type) = @_; $extended_type =~ s/Extended_?//; @@ -575,17 +559,16 @@ The only solution is to move your primary partitions to have the hole next to th sub add { my ($hd, $part, $b_primaryOrExtended, $b_forceNoAdjust) = @_; - get_normal_parts($hd) >= ($hd->{device} =~ /^rd/ ? 7 : $hd->{device} =~ /^(ida|cciss|ataraid)/ ? 15 : 63) and cdie "maximum number of partitions handled by linux reached"; + get_normal_parts($hd) >= ($hd->{device} =~ /^rd/ ? 7 : $hd->{device} =~ /^(ida|cciss)/ ? 15 : 63) and cdie "maximum number of partitions handled by linux reached"; set_isFormatted($part, 0); put_in_hash($part, hd2minimal_part($hd)); - $part->{start} ||= 1 if arch() !~ /^sparc/; #- starting at sector 0 is not allowed + $part->{start} ||= 1; #- starting at sector 0 is not allowed adjustStartAndEnd($hd, $part) unless $b_forceNoAdjust; my $nb_primaries = $hd->{device} =~ /^rd/ ? 3 : 1; - if (arch() =~ /^sparc|ppc/ || - $b_primaryOrExtended eq 'Primary' || + if ($b_primaryOrExtended eq 'Primary' || $b_primaryOrExtended !~ /Extended/ && @{$hd->{primary}{normal} || []} < $nb_primaries) { eval { add_primary($hd, $part) }; goto success if !$@; |
