/[soft]/drakx/trunk/perl-install/standalone/service_harddrake
ViewVC logotype

Annotation of /drakx/trunk/perl-install/standalone/service_harddrake

Parent Directory Parent Directory | Revision Log Revision Log


Revision 446 - (hide annotations) (download)
Sun Feb 6 22:37:08 2011 UTC (13 years, 2 months ago) by dmorgan
File size: 15015 byte(s)
Import Clean perl-install
1 dmorgan 446 #!/usr/bin/perl
2    
3     use lib qw(/usr/lib/libDrakX);
4    
5     # prevent firing up drakbug (doesn't work w/o X11):
6     BEGIN { $ENV{DISABLE_DRAKBUG} = 1 }
7    
8     use strict;
9     use diagnostics;
10    
11     # fix translating reasons for 2nd stage warning
12     use lang;
13     BEGIN {
14     my $locale = lang::read($>);
15     lang::set($locale);
16     }
17    
18     use standalone; #- warning, standalone must be loaded very first, for 'explanations'
19     use c;
20     use common;
21     use interactive;
22     use detect_devices;
23     use harddrake::data;
24     use harddrake::autoconf;
25     use harddrake::sound;
26     use Xconfig::card;
27     use modules;
28     use Storable qw(store retrieve);
29    
30    
31     my $force = member('--force', @ARGV);
32    
33     my $invert_do_it = $ARGV[0] eq 'X11' ? 1 : 0;
34     my ($hw_sysconfdir, $timeout) = ("/etc/sysconfig/harddrake2", $invert_do_it ? 600 : 25);
35     my $last_boot_config = "$hw_sysconfdir/previous_hw";
36    
37     $last_boot_config .= '_X11' if $invert_do_it;
38    
39     # first run ? if not read old hw config
40     my $previous_config;
41     if (-f $last_boot_config && -s $last_boot_config) {
42     eval { $previous_config = Storable::retrieve($last_boot_config) };
43     log::explanations("resetting previous hardware file ($@)") if $@;
44     }
45     $previous_config ||= {};
46     $previous_config = $$previous_config if ref($previous_config) !~ /HASH/;
47     my $first_run = is_empty_hash_ref($previous_config);
48    
49     my $modules_conf = modules::any_conf->read;
50    
51     my $isLaptop = detect_devices::isLaptop();
52     my $curr_kernel = c::kernel_version();
53     my ($kernel_major) = $curr_kernel =~ /^(\d+\.\d+)/;
54    
55     my %previous_kernel_config = getVarsFromSh("$hw_sysconfdir/kernel");
56     my %previous_xorg_config = getVarsFromSh("$hw_sysconfdir/xorg");
57     setVarsInSh("$hw_sysconfdir/kernel", { KERNEL => $kernel_major, IS_LAPTOP => bool2text($isLaptop) });
58     my %cfg = getVarsFromSh("$hw_sysconfdir/service.conf");
59    
60     # default to 'yes' on upgrade:
61     $cfg{AUTORECONFIGURE_RIGHT_XORG_DRIVER} = 'yes' if !exists $cfg{AUTORECONFIGURE_RIGHT_XORG_DRIVER};
62    
63     # autoreconfigure laptop-dependent services when switching from laptop to desktop, and vice versa
64     if (!exists $previous_kernel_config{IS_LAPTOP} || $force || $isLaptop != text2bool($previous_kernel_config{IS_LAPTOP})) {
65     log::explanations("Autoconfiguring laptop tools since we switched between laptop and desktop systems");
66     harddrake::autoconf::laptop($isLaptop);
67     }
68    
69     my $known_kernels = "$hw_sysconfdir/kernels";
70     if (!member($curr_kernel, chomp_(cat_($known_kernels)))) {
71     harddrake::autoconf::fix_aliases($modules_conf) if !$first_run;
72     append_to_file($known_kernels, "$curr_kernel\n");
73     }
74    
75     sub get_xorg_driver() {
76     my $x = Xconfig::xfree->read;
77     if ($x) {
78     my ($dev_section) = grep { $_->{name} eq 'Device' } @{$x->{raw}};
79     $dev_section && $dev_section->{l}{Driver}{val};
80     }
81     }
82    
83     sub schedule_warn_about_switch {
84     my ($reason) = @_;
85     output('/var/run/harddrake-notify-x11-free-driver-switch', $reason);
86     }
87    
88     my $lib = arch() =~ /x86_64/ ? "lib64" : "lib";
89    
90     sub find_xorg_driver {
91     my ($new_driver) = @_;
92     # nvidia driver has special place:
93     -e "/usr/$lib/xorg/modules/drivers/${new_driver}_drv.so"
94     || -e "/usr/$lib/xorg/extra-modules/${new_driver}_drv.so";
95     }
96    
97     sub switch_x_driver {
98     my ($old_driver, $new_driver, $reason) = @_;
99     if (!find_xorg_driver($new_driver)) {
100     log::explanations("would switch X.org driver from '$old_driver' to '$new_driver' ($reason); but new driver is not installed");
101     return;
102     }
103     cp_af('/etc/X11/xorg.conf', "/etc/X11/xorg.conf.mga$^T");
104     substInFile { s!Driver "($old_driver)"!Driver "$new_driver"!g } '/etc/X11/xorg.conf';
105     log::explanations("switch X.org driver from '$old_driver' to '$new_driver' ($reason)");
106     Xconfig::card::libgl_config_and_more({ Driver => $new_driver });
107     }
108    
109     sub should_reconfigure_x_driver {
110     my ($card_data, $device, $current_driver) = @_;
111     my $reason;
112     my $reconfigure;
113     my $new_key = $card_data->{Driver} . $card_data->{Driver2};
114     setVarsInSh("$hw_sysconfdir/xorg", { XORG_DRV => $new_key });
115     # auto reconfigure x11 only on first time default driver have changed:
116     if ($previous_xorg_config{XORG_DRV} ne $new_key) {
117     if (!member($current_driver, $card_data->{Driver}, $card_data->{Driver2}, 'fbdev', 'vesa')) {
118     $reason = N("The graphic card '%s' is no more supported by the '%s' driver",
119     $device->{description}, $current_driver);
120     $reconfigure = 1;
121     }
122     } elsif ((stat('/etc/X11/xorg.conf'))[9] < (stat('/etc/product.id'))[9]) {
123     # when switching to a new release (product.id is newer than xorg.conf),
124     # regenerate xorg.conf even if the driver used is vesa or fbdev, this
125     # way we handle switches like "no driver for the card in older releases
126     # but good driver in new release", see bug #53753
127     if (!member($current_driver, $card_data->{Driver}, $card_data->{Driver2})) {
128     $reason = N("New release, reconfiguring X for %s", $device->{description});
129     $reconfigure = 1;
130     }
131     }
132    
133     ($reconfigure, $reason);
134     }
135    
136     my @cards = (
137     {
138     ldetect_driver_regexp => 'Card:NVIDIA',
139     xorg_driver_regexp => 'nv.+',
140     module_names => [ qw(NVdriver nvidia.o nvidia.ko nvidia71xx.ko nvidia96xx.ko nvidia97xx.ko nvidia173.ko nvidia-current.ko) ]
141     },
142     {
143     ldetect_driver_regexp => 'Card:ATI Radeon',
144     xorg_driver_regexp => 'fglrx',
145     module_names => [ qw(fglrx.ko fglrx-hd2000.ko) ]
146     }
147     );
148    
149    
150     my @devices;
151     @devices = grep { $_->{driver} =~ /^Card:/ } detect_devices::probeall()
152     if -f '/etc/X11/xorg.conf';
153    
154     # do not auto reconfigure if more than one graphic card:
155     $cfg{AUTORECONFIGURE_RIGHT_XORG_DRIVER} = 'no' if scalar(@devices) > 1;
156    
157     foreach my $device (@devices) {
158     next if !text2bool($cfg{AUTORECONFIGURE_RIGHT_XORG_DRIVER});
159    
160     my $id = $device->{driver} =~ /Card:(.*)/ && $1;
161     my $card_data = Xconfig::card::readCardsDB("/usr/share/ldetect-lst/Cards+")->{$id};
162     my $current_driver = get_xorg_driver();
163    
164     # nvidia proprietary driver in ldetect-lst can be 'nvidia173', 'nvidia-current', ...
165     # but really is just 'nvidia' in xorg.conf:
166     $card_data->{Driver2} =~ s/(nvidia).*/$1/;
167    
168     # auto reconfigure x11 only on first time default driver have changed:
169     my ($should_reconfigure, $reason) = should_reconfigure_x_driver($card_data, $device, $current_driver);
170     if ($should_reconfigure) {
171     switch_x_driver($current_driver, $card_data->{Driver}, $reason);
172     schedule_warn_about_switch($reason) if any { $current_driver =~ $_->{xorg_driver_regexp} } @cards;
173     # Update $current_driver with the new one
174     $current_driver = $card_data->{Driver};
175     }
176    
177     # nv->nouveau or non_kms_nouveau->kms_nouveau can't have "Disable dri"!
178     if ($current_driver eq "nouveau") {
179     my $raw_x = Xconfig::xfree->read;
180     if ($raw_x) {
181     if (member("dri", $raw_x->get_disabled_modules)) {
182     $raw_x->remove_disable_module("dri");
183     $raw_x->write;
184     }
185     }
186     }
187     }
188    
189    
190     foreach my $card (@cards) {
191     my $device = find { $_->{driver} =~ /$card->{ldetect_driver_regexp}/ } @devices;
192     next if !$device;
193    
194     if (find { -e join('', "/lib/modules/", c::kernel_version(), $_) }
195     map { ("/dkms/$_", "/dkms-binary/$_", "/kernel/$_") } map { "/drivers/$_" } map { ("extra/$_", "video/$_", "char/$_", "char/drm/$_") } map { $_, "$_.gz" } @{$card->{module_names}}) {
196    
197     # do not automatically switch from nv to nvidia (in order to handle
198     # cases where nvidia module crashes the system):
199     #
200     # substInFile {
201     # log::explanations("switch XFree86 driver from nv to nvidia") if /Driver "nv"/;
202     # s!Driver "nv.*"!Driver "nvidia"!g;
203     # s!#*( Load.*glx)!\1!g;
204     # } $_ foreach "/etc/X11/XF86Config-4", "/etc/X11/XF86Config";
205     } else {
206     my @cards = Xconfig::card::probe();
207     my $driver = $cards[0]{Driver};
208     my $old_driver = cat_('/etc/X11/xorg.conf') =~ /Driver "($card->{xorg_driver_regexp})"/ && $1;
209     if ($old_driver) {
210     my $reason = N("The proprietary kernel driver was not found for '%s' X.org driver",
211     $old_driver);
212     switch_x_driver($card->{xorg_driver_regexp}, $driver, $reason);
213     schedule_warn_about_switch($reason);
214     }
215     }
216     }
217    
218     my $is_globetrotter = -f '/usr/sbin/mdkmove';
219    
220     my (%config, $wait);
221     my $in;
222     my $splash = -f '/proc/splash';
223     my $splash_was_silent = cat_('/proc/splash') =~ /, silent : on/;
224    
225     # For each hw, class, detect device, compare and offer to reconfigure if needed
226     foreach my $hw_class (@harddrake::data::tree) {
227     my ($Ident, $item, $configurator, $detector, $do_it) = @$hw_class{qw(class string configurator detector checked_on_boot)};
228     next if member($cfg{"DETECT_$Ident"}, qw(NO no));
229    
230     $configurator ||= $hw_class->{configurator};
231    
232     next unless $do_it ^ $invert_do_it;
233     # No detector ? (should never happen but who know ?)
234     ref($detector) eq 'CODE' or next;
235    
236     my %ID = map {
237     my $i = $_;
238     my $id = defined $i->{device} ? $i->{device} : join(':', map { $i->{$_} } qw(vendor id subvendor subid));
239     $id => $i;
240     } eval { $detector->({}) };
241     $config{$Ident} = \%ID;
242     next if !$is_globetrotter && !$force && $first_run; # do not fsck on first run but if --force
243    
244     my $oldconfig = $force ? {} : $previous_config->{$Ident};
245    
246     my $msg;
247     my @was_removed = difference2([ keys %$oldconfig ], [ keys %ID ]);
248     if (@was_removed) {
249     $msg .= N("Some devices in the \"%s\" hardware class were removed:\n", $item) .
250     join('', map { N("- %s was removed\n", harddrake::data::custom_id($oldconfig->{$_}, $item)) } @was_removed) . "\n";
251     }
252     my @added = difference2([ keys %ID ], [ keys %$oldconfig ]);
253     $msg .= N("Some devices were added: %s\n", $item) if @added;
254     $msg .= N("- %s was added\n", harddrake::data::custom_id($ID{$_}, $item)) foreach @added;
255     log::explanations("removed $Ident: " . harddrake::data::custom_id($oldconfig->{$_}, $item)) foreach @was_removed;
256     log::explanations("added $Ident: " . harddrake::data::custom_id($ID{$_}, $item)) foreach @added;
257    
258     if ($Ident eq 'FIREWIRE_CONTROLLER' && any { $_->{driver} eq 'ohci1394' } @ID{@added}) {
259     modules::load_and_configure($modules_conf, 'ohci1394');
260     $modules_conf->write;
261     }
262    
263     @added || @was_removed or $cfg{"DETECT_$Ident"} ne 'force' and next;
264    
265     next if $Ident eq 'MOUSE' && $kernel_major ne $previous_kernel_config{KERNEL} && $cfg{"DETECT_$Ident"} ne 'force';
266    
267     my @configurator_pool = $configurator;
268    
269     if ($Ident eq "AUDIO") {
270     # automatic sound slots configuration
271     rm_rf("/etc/asound.state") if -e "/etc/asound.state";
272     harddrake::sound::configure_sound_slots($modules_conf);
273     next;
274     } elsif ($Ident eq "ETHERNET") {
275     $modules_conf->remove_alias_regexp('^(wlan|eth)[0-9]*$');
276     modules::load_category($modules_conf, 'network/main|gigabit|usb|wireless|firewire|pcmcia');
277     require network::connection::ethernet;
278     network::connection::ethernet::configure_eth_aliases($modules_conf);
279     require network::rfswitch;
280     network::rfswitch::configure();
281     require network::shorewall;
282     network::shorewall::update_interfaces_list();
283     $modules_conf->write;
284     next;
285     } elsif (member($Ident, qw(ATA_STORAGE CARD_READER RAID_STORAGE SATA_STORAGE SCSI_CONTROLLER))) {
286     # set scsi_hostadapter in modprobe.conf:
287     modules::load_category($modules_conf, 'disk/' . {
288     ATA_STORAGE => 'ide',
289     SATA_STORAGE => 'sata',
290     SCSI_CONTROLLER => 'scsi',
291     RAID_STORAGE => 'hardware_raid',
292     CARD_READER => 'card_reader'
293     }->{$Ident});
294     $modules_conf->write;
295     next;
296     } elsif (member($Ident, qw(AGP DVB TV))) {
297     my @old_drivers = uniq(map { $_->{driver} } values %$oldconfig);
298     my @new_drivers = uniq(map { $_->{driver} } values %ID);
299     # load DVB & TV drivers (eg: for One), not for AGP (done by X):
300     modules::load_category($modules_conf, 'multimedia/' . lc($Ident)) if member($Ident, qw(DVB TV));
301     $modules_conf->remove_module(difference2(\@old_drivers, \@new_drivers));
302     # add agpgart and the like modules to modprobe.preload if needed:
303     $modules_conf->write;
304     foreach (difference2(\@new_drivers, \@old_drivers)) {
305     eval { modules::load($_) };
306     warn "warning: $@" if $@;
307     }
308     next;
309     } elsif ($Ident eq "BLUETOOTH") {
310     harddrake::autoconf::bluetooth(scalar keys %ID);
311     } elsif ($Ident eq "PCMCIA_CONTROLLER") {
312     harddrake::autoconf::pcmcia(keys %ID ? first(values(%ID))->{driver} : '');
313     } elsif ($Ident eq "USB_CONTROLLER") {
314     # nearly useless (only mkinitrd uses it):
315     modules::load_category($modules_conf, 'bus/usb');
316     $modules_conf->write;
317     } elsif ($Ident eq "VIDEO") {
318     # explicitely NOT read the existing config (eg: new profile with globetrotter)
319     harddrake::autoconf::xconf($modules_conf, {}, member($cfg{SETUP_FB}, qw(NO no)), $cfg{RESOLUTION_WANTED});
320     next;
321     } elsif ($Ident eq "MOUSE") {
322     harddrake::autoconf::mouse_conf($modules_conf);
323     next;
324     } elsif ($Ident eq "CPU") {
325     harddrake::autoconf::cpufreq();
326     } elsif ($Ident eq "FLOPPY") {
327     harddrake::autoconf::floppy();
328     }
329    
330     next if $is_globetrotter && !$hw_class->{automatic};
331     next unless $configurator_pool[0];
332     if (ref($configurator) ne 'CODE' && !-x first(split /\s+/, $configurator_pool[0])) {
333     log::explanations(qw(skip $Ident configuration since "$configurator" is not executable));
334     next;
335     }
336     my ($pid, $no, $res);
337     $hw_class->{automatic} ||= ref($configurator) eq 'CODE';
338    
339     if (!$hw_class->{automatic}) {
340     $SIG{ALRM} = sub { $no = 1; kill 15, $pid };
341     unless ($pid = fork()) {
342     $splash and eval { output('/proc/splash', 'verbose') } and $splash = 0;
343     exec("/usr/share/harddrake/confirm", $Ident, $timeout, $msg);
344     }
345     alarm($timeout);
346     wait();
347     $res = $?;
348     alarm(0);
349     } else {
350     $res = 1;
351     }
352     if (ref($configurator) eq 'CODE') {
353     eval { $configurator->() };
354     log::explanations(qw(cannot run "$configurator": $@)) if $@;
355     } elsif (!$no && $res) {
356     foreach my $program (@configurator_pool) {
357     if (fork()) {
358     wait();
359     } else {
360     log::explanations(qq(run "$program"));
361     exec("$program 2>/dev/null") or do {
362     log::explanations(qq(cannot run "$program"));
363     require POSIX;
364     POSIX::_exit();
365     };
366     }
367     }
368     }
369     if (!$hw_class->{automatic}) {
370     require interactive;
371     undef $wait;
372     $in ||= interactive->vnew;
373     $wait = $in->wait_message(N("Please wait"), N("Hardware probing in progress"));
374     }
375    
376     }
377    
378     # output new hw config
379     log::explanations("created file $last_boot_config");
380     Storable::store(\%config, $last_boot_config);
381    
382     # restore bootsplash mode
383     $splash_was_silent and eval { output('/proc/splash', 'silent') };
384    
385    
386     $in->exit(0) if $in;

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.30