summaryrefslogtreecommitdiffstats
path: root/rescue/bin/guessmounts
blob: 714d26251ab337487c3010a719fe9128528e9be8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/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 = $_->{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";
}