summaryrefslogtreecommitdiffstats
path: root/perl-install/standalone/service_harddrake
blob: 5c4ac681190c5ed56030968faa6cdb8eb0dd5808 (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
#!/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 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');

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";
    }
}

# 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_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;
    $splash and !system('echo verbose > /proc/splash') and $splash = 0;
    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
        system("rm -f /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');
        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();
    }

    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()) {
            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 die "$configurator missing\n" }
        }
    }
    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;