From 1ea3578bfb4c6b4ef7b3854ce4561d8bc9afaef4 Mon Sep 17 00:00:00 2001 From: Pascal Rigaux Date: Fri, 17 Sep 2004 10:33:54 +0000 Subject: try to get geometry from EDD --- perl-install/fsedit.pm | 10 ++++---- perl-install/partition_table/dos.pm | 17 +++++++++++++- perl-install/partition_table/raw.pm | 46 ++++++++++++++++++++++++++++++++++++- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/perl-install/fsedit.pm b/perl-install/fsedit.pm index ddc6a47fd..1072464c7 100644 --- a/perl-install/fsedit.pm +++ b/perl-install/fsedit.pm @@ -104,14 +104,16 @@ sub get_hds { my @drives = detect_devices::hds(); - my (@hds, @raw_hds); foreach my $hd (@drives) { $hd->{file} = devices::make($hd->{device}); $hd->{prefix} ||= $hd->{device}; - $hd->{readonly} = $flags->{readonly}; + } + + partition_table::raw::get_geometries(\@drives); - my $h = partition_table::raw::get_geometry($hd->{file}) or log::l("An error occurred while getting the geometry of block device $hd->{file}: $!"), next; - add2hash_($hd, $h); + my (@hds, @raw_hds); + foreach my $hd (@drives) { + $hd->{readonly} = $flags->{readonly}; eval { partition_table::raw::test_for_bad_drives($hd) }; if (my $err = $@) { diff --git a/perl-install/partition_table/dos.pm b/perl-install/partition_table/dos.pm index 8c30e6558..8a24cec84 100644 --- a/perl-install/partition_table/dos.pm +++ b/perl-install/partition_table/dos.pm @@ -124,6 +124,21 @@ sub guess_geometry_from_partition_table { $geom; } +sub geometry_from_edd { + my ($hd, $edd_dir) = @_; + + my $geom = { sectors => 0 + cat_("$edd_dir/legacy_sectors_per_track"), + heads => 1 + cat_("$edd_dir/legacy_max_head"), + from_edd => 1 }; + partition_table::raw::compute_nb_cylinders($geom, $hd->{totalsectors}); + + log::l("geometry_from_edd $hd->{device} $hd->{volume_id}: " . geometry_to_string($geom)); + + member($geom->{heads}, @valid_nb_heads) && member($geom->{sectors}, @valid_nb_sectors) + && $geom; +} + + sub try_every_geometry { my ($hd) = @_; @@ -148,7 +163,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); diff --git a/perl-install/partition_table/raw.pm b/perl-install/partition_table/raw.pm index 8cbe0ec14..59ca08906 100644 --- a/perl-install/partition_table/raw.pm +++ b/perl-install/partition_table/raw.pm @@ -94,7 +94,51 @@ 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) = @_; + + foreach my $hd (@$hds) { + my $h = get_geometry($hd->{file}) or log::l("An error occurred while getting the geometry of block device $hd->{file}: $!"), next; + add2hash_($hd, $h); + } + + my %id2hd = keep_non_duplicates(map { + my $F = openit($_) or die "failed to open device $_->{device}"; + my $tmp; + if (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; + } + } +} + +sub get_geometry { my ($dev) = @_; my $g = ""; -- cgit v1.2.1