summaryrefslogtreecommitdiffstats
path: root/perl-install/standalone/service_harddrake
blob: cbca4beb760ef4f0f0e5cb121d16c1b08931c31f (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
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/perl

use lib qw(/usr/lib/libDrakX);

use strict;
use diagnostics;
use standalone;     #- warning, standalone must be loaded very first, for 'explanations'
use c;
use common;
use interactive;
use detect_devices;
use harddrake::data;
use harddrake::sound;
use modules;
use Storable qw(store retrieve);

my $invert_do_it = $ARGV[0] eq 'X11' ? 1 : 0;
my ($hw_sysconfdir, $timeout) = ("/etc/sysconfig/harddrake2", $invert_do_it ? 600 : 25);
my $last_boot_config = $hw_sysconfdir."/previous_hw";

$last_boot_config .= '_X11' if $invert_do_it;

modules::mergein_conf('/etc/modules.conf');

# autoreconfigure the mouse on major kernel change:
my $prev_kernel = { getVarsFromSh("$hw_sysconfdir/kernel") }->{KERNEL};
my $curr_kernel = c::kernel_version();
$curr_kernel =~ s/(^\d+\.\d+).*/\1/;
setVarsInSh("$hw_sysconfdir/kernel", KERNEL => $curr_kernel);
if ($curr_kernel ne $prev_kernel) {
    require class_discard;
    require mouse;
    mouse::write_conf(class_discard->new, mouse::detect(), 1);
}

if (find { $_->{driver} =~ /Card:NVIDIA/ } detect_devices::probeall()) {
    if (find { -e join('', "/lib/modules/", c::kernel_version(), "/kernel/drivers/$_") }  map { ("video/$_", "char/$_") } qw(NVdriver nvidia.o nvidia.o.gz nvidia.ko nvidia.ko.gz)) {
        #log::explanations("switch XFree86 driver from nv to nvidia");
        #substInFile { s!Driver "nv.*"!Driver "nvidia"!g; s!#*( Load.*glx)!\1!g } $_ foreach "/etc/X11/XF86Config-4", "/etc/X11/XF86Config";
    } else {
        log::explanations("switch XFree86 driver from nvidia to nv");
        substInFile { s!Driver "nv.*"!Driver "nv"!g; s!([^#]Load.*glx)!#\1!g } $_ foreach "/etc/X11/XF86Config-4", "/etc/X11/XF86Config";
    }
}

my $is_globetrotter = -f '/usr/sbin/mdkmove';

# first run ? if not read old hw config
my $previous_config = -f $last_boot_config && -s $last_boot_config ? Storable::retrieve($last_boot_config) : {};
$previous_config = $$previous_config if ref($previous_config) !~ /HASH/;
my (%config, $wait);
my $in;
my $splash = -f '/proc/splash';
# For each hw, class, detect device, compare and offer to reconfigure if needed
foreach my $hw_class (@harddrake::data::tree) {
    my ($Ident, $item, $configurator, $detector, $do_it) = @$hw_class{qw(class string configurator_auto detector checked_on_boot)};
    $configurator ||= $hw_class->{configurator};

    next unless $do_it ^ $invert_do_it;
    # No detector ? (should never happen but who know ?)
    ref($detector) eq 'CODE' or next;

    my %ID = map {
        my $i = $_;
        my $id = defined $i->{device} ? $i->{device} : join(':', map { $i->{$_} } qw(vendor id subvendor subid));
        $id => $i;
    } eval { &$detector };
    $config{$Ident} = \%ID;
    next if !$is_globetrotter && is_empty_hash_ref $previous_config; # don't fsck on first run

    my $oldconfig = $previous_config->{$Ident};

    my $msg;
    my @was_removed = difference2([ keys %$oldconfig ], [ keys %ID ]);
    if (@was_removed) {
     $msg .= N("Some devices in the \"%s\" hardware class were removed:\n", $item) .
       join('', map { N("- %s was removed\n", harddrake::data::custom_id($oldconfig->{$_}, $item)) } @was_removed) . "\n";
    }
    my @added = difference2([ keys %ID ], [ keys %$oldconfig ]);
    $msg .= N("Some devices were added: %s\n", $item) if @added;
    $msg .= N("- %s was added\n", harddrake::data::custom_id($ID{$_}, $item)) foreach @added;
    log::explanations("removed $Ident: " . harddrake::data::custom_id($oldconfig->{$_}, $item)) foreach @was_removed;
    log::explanations("added $Ident: " . harddrake::data::custom_id($oldconfig->{$_}, $item)) foreach @added;

    modules::load('ohci1394') if $Ident eq 'FIREWIRE_CONTROLLER' && any { $_->{driver} eq 'ohci1394' } @added;
    @added || @was_removed or next;
    my @configurator_pool;
    if (harddrake::data::is_removable($Ident)) {
        foreach my $device (@ID{@added}) {
            push @configurator_pool, harddrake::data::set_removable_configurator($Ident, $device);
        };
        foreach my $device (@$oldconfig{@was_removed}) {
            push @configurator_pool, harddrake::data::set_removable_remover($Ident, $device);
        }
    } else {
        @configurator_pool = $configurator;
    }
    if ($Ident eq "AUDIO") {
        # automatic sound slots configuration
        rm_rf("/etc/asound.state");
        harddrake::sound::configure_sound_slots();
        next;
    } elsif ($Ident eq "ETHERNET") {
        modules::remove_alias_regexp('^(wlan|eth)[0-9]*$');
        modules::load_category('network/main|gigabit|usb|wireless');
        require network::ethernet;
        network::ethernet::configure_eth_aliases();
        modules::write_conf();
    } elsif ($Ident eq "AGP") {
        # add agpgart modules to modprobe.preload if needed:
        modules::write_conf();
    } elsif ($Ident eq "VIDEO") {
        require harddrake::autoconf;
        harddrake::autoconf::xconf();
        undef @configurator_pool;
    }

    next if $is_globetrotter && !$hw_class->{automatic};
    next unless -x first(split /\s+/, $configurator_pool[0]);
    my ($pid, $no, $res);
    if (!$hw_class->{automatic}) {
        $SIG{ALRM} = sub { $no = 1; kill 15, $pid };
        unless ($pid = fork()) {
            $splash and eval { output('/proc/splash', 'verbose') } and $splash = 0;
            exec("/usr/share/harddrake/confirm", $Ident, $timeout, $msg);
        }
        alarm($timeout);
        wait();
        $res = $?;
        alarm(0);
    } else {
        $res = 1;
    }
    if (!$no && $res) {
        foreach my $configurator (@configurator_pool) {
            if (fork()) {
                wait();
            } else {
                exec("$configurator 2>/dev/null") or do {
                    log::explanations(qw(cannot run "$configurator"));
                    require POSIX;
                    POSIX::_exit();
                };
            }
        }
    }
    if (!$hw_class->{automatic}) {
        require interactive;
        undef $wait;
        $in ||= interactive->vnew;
        $wait = $in->wait_message(N("Please wait"), N("Hardware probing in progress"));
    }

}

# output new hw config
log::explanations("created file $last_boot_config");
Storable::store(\%config, $last_boot_config);


$in->exit(0) if $in;