#!/usr/bin/perl # # Guillaume Cottenceau # # Copyright 2001-2005 Mandriva # # This software may be freely redistributed under the terms of the GNU # public license. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # use lib qw(/usr/lib/libDrakX); use common; use devices; use fs; use fs::dmcrypt; use fs::proc_partitions; use fs::type; use lvm; use run_program; my @proc_mounts = fs::read_fstab('', '/proc/mounts'); my $target = '/mnt'; if (fs::get::mntpoint2part($target, \@proc_mounts)) { print STDERR "$target is already mounted (according to /proc/mounts)\n"; exit 0; } system('drvinst', 'STORAGE'); print STDERR "\nPlease wait, trying to find your root device...\n"; mkdir_p($target); { local $::isInstall = 1; # so that detect_during_install() got called by init: lvm::init(); } fs::dmcrypt::init; my @parts = map { $_->{device} = delete $_->{dev}; put_in_hash($_, fs::type::type_subpart_from_magic($_)); } fs::proc_partitions::read_raw(); my ($raid_parts, $normal_parts) = partition { isRawRAID($_) } @parts; if (@$raid_parts) { require raid; raid::detect_during_install(@$raid_parts); my $raids = raid::get_existing(@$raid_parts); push @$normal_parts, @$raids; } my @roots; my $arch = arch() =~ /i.86/ ? $MDK::Common::System::compat_arch{arch()} : arch(); foreach (@$normal_parts) { my $dev = devices::make($_->{device}); my $fs = find { system("mount -t $_ $dev $target 2>/dev/null") == 0; } fs::type::true_local_fs_types() or next; if (my $release_file = common::release_file($target)) { my $release = chomp_(cat_("$target$release_file")); print STDERR "=> found a $release root partition on $dev\n=> type $fs, version `\n"; my @fstab = fs::read_fstab($target, '/etc/fstab'); my $h = common::parse_release_file($target, $release_file, $_); add2hash($h, { dev => $dev, fs => $fs, fstab => \@fstab, pretty_name => "$h->{release} $h->{version} $h->{arch} on $dev" }); # Offer to rescue only same arch: $h->{pretty_name} .= " (cannot be rescued: $h->{arch} ne $arch;)" if $h->{arch} ne $arch; push @roots, $h; } system('umount', $target) == 0 or die "error unmounting $target\n"; } my ($root, $fs, @fstab); # Try Mageia first: if (@roots) { # Order by release number: @roots = sort { $b->{version} cmp $a->{version} } @roots; # Then pick mga over mdv: @roots = map { @$_ } partition { $_->{release} =~ /Mageia/ } @roots; my $selected; if (@roots == 1) { $selected = first(@roots); } else { print "\n\nWhich system do you want to rescue?\n0: Abort\n"; each_index { print $::i + 1, ": $_->{pretty_name}\n" } @roots; my $res; while ($res < 1 || $res > @roots) { print "what is your choice (type the number of your selection or C^c to abort)?\n"; $res = <>; chomp($res); if ($res eq "0") { print "Aborting\n"; exit(1); } } $selected = $roots[$res-1]; } $root = $selected->{dev}; $fs = $selected->{fs}; @fstab = @{$selected->{fstab}}; print STDERR "=> Selecting $root as root fs\n"; } if ($root) { system("mount -t $fs $root $target 2>/dev/null"); print STDERR "\nMounting other partitions from fstab on $target...\n"; foreach (@fstab) { my ($valued_options, $options) = fs::mount_options::unpack($_); next if !$_->{fs_type} || $_->{device} eq 'none' || $valued_options->{noauto} || $_->{mntpoint} eq '/' || member($_->{fs_type}, 'swap', 'nfs', 'ntfs', 'ntfs-3g'); delete $valued_options->{'iocharset='}; delete $valued_options->{'codepage='}; fs::mount_options::pack($_, $valued_options, $options); #- vfat opts, we don't have the modules in rescue my $where = "$target$_->{mntpoint}"; my $dev = fs::wild_device::from_part('', $_); mkdir_p($where); print STDERR "\t$dev on $where type $_->{fs_type} options $_->{options}\n"; system("mount -t $_->{fs_type} $dev $where -o $_->{options}"); } system("mount -t proc proc $target/proc"); print STDERR "\nYour system is ready on $target.\n\n"; } else { die "Could not find your root device :-(.\n"; }