summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perl-install/devices.pm13
-rw-r--r--perl-install/diskdrake/interactive.pm1
-rw-r--r--perl-install/fs.pm10
-rw-r--r--perl-install/fs/mount_options.pm4
-rw-r--r--perl-install/fs/type.pm5
-rw-r--r--perl-install/install_any.pm112
-rw-r--r--perl-install/install_steps.pm2
-rw-r--r--perl-install/install_steps_interactive.pm2
-rw-r--r--perl-install/partition_table.pm20
-rwxr-xr-xperl-install/standalone/drakupdate_fstab1
10 files changed, 142 insertions, 28 deletions
diff --git a/perl-install/devices.pm b/perl-install/devices.pm
index 8a3654566..c7be884c2 100644
--- a/perl-install/devices.pm
+++ b/perl-install/devices.pm
@@ -239,4 +239,17 @@ sub from_devfs {
undef;
}
+sub simple_partition_scan {
+ my ($part) = @_;
+ $part->{device} =~ /([hs]d[a-z])(\d+)$/;
+}
+sub part_number {
+ my ($part) = @_;
+ (simple_partition_scan($part))[1];
+}
+sub part_prefix {
+ my ($part) = @_;
+ (simple_partition_scan($part))[0];
+}
+
1;
diff --git a/perl-install/diskdrake/interactive.pm b/perl-install/diskdrake/interactive.pm
index 679235d95..412258eed 100644
--- a/perl-install/diskdrake/interactive.pm
+++ b/perl-install/diskdrake/interactive.pm
@@ -27,6 +27,7 @@ struct part {
int size # in sectors
int pt_type # 0x82, 0x83, 0x6 ...
string fs_type # 'ext2', 'nfs', ...
+ int part_number # 1 for hda1...
string device # 'hda5', 'sdc1' ...
string devfs_device # 'ide/host0/bus0/target0/lun0/part5', ...
string prefer_devfs_name # should the {devfs_device} or the {device} be used in fstab
diff --git a/perl-install/fs.pm b/perl-install/fs.pm
index 8d76939b8..2f8eb0057 100644
--- a/perl-install/fs.pm
+++ b/perl-install/fs.pm
@@ -157,8 +157,14 @@ sub subpart_from_wild_device_name {
}
$dev =~ s!/(tmp|u?dev)/!!;
- my $is_devfs = $dev =~ m!/(disc|part\d+)$!;
- $part{$is_devfs ? 'devfs_device' : 'device'} = $dev;
+ if (my ($is_devfs, $part_number) = $dev =~ m!/(disc|part(\d+))$!) {
+ $part{part_number} = $part_number if $part_number;
+ $part{devfs_device} = $dev;
+ } else {
+ $part{device} = $dev;
+ my $part_number = devices::part_number(\%part);
+ $part{part_number} = $part_number if $part_number;
+ }
return \%part;
} elsif ($dev =~ m!^/! && -f "$::prefix$dev") {
#- loopback file
diff --git a/perl-install/fs/mount_options.pm b/perl-install/fs/mount_options.pm
index c7baa4e7b..b4890e877 100644
--- a/perl-install/fs/mount_options.pm
+++ b/perl-install/fs/mount_options.pm
@@ -195,7 +195,7 @@ sub set_default {
if ($part->{fs_type} eq 'smbfs') {
add2hash($options, { 'username=' => '%' }) if !$options->{'credentials='};
}
- if (member('vfat', split(':', $part->{fs_type})) || $part->{fs_type} eq 'auto') {
+ if (fs::type::can_be_this_fs_type($part, 'vfat')) {
put_in_hash($options, {
users => 1, noexec => 0,
@@ -211,7 +211,7 @@ sub set_default {
'umask=0' => $opts{security} < 3, 'umask=0022' => $opts{security} < 4,
});
}
- if (member('iso9660', split(':', $part->{fs_type})) || $part->{fs_type} eq 'auto') {
+ if (fs::type::can_be_this_fs_type($part, 'iso9660')) {
put_in_hash($options, { user => 1, noexec => 0, 'iocharset=' => $opts{iocharset} });
}
if ($part->{fs_type} eq 'reiserfs') {
diff --git a/perl-install/fs/type.pm b/perl-install/fs/type.pm
index 0b361b8f2..70aace58f 100644
--- a/perl-install/fs/type.pm
+++ b/perl-install/fs/type.pm
@@ -341,6 +341,11 @@ sub isMounted { $_[0]{isMounted} }
sub isBusy { isMounted($_[0]) || isPartOfRAID($_[0]) || isPartOfLVM($_[0]) || isPartOfLoopback($_[0]) }
sub isSpecial { isRAID($_[0]) || isLVM($_[0]) || isLoopback($_[0]) || isUBD($_[0]) }
+sub can_be_this_fs_type {
+ my ($part, $fs_type) = @_;
+ $part->{fs_type} && ($part->{fs_type} eq 'auto' || member($fs_type, split(':', $part->{fs_type})));
+}
+
sub maybeFormatted {
my ($part) = @_;
$part->{isFormatted} || !$part->{notFormatted} && !$part->{bad_fs_type_magic};
diff --git a/perl-install/install_any.pm b/perl-install/install_any.pm
index fa73a4a7b..ac074414e 100644
--- a/perl-install/install_any.pm
+++ b/perl-install/install_any.pm
@@ -1270,24 +1270,106 @@ sub find_root_parts {
} else { () }
} @$fstab;
}
+
+sub migrate_device_names {
+ my ($all_hds, $from_fstab, $new_root, $root_from_fstab, $o_in) = @_;
+
+ log::l("warning: fstab says root partition is $root_from_fstab->{device}, whereas we were reading fstab from $new_root->{device}");
+ my ($old_prefix, $old_part_number) = devices::simple_partition_scan($root_from_fstab);
+ my ($new_prefix, $new_part_number) = devices::simple_partition_scan($new_root);
+
+ if ($old_part_number != $new_part_number) {
+ log::l("argh, $root_from_fstab->{device} and $old_part_number->{device} are not the same partition number");
+ return;
+ }
+
+ log::l("replacing $old_prefix with $new_prefix");
+
+ my %h;
+ foreach (@$from_fstab) {
+ if ($_->{device} =~ s!^\Q$old_prefix!$new_prefix!) {
+ #- this is simple to handle, nothing more to do
+ } elsif ($_->{part_number}) {
+ my $device_prefix = devices::part_prefix($_);
+ push @{$h{$device_prefix}}, $_;
+ } else {
+ #- hopefully this doesn't need anything special
+ }
+ };
+ my @from_fstab_per_hds = values %h or return;
+
+
+ my @current_hds = grep { $new_root->{rootDevice} ne $_->{device} } fs::get::hds($all_hds);
+
+ found_one:
+ @from_fstab_per_hds or return;
+
+ foreach my $from_fstab_per_hd (@from_fstab_per_hds) {
+ my ($matching, $other) = partition {
+ my $hd = $_;
+ every {
+ my $wanted = $_;
+ my $part = find { $_->{part_number} eq $wanted->{part_number} } partition_table::get_normal_parts($hd);
+ $part && $part->{fs_type} && fs::type::can_be_this_fs_type($wanted, $part->{fs_type});
+ } @$from_fstab_per_hd;
+ } @current_hds;
+ @$matching == 1 or next;
+
+ my ($hd) = @$matching;
+ @current_hds = @$other;
+ @from_fstab_per_hds = grep { $_ != $from_fstab_per_hd } @from_fstab_per_hds;
+
+ log::l("$hd->{device} nicely corresponds to " . join(' ', map { $_->{device} } @$from_fstab_per_hd));
+ foreach (@$from_fstab_per_hd) {
+ partition_table::compute_device_name($_, $hd);
+ }
+ goto found_one;
+ }
+
+ #- we can't find one and only one matching hd
+ my @from_fstab_not_handled = map { @$_ } @from_fstab_per_hds;
+ log::l("we still don't know what to do with: " . join(' ', map { $_->{device} } @from_fstab_not_handled));
+
+
+ if (!$o_in) {
+ die 'still have';
+ log::l("well, ignoring them!");
+ return;
+ }
+
+ my $propositions_valid = every {
+ my $wanted = $_;
+ my @parts = grep { $_->{part_number} eq $wanted->{part_number}
+ && $_->{fs_type} && fs::type::can_be_this_fs_type($wanted, $_->{fs_type}) } fs::get::hds_fstab(@current_hds);
+ $wanted->{propositions} = \@parts;
+ @parts > 0;
+ } @from_fstab_not_handled;
+
+ $o_in->ask_from('',
+ N("The "),
+ [ map {
+ { label => N("%s (was %s)", $_->{mntpoint}, $_->{device}), val => \$_->{device},
+ format => sub { $_[0] && $_->{device} },
+ list => [ '',
+ $propositions_valid ? @{$_->{propositions}} :
+ fs::get::hds_fstab(@current_hds) ] };
+ } @from_fstab_not_handled ]);
+}
+
sub use_root_part {
- my ($all_hds, $part, $prefix) = @_;
+ my ($all_hds, $part, $o_in) = @_;
{
- my $handle = any::inspect($part, $prefix) or die;
-
- my @l = fs::read_fstab($handle->{dir}, '/etc/fstab', 'keep_default');
-
- my $root = fs::get::root_(\@l);
- if (!fsedit::is_same_hd($root, $part)) {
- log::l("warning: fstab says root partition is $root->{device}, whereas we were reading fstab from $part->{device}");
- my ($old, $new) = map { my $s = $_->{device}; $s =~ s/\d+$//; $s } ($root, $part);
- if ($old && $new) {
- log::l("replacing $old with $new");
- $_->{device} =~ s!^\Q$old!$new! foreach @l;
- log::l("l contains: $_->{device} $_->{mntpoint}") foreach @l;
- }
+ my $handle = any::inspect($part, $::prefix) or die;
+
+ my @from_fstab = fs::read_fstab($handle->{dir}, '/etc/fstab', 'keep_default');
+
+ my $root_from_fstab = fs::get::root_(\@from_fstab);
+ if (!fsedit::is_same_hd($root_from_fstab, $part)) {
+ log::l("from_fstab contained: $_->{device} $_->{mntpoint}") foreach @from_fstab;
+ migrate_device_names($all_hds, \@from_fstab, $part, $root_from_fstab, $o_in);
+ log::l("from_fstab now contains: $_->{device} $_->{mntpoint}") foreach @from_fstab;
}
- fs::add2all_hds($all_hds, @l);
+ fs::add2all_hds($all_hds, @from_fstab);
log::l("fstab is now: $_->{device} $_->{mntpoint}") foreach fs::get::fstab($all_hds);
}
isSwap($_) and $_->{mntpoint} = 'swap' foreach fs::get::really_all_fstab($all_hds); #- use all available swap.
diff --git a/perl-install/install_steps.pm b/perl-install/install_steps.pm
index fe8f207e2..f1198479f 100644
--- a/perl-install/install_steps.pm
+++ b/perl-install/install_steps.pm
@@ -170,7 +170,7 @@ sub selectInstallClass {
if ($o->{partitioning}{use_existing_root} || $o->{isUpgrade}) {
# either one root is defined (and all is ok), or we take the first one we find
my $p = fs::get::root_($o->{fstab}) || (first(install_any::find_root_parts($o->{fstab}, $o->{prefix})) || die)->{part};
- install_any::use_root_part($o->{all_hds}, $p, $o->{prefix});
+ install_any::use_root_part($o->{all_hds}, $p);
}
}
diff --git a/perl-install/install_steps_interactive.pm b/perl-install/install_steps_interactive.pm
index b7ac7847c..afee41a6f 100644
--- a/perl-install/install_steps_interactive.pm
+++ b/perl-install/install_steps_interactive.pm
@@ -162,7 +162,7 @@ sub selectInstallClass {
if (ref $p) {
my $part = $p->{part};
log::l("choosing to upgrade partition $part->{device}");
- install_any::use_root_part($o->{all_hds}, $part, $o->{prefix});
+ install_any::use_root_part($o->{all_hds}, $part, $o);
foreach (grep { $_->{mntpoint} } @{$o->{fstab}}) {
my ($options, $_unknown) = fs::mount_options::unpack($_);
$options->{encrypted} or next;
diff --git a/perl-install/partition_table.pm b/perl-install/partition_table.pm
index edb061bdb..26995921d 100644
--- a/perl-install/partition_table.pm
+++ b/perl-install/partition_table.pm
@@ -86,6 +86,12 @@ sub verifyPrimary {
verifyParts_(@{$pt->{normal}}, $pt->{extended});
}
+sub compute_device_name {
+ my ($part, $hd) = @_;
+ $part->{device} = $hd->{prefix} . $part->{part_number};
+ $part->{devfs_device} = $hd->{devfs_prefix} . '/part' . $part->{part_number};
+}
+
sub assign_device_numbers {
my ($hd) = @_;
@@ -104,15 +110,15 @@ sub assign_device_numbers {
log::l("PPC: found a hole on $hd->{prefix} before $_->{start}, skipping device...");
$i++;
}
- $_->{device} = $hd->{prefix} . $i;
- $_->{devfs_device} = $hd->{devfs_prefix} . '/part' . $i;
+ $_->{part_number} = $i;
+ compute_device_name($_, $hd);
$start = $_->{start} + $_->{size};
$i++;
}
} else {
foreach (@{$hd->{primary}{raw}}) {
- $_->{device} = $hd->{prefix} . $i;
- $_->{devfs_device} = $hd->{devfs_prefix} . '/part' . $i;
+ $_->{part_number} = $i;
+ compute_device_name($_, $hd);
$i++;
}
foreach (map { $_->{normal} } @{$hd->{extended} || []}) {
@@ -124,8 +130,8 @@ sub assign_device_numbers {
will_tell_kernel($hd, del => $_, 'delay_del');
push @{$hd->{partitionsRenumbered}}, [ $_->{device}, $dev ];
}
- $_->{device} = $dev;
- $_->{devfs_device} = $hd->{devfs_prefix} . '/part' . $i;
+ $_->{part_number} = $i;
+ compute_device_name($_, $hd);
if ($renumbered) {
will_tell_kernel($hd, add => $_, 'delay_add');
}
@@ -338,7 +344,7 @@ sub will_tell_kernel {
will_tell_kernel($hd, del => $o_part);
will_tell_kernel($hd, add => $o_part);
} else {
- my $part_number = sub { $o_part->{device} =~ /(\d+)$/ ? $1 : internal_error("bad device " . description($o_part)) };
+ my $part_number = sub { devices::part_number($o_part) || internal_error("bad device " . description($o_part)) };
push @{$hd->{'will_tell_kernel' . ($o_delay || '')} ||= []},
[
$action,
diff --git a/perl-install/standalone/drakupdate_fstab b/perl-install/standalone/drakupdate_fstab
index 25fa7ad1c..938800437 100755
--- a/perl-install/standalone/drakupdate_fstab
+++ b/perl-install/standalone/drakupdate_fstab
@@ -82,6 +82,7 @@ sub device_name_to_entry {
my $e;
if (my ($devfs_prefix, $nb) = $name =~ m,(.*)/(?:cd|disc|part(\d+))$,) {
$e = find { $_->{devfs_prefix} eq $devfs_prefix } @l;
+ $e->{part_number} = $nb;
$e->{devfs_prefix} ||= $devfs_prefix;
$e->{devfs_device} = $e->{devfs_prefix} . '/part' . $nb;
if ($e->{devfs_device} eq $name) {