diff options
Diffstat (limited to 'rescue/bin/guessmounts')
| -rwxr-xr-x | rescue/bin/guessmounts | 168 | 
1 files changed, 168 insertions, 0 deletions
| diff --git a/rescue/bin/guessmounts b/rescue/bin/guessmounts new file mode 100755 index 000000000..494f98f44 --- /dev/null +++ b/rescue/bin/guessmounts @@ -0,0 +1,168 @@ +#!/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)) { +	system('mount', '--bind', $_, "$target/$_"); +    } +    system(qw(mount -t sysfs sysfs), "$target/sys"); +    system(qw(mount -t efivarfs efivarfs), "$target/sys/firmware/efi/efivars") if is_uefi(); +    print STDERR "\nYour system is ready on $target.\n\n"; +} else { +    die "Could not find your root device :-(.\n"; +} + | 
