#!/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(); # Basically doing fsedit::raids(): 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; } # Basically doing fsedit::dmcrypts(): (my $luks_parts, $normal_parts) = partition { isRawLUKS($_) } @$normal_parts; if (@$luks_parts) { use interactive; use interactive::curses; require diskdrake::interactive; my $in = interactive->vnew('su'); my $all_hds = fsedit::get_hds({}, $in); # Unlocking them in order to look at their fs (do they hold a Mageia installation): foreach my $part (@$luks_parts) { diskdrake::interactive::dmcrypt_open($in, undef, $part, $all_hds) } my @dmcrypts = fs::dmcrypt::get_existing(@$luks_parts); push @$normal_parts, @dmcrypts; } my @roots; my $arch = arch() =~ /i.86/ ? $MDK::Common::System::compat_arch{arch()} : arch(); foreach (@$normal_parts) { my $dev = devices::make($_->{device}); my $fs = $_->{fs_type}; member($fs, fs::type::true_local_fs_types()) or next; system("mount -t $fs $dev $target 2>/dev/null"); if (my $release_file = common::release_file($target)) { 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" }); my $release = chomp_(cat_("$target$release_file")); printf STDERR "=> found a %s root partition on $dev\n=> type $fs, version `$release'\n", $h->{release}; # 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(qw(mount -t proc proc), "$target/proc"); foreach (qw(/dev /run /sys)) { system('mount', '--bind', $_, "$target/$_"); } print STDERR "\nYour system is ready on $target.\n\n"; } else { die "Could not find your root device :-(.\n"; }