summaryrefslogtreecommitdiffstats
path: root/perl-install/partition_table
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/partition_table')
-rw-r--r--perl-install/partition_table/bsd.pm2
-rw-r--r--perl-install/partition_table/dos.pm26
-rw-r--r--perl-install/partition_table/empty.pm2
-rw-r--r--perl-install/partition_table/gpt.pm4
-rw-r--r--perl-install/partition_table/lvm_PV.pm12
-rw-r--r--perl-install/partition_table/mac.pm17
-rw-r--r--perl-install/partition_table/raw.pm54
-rw-r--r--perl-install/partition_table/sun.pm6
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;