summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rigaux <pixel@mandriva.com>2004-09-17 10:33:54 +0000
committerPascal Rigaux <pixel@mandriva.com>2004-09-17 10:33:54 +0000
commit1ea3578bfb4c6b4ef7b3854ce4561d8bc9afaef4 (patch)
treef7c69b2ee55ed40ab4f6c0fa4e5e5f26b3239f84
parent69617c268cef38da90a2a40dd8ec3c2b385a09e9 (diff)
downloaddrakx-1ea3578bfb4c6b4ef7b3854ce4561d8bc9afaef4.tar
drakx-1ea3578bfb4c6b4ef7b3854ce4561d8bc9afaef4.tar.gz
drakx-1ea3578bfb4c6b4ef7b3854ce4561d8bc9afaef4.tar.bz2
drakx-1ea3578bfb4c6b4ef7b3854ce4561d8bc9afaef4.tar.xz
drakx-1ea3578bfb4c6b4ef7b3854ce4561d8bc9afaef4.zip
try to get geometry from EDD
-rw-r--r--perl-install/fsedit.pm10
-rw-r--r--perl-install/partition_table/dos.pm17
-rw-r--r--perl-install/partition_table/raw.pm46
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 = "";