diff options
Diffstat (limited to 'perl-install/partition_table')
| -rw-r--r-- | perl-install/partition_table/bsd.pm | 2 | ||||
| -rw-r--r-- | perl-install/partition_table/dos.pm | 26 | ||||
| -rw-r--r-- | perl-install/partition_table/empty.pm | 2 | ||||
| -rw-r--r-- | perl-install/partition_table/gpt.pm | 4 | ||||
| -rw-r--r-- | perl-install/partition_table/lvm_PV.pm | 12 | ||||
| -rw-r--r-- | perl-install/partition_table/mac.pm | 17 | ||||
| -rw-r--r-- | perl-install/partition_table/raw.pm | 54 | ||||
| -rw-r--r-- | perl-install/partition_table/sun.pm | 6 |
8 files changed, 97 insertions, 26 deletions
diff --git a/perl-install/partition_table/bsd.pm b/perl-install/partition_table/bsd.pm index cdf18e6d1..0e2421c25 100644 --- a/perl-install/partition_table/bsd.pm +++ b/perl-install/partition_table/bsd.pm @@ -73,7 +73,7 @@ sub read($$) { my $size = psizeof($format); my @pt = map { my %h; @h{@fields} = unpack $format, $_; - $h{pt_type} = $pt_typeToDos{$h{pt_type}} || $h{pt_type}; + fs::type::set_pt_type(\%h, $pt_typeToDos{$h{pt_type}} || $h{pt_type}); \%h; } $info{partitions} =~ /(.{$size})/g; diff --git a/perl-install/partition_table/dos.pm b/perl-install/partition_table/dos.pm index 38cdf60ed..23164a286 100644 --- a/perl-install/partition_table/dos.pm +++ b/perl-install/partition_table/dos.pm @@ -124,6 +124,22 @@ sub guess_geometry_from_partition_table { $geom; } +sub geometry_from_edd { + my ($hd, $edd_dir) = @_; + + my $sectors = cat_("$edd_dir/legacy_sectors_per_track") or return; + my $heads = cat_("$edd_dir/legacy_max_head") or return; + + my $geom = { sectors => 0 + $sectors, heads => 1 + $heads, from_edd => 1 }; + is_geometry_valid_for_the_partition_table($hd, $geom, 0) or return; + partition_table::raw::compute_nb_cylinders($geom, $hd->{totalsectors}); + + log::l("geometry_from_edd $hd->{device} $hd->{volume_id}: " . geometry_to_string($geom)); + + $geom; +} + + sub try_every_geometry { my ($hd) = @_; @@ -148,7 +164,7 @@ sub set_best_geometry_for_the_partition_table { my $guessed_geom = guess_geometry_from_partition_table($hd); if ($guessed_geom->{empty}) { - log::l("$hd->{device}: would need looking at BIOS info to find out geometry"); + log::l("$hd->{device}: would need looking at BIOS info to find out geometry") if !$hd->{geom}{from_edd}; return; } my $default_ok = is_geometry_valid_for_the_partition_table($hd, $hd->{geom}, 0); @@ -185,7 +201,9 @@ sub read { my @pt = map { sysread $F, $tmp, psizeof($format) or die "error while reading partition table in sector $sector"; - my %h; @h{@fields} = unpack $format, $tmp; + my %h; + @h{@fields} = unpack $format, $tmp; + fs::type::set_pt_type(\%h, $h{pt_type}); \%h; } (1..$nb_primary); @@ -198,9 +216,11 @@ sub read { # write the partition table (and extended ones) # for each entry, it uses fields: start, size, pt_type, active -sub write($$$;$) { +sub write { my ($hd, $sector, $pt) = @_; + log::l("partition::dos::write $hd->{device}"); + #- handle testing for writing partition table on file only! my $F; if ($::testing) { diff --git a/perl-install/partition_table/empty.pm b/perl-install/partition_table/empty.pm index 596088619..66a384ab3 100644 --- a/perl-install/partition_table/empty.pm +++ b/perl-install/partition_table/empty.pm @@ -30,7 +30,7 @@ sub read($$) { partition_table::raw::zero_MBR($hd); - $hd->{primary}{raw}; + $hd->{primary}{raw}, $hd->{primary}{info}; } 1; diff --git a/perl-install/partition_table/gpt.pm b/perl-install/partition_table/gpt.pm index 2f1506bbd..423d73a7a 100644 --- a/perl-install/partition_table/gpt.pm +++ b/perl-install/partition_table/gpt.pm @@ -130,8 +130,8 @@ sub read_partitionEntries { sysread $F, $tmp, psizeof($partitionEntry_format) or die "error while reading partition table in sector $info->{partitionEntriesLBA}"; my %h; @h{@$partitionEntry_fields} = unpack $partitionEntry_format, $tmp; $h{size} = $h{ending} - $h{start} + 1; - $h{pt_type} = $gpt_types_rev{$h{gpt_type}}; - $h{pt_type} = 0x100 if !defined $h{pt_type}; + my $pt_type = $gpt_types_rev{$h{gpt_type}}; + fs::type::set_pt_type(\%h, defined $pt_type ? $pt_type : 0x100); \%h; } (1 .. $info->{nbPartitions}); \@pt; diff --git a/perl-install/partition_table/lvm_PV.pm b/perl-install/partition_table/lvm_PV.pm index 6311a7da5..b53867d5f 100644 --- a/perl-install/partition_table/lvm_PV.pm +++ b/perl-install/partition_table/lvm_PV.pm @@ -8,9 +8,6 @@ our @ISA = qw(partition_table::raw); use partition_table::raw; use c; -my $magic = "HM\1\0"; -my $offset = 0; - #- Allows people having PVs on unpartitioned disks to install #- (but no way to create such beasts) @@ -21,13 +18,12 @@ my $offset = 0; sub read { - my ($hd, $sector) = @_; + my ($hd, $_sector) = @_; - my $F = partition_table::raw::openit($hd) or die "failed to open device"; - c::lseek_sector(fileno($F), $sector, $offset) or die "reading of partition in sector $sector failed"; + require fs::type; + my $t = fs::type::type_subpart_from_magic($hd); - sysread $F, my $tmp, length $magic or die "error reading magic number on disk $hd->{file}"; - $tmp eq $magic or die "bad magic number on disk $hd->{file}"; + $t && $t->{pt_type} == 0x8e or die "bad magic number on disk $hd->{device}"; []; } diff --git a/perl-install/partition_table/mac.pm b/perl-install/partition_table/mac.pm index 219b6434d..4b60710bb 100644 --- a/perl-install/partition_table/mac.pm +++ b/perl-install/partition_table/mac.pm @@ -7,6 +7,7 @@ use vars qw(@ISA $freepart $bootstrap_part $macos_part); @ISA = qw(partition_table::raw); use common; +use fs::type; use partition_table::raw; use partition_table; use c; @@ -139,7 +140,7 @@ sub read($$) { $h{start} = ($h{pPBlockStart} * $info{bzBlkSize}) / 512; if ($h{pType} =~ /^Apple_UNIX_SVR2/i) { - $h{pName} =~ /swap/i ? ($h{pt_type} = 0x82) : ($h{pt_type} = 0x83); + $h{fs_type} = $h{pName} =~ /swap/i ? 'swap' : 'ext2'; } elsif ($h{pType} =~ /^Apple_Free/i) { #- need to locate a 1MB partition to setup a bootstrap on if ($freepart && $freepart->{size} >= 1) { @@ -151,7 +152,7 @@ sub read($$) { $h{pt_type} = 0x0; $h{pName} = 'Extra'; } elsif ($h{pType} =~ /^Apple_HFS/i) { - $h{pt_type} = 0x402; + fs::type::set_pt_type(\%h, 0x402); if (defined $macos_part) { #- swag at identifying MacOS - 1st HFS partition } else { @@ -297,27 +298,27 @@ sub write($$$;$) { log::l("writing a bootstrap at /dev/$_->{device}"); $install_steps_interactive::new_bootstrap = 1 if !(defined $partition_table::mac::bootstrap_part); $bootstrap_part = "/dev/" . $_->{device}; - } elsif ($_->{pt_type} == 0x82) { + } elsif (isSwap($_)) { $_->{pType} = "Apple_UNIX_SVR2"; $_->{pName} = "swap"; $_->{pFlags} = 0x33; - } elsif ($_->{pt_type} == 0x83) { + } elsif ($_->{fs_type} eq 'ext2') { $_->{pType} = "Apple_UNIX_SVR2"; $_->{pName} = "Linux Native"; $_->{pFlags} = 0x33; - } elsif ($_->{pt_type} == 0x183) { + } elsif ($_->{fs_type} eq 'reiserfs') { $_->{pType} = "Apple_UNIX_SVR2"; $_->{pName} = "Linux ReiserFS"; $_->{pFlags} = 0x33; - } elsif ($_->{pt_type} == 0x283) { + } elsif ($_->{fs_type} eq 'xfs') { $_->{pType} = "Apple_UNIX_SVR2"; $_->{pName} = "Linux XFS"; $_->{pFlags} = 0x33; - } elsif ($_->{pt_type} == 0x383) { + } elsif ($_->{fs_type} eq 'jfs') { $_->{pType} = "Apple_UNIX_SVR2"; $_->{pName} = "Linux JFS"; $_->{pFlags} = 0x33; - } elsif ($_->{pt_type} == 0x483) { + } elsif ($_->{fs_type} eq 'ext3') { $_->{pType} = "Apple_UNIX_SVR2"; $_->{pName} = "Linux ext3"; $_->{pFlags} = 0x33; diff --git a/perl-install/partition_table/raw.pm b/perl-install/partition_table/raw.pm index 8cbe0ec14..0e87cda9d 100644 --- a/perl-install/partition_table/raw.pm +++ b/perl-install/partition_table/raw.pm @@ -20,6 +20,7 @@ if_(arch() =~ /ppc/, [ 'grub', 0, "\xEBH", 0x181, "GRUB \0" ], [ 'lilo', 0x2, "LILO" ], [ 'lilo', 0x6, "LILO" ], + [ 'lilo', 0x6 + 0x40, "LILO" ], #- when relocated in lilo's bsect_update(), variable "space" on paragraph boundary gives 0x40 [ 'grub', 0x6, "GRUB" ], [ 'osbs', 0x2, "OSBS" ], #- http://www.prz.tu-berlin.de/~wolf/os-bs.html [ 'pqmagic', 0xef, "PQV" ], @@ -94,7 +95,58 @@ sub compute_nb_cylinders { $geom->{cylinders} = int $totalsectors / $geom->{heads} / $geom->{sectors}; } -sub get_geometry($) { +sub keep_non_duplicates { + my %l; + $l{$_->[0]}++ foreach @_; + map { @$_ } grep { $l{$_->[0]} == 1 } @_; +} + +sub get_geometries { + my (@hds) = @_; + + @hds = grep { + if (my $h = get_geometry($_->{file})) { + add2hash_($_, $h); + 1; + } else { + log::l("An error occurred while getting the geometry of block device $_->{file}: $!"); + 0; + } + } @hds; + + my %id2hd = keep_non_duplicates(map { + my $F = openit($_) or log::l("failed to open device $_->{device}"); + my $tmp; + if ($F && c::lseek_sector(fileno($F), 0, 0x1b8) && sysread($F, $tmp, 4)) { + [ sprintf('0x%08x', unpack('V', $tmp)), $_ ]; + } else { + (); + } + } @hds); + + + my %id2edd = keep_non_duplicates(map { [ chomp_(cat_("$_/mbr_signature")), $_ ] } glob("/sys/firmware/edd/int13_dev*")); + + log::l("id2hd: " . join(' ', map_each { "$::a=>$::b->{device}" } %id2hd)); + log::l("id2edd: " . join(' ', map_each { "$::a=>$::b" } %id2edd)); + + foreach my $id (keys %id2hd) { + my $hd = $id2hd{$id}; + $hd->{volume_id} = $id; + + if (my $edd_dir = $id2edd{$id}) { + $hd->{bios_from_edd} = $1 if $edd_dir =~ /int13_dev(.*)/; + + require partition_table::dos; + my $geom = partition_table::dos::geometry_from_edd($hd, $edd_dir); + $hd->{geom} = $geom if $geom; + } + } + + @hds; +} + +sub get_geometry { my ($dev) = @_; my $g = ""; diff --git a/perl-install/partition_table/sun.pm b/perl-install/partition_table/sun.pm index 7c8a6beb9..54e734ca8 100644 --- a/perl-install/partition_table/sun.pm +++ b/perl-install/partition_table/sun.pm @@ -9,6 +9,7 @@ use vars qw(@ISA); use common; use partition_table::raw; use partition_table; +use fs::type; use c; my ($main_format, $main_fields) = list2kv( @@ -92,8 +93,9 @@ sub read($$) { my @infos_up = unpack $format1 x $nb_primary, $info{infos}; my @partitions_up = unpack $format2 x $nb_primary, $info{partitions}; foreach (0..$nb_primary-1) { - my $h = { pt_type => $infos_up[2 * $_], flag => $infos_up[1 + 2 * $_], + my $h = { flag => $infos_up[1 + 2 * $_], start_cylinder => $partitions_up[2 * $_], size => $partitions_up[1 + 2 * $_] }; + fs::type::set_pt_type($h, $infos_up[2 * $_]); $h->{start} = $sector + $h->{start_cylinder} * $hd->cylinder_size; $h->{pt_type} && $h->{size} or $h->{$_} = 0 foreach keys %$h; push @pt, $h; @@ -133,7 +135,7 @@ sub write($$$;$) { # $csize += $_->{size} if $_->{pt_type} != 5; # $wdsize += $_->{size} if $_->{pt_type} == 5; $_->{flags} |= 0x10 if $_->{mntpoint} eq '/'; - $_->{flags} |= 0x01 if partition_table::isSwap($_); + $_->{flags} |= 0x01 if !isSwap($_); local $_->{start_cylinder} = $_->{start} / $hd->cylinder_size - $sector; pack($format1, @$_{@$fields1}), pack($format2, @$_{@$fields2}); } @$pt; |
