/[soft]/drakx-kbd-mouse-x11/trunk/tools/display_driver_helper
ViewVC logotype

Annotation of /drakx-kbd-mouse-x11/trunk/tools/display_driver_helper

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2245 - (hide annotations) (download)
Fri Dec 2 21:32:31 2011 UTC (12 years, 4 months ago) by anssi
File size: 13054 byte(s)
display_driver_helper: use modprobe --resolve-alias

Adapt display_driver_helper to use the new modprobe --resolve-alias
instead of manually parsing --dry-run --verbose output.
1 anssi 912 #!/bin/sh
2     #
3     # Display driver helper
4     #
5     # Copyright (c) 2010, 2011 Anssi Hannula <anssi.hannula@iki.fi>
6     #
7     # - Load drivers for specified modaliases, skipping disabled display drivers
8     # that would cause conflicts (KMS vs. vesa, KMS vs. proprietary).
9     # - Get information about enabled driver modules
10     # - Check that the loaded modules are correct
11     #
12     # Licensed under terms of GPLv2 or later.
13     #
14     # When updating, check:
15     # - the variables below
16     # - check_driver function
17     # - check_dkms_status function
18     #
19    
20 anssi 958 if [ -n "$DEBUG_DISPLAY_DRIVER_HELPER" ]; then
21     echo "$(date) $*" >> /dev/ddh_debug
22     exec 2>>/dev/ddh_debug
23     set -x
24     fi
25 anssi 912
26     export LC_ALL=C
27    
28     KMS_DRIVERS="i915 radeon nouveau"
29     # module names at run-time (hence nvidia instead of nvidia*):
30     KNOWN_MODULES="i915|radeon|nouveau|fglrx|nvidia"
31    
32     XORG_i915="intel"
33     CONFLICTS_i915=""
34    
35     XORG_nouveau="nouveau"
36     CONFLICTS_nouveau="nv nvidia"
37    
38     XORG_radeon="ati radeon"
39     CONFLICTS_radeon="fglrx"
40    
41     # Note: no /usr
42     # See end of script for descriptions of global variables.
43     check_driver() {
44     local name="$1"
45     case "$name" in
46     i915)
47     # implicitely loaded by X.org
48     check_xorg $name 0 || return 1
49     IS_KMS=1
50     ;;
51     radeon)
52     # implicitely loaded by X.org
53     check_xorg $name 0 || return 1
54 anssi 997 # Do not load if the proprietary driver is temporarily disabled
55     # on a PowerXpress system.
56     # TODO: this check could be omitted if radeon was explicitely
57     # specified in xorg.conf - but that is only known by check_xorg.
58     check_gl /etc/fglrx/pxpress-free.ld.so.conf && return 1
59 anssi 912 IS_KMS=1
60 anssi 2244 # radeon needs to be loaded before X server
61 anssi 912 NEEDS_LOAD_NOW=1
62     ;;
63     nouveau)
64     # these KMS drivers require an explicit directive in xorg.conf
65     check_xorg $name 1 || return 1
66     IS_KMS=1
67     ;;
68     fglrx)
69     check_xorg fglrx 1 || return 1
70     check_dkms fglrx || return 1
71     ;;
72     nvidia)
73     # manually installed driver or a call from check_loaded()
74     UNSURE=1
75     check_xorg nvidia 1 || return 1
76     ;;
77     nvidiafb)
78     # this is only reached if nvidiafb is manually unblacklisted
79     return 2
80     ;;
81     nvidia*)
82     [ "$name" = "nvidia_current" ] && name=nvidia-current
83     # there are multiple co-installable driver versions, so check
84     # the active alternative as well
85     check_gl /etc/$name/ld.so.conf || return 1
86     check_xorg nvidia 1 || return 1
87     check_dkms $name || return 1
88     ;;
89     *)
90     # unknown, will be loaded only if no known drivers were found
91     return 2
92     ;;
93     esac
94     return 0
95     }
96    
97     # Return success if there is no new pending DKMS build (needed to disallow
98     # speedboot on very early boot).
99     # Previously failed build or a missing module is counted as no pending build.
100     # Note: no /usr
101     check_dkms_status() {
102     [ -e /etc/alternatives/gl_conf ] || return 0
103     # return fast for non-DKMS
104     check_gl /etc/ld.so.conf.d/GL/standard.conf && return 0
105    
106     local active="$(ls -l /etc/alternatives/gl_conf | awk '{ print $NF }')"
107    
108     local modname=
109    
110     case $active in
111     /etc/nvidia*/ld.so.conf)
112     modname="nvidia${active#*nvidia}"
113     modname="${modname%/*}"
114     ;;
115     /etc/ld.so.conf.d/GL/ati.conf)
116     modname="fglrx"
117     ;;
118     *)
119     # Unknown DKMS-looking driver,
120     # allow speedboot.
121     return 0
122     ;;
123     esac
124     check_dkms "$modname" 1
125     }
126    
127     # Check if all loaded kernel modules have correct xorg.conf
128     check_loaded() {
129     for module in $(grep -oE "^($KNOWN_MODULES) " /proc/modules); do
130 anssi 961 # try to unload the driver in case it is not in use before bailing
131     check_driver "$module" || rmmod "$module" &>/dev/null || return 1
132 anssi 912 done
133     return 0
134     }
135    
136     # Check that specified DKMS driver is not queued for build for the current
137     # kernel. Used to check if we 1) should disable speedboot for this boot
138     # (--check-dkms-status), and 2) if should should load the currently
139     # existing driver (--load). Doing otherwise might cause us to load a wrong old
140     # version of the driver that had been installed using e.g. binary DKMS
141     # packages.
142     # Note: no /usr
143     check_dkms() {
144     local driver="$1"
145     local force="$2"
146    
147     # If called from DKMS itself or we are not in rc.sysinit anymore,
148     # there are no pending builds.
149     if [ -z "$force" ]; then
150     [ "$DKMS_AUTOLOAD_MODULE" = "$driver" ] && return 0
151     [ -z "$STARTUP" ] && [ ! -f "/dev/.in_sysinit" ] && return 0
152     fi
153    
154     local found=
155     local uname_r="$(uname -r)"
156    
157     for dir in /var/lib/dkms/$driver/*; do
158     [ -e "$dir" ] || return 0 # no module, no build; or no /var
159     [ -L "$dir" ] && continue # not a module version
160     found=1 # module version found
161     [ -e "$dir/$uname_r" ] && return 0
162     [ -e "/var/lib/dkms-binary/$driver/$(basename "$dir")/$uname_r" ] && return 0
163    
164     if [ -e "$dir/build/make.log" ]; then
165     # Build has failed for some kernel, check if it is this one.
166     # If so, there is no point in returning 1.
167     grep -q "^DKMS make\.log.* $uname_r " && return 0
168     fi
169     done
170    
171     # if module versions were found but none were built for this kernel, return 1
172     [ -n "$found" ] && return 1 || return 0
173     }
174    
175     # Note: no /usr
176     check_gl() {
177     local alt_inode="$(stat -L -c%i $1 2>/dev/null)"
178     [ -n "$alt_inode" ] || return 1
179     [ -n "$GL_INODE" ] || GL_INODE="$(stat -L -c%i /etc/alternatives/gl_conf 2>/dev/null)"
180     [ "$alt_inode" = "$GL_INODE" ] || return 1
181     return 0
182     }
183    
184     # Note: no /usr
185     get_xorg_drivers() {
186     if [ -z "$XORG_DRIVERS" ]; then
187     XORG_DRIVERS="$(cat /etc/X11/xorg.conf /etc/X11/xorg.conf.d/*.conf 2>/dev/null |
188     awk -F'"' -vORS=' ' -vIGNORECASE=1 '
189     /^[[:space:]]+*section[[:space:]]+"device"/ { device=1 }
190     /endsection/ { device=0 }
191     /^[[:space:]]*driver[[:space:]]*".*"/ { if (device) drivers[$2]=$2 }
192     END { for (driver in drivers) print driver }
193     ')"
194     [ -n "$XORG_DRIVERS" ] || XORG_DRIVERS="-"
195     fi
196     }
197    
198     # Note: no /usr
199     # parameter 1: xorg driver
200     # parameter 2: 1 the check if the driver is explicitely enabled
201     # 0 means that check only for conflicts
202     check_xorg() {
203     local driver="$1"
204     local explicit_only="$2"
205    
206     eval local xorg_drivers=\"\$XORG_$driver\"
207 anssi 959 [ -n "$xorg_drivers" ] || xorg_drivers="$driver"
208 anssi 912 eval local conflicts=\"\$CONFLICTS_$driver\"
209    
210     get_xorg_drivers
211    
212     conflict_found=
213     for enabled_driver in $XORG_DRIVERS; do
214     for xorg_driver in $xorg_drivers; do
215     [ "$enabled_driver" = "$xorg_driver" ] && return 0
216     done
217    
218     # if the X.org driver can be loaded implicitely, check that
219     # there are no conflicting drivers that override the driver
220     if [ "$explicit_only" = "0" -a -z "$conflict_found" ]; then
221     for conflict in vesa $conflicts; do
222     if [ "$enabled_driver" = "$conflict" ]; then
223     conflict_found=1
224     continue 2
225     # continue loop to check for an explicit load
226     fi
227     done
228     fi
229     done
230    
231     # in case of a conflict, do not load the module
232     [ -n "$conflict_found" ] && return 1
233    
234     # no driver is selected - don't load if explicit_only is 1
235     [ "$explicit_only" = "1" ] && return 1
236    
237 anssi 1681 # implicit load allowed; only load if there is evidence that this is
238     # not a live cd or similar with automatic configuration occurring later
239     # in the boot process (which might configure a driver conflicting with
240     # the implicit driver, e.g. a proprietary one)
241     # TODO: Could this be replaced with a more robust check?
242     [ -e "/etc/X11/xorg.conf" ] || [ -e "/etc/sysconfig/harddrake2/kernels" ] ||
243     [ -e "/etc/sysconfig/harddrake2/xorg" ] || [ -e "/boot/grub/menu.lst" ]
244 anssi 912 }
245    
246     # Load the driver for the specified modalias, if configured.
247     # Note: no /usr
248     load_driver() {
249     local modulename
250     local load_default=1
251    
252 anssi 2245 for modulename in $(/sbin/modprobe -Rq "$1"); do
253 anssi 912 check_driver "$modulename"
254     case $? in
255     1) # a driver which needs handling by this script matches
256     # the modalias, but was not configured - do not run
257     # the generic modprobe if no other drivers are
258     # configured either
259     load_default=
260     continue
261     ;;
262     2) continue
263     ;;
264     esac
265    
266     if [ -n "$IS_KMS" ]; then
267     grep -q "^$modulename " /proc/modules && return 0
268     echo "$modulename" > /dev/.late_kms 2>/dev/null
269     # If NEEDS_LOAD_NOW is not set and plymouth is running,
270     # skip loading the driver to avoid quitting plymouth.
271     # The driver will be loaded later by X server itself.
272     [ -z "$NEEDS_LOAD_NOW" ] && /bin/plymouth --ping 2>/dev/null && return 0
273     /bin/plymouth quit 2>/dev/null
274     fi
275     /sbin/modprobe -b "$modulename" && return 0
276     done
277    
278     # no specially handled modules were loaded, so load all modules normally
279     # unless $load_default was set above
280     [ -z "$load_default" ] || /sbin/modprobe -b "$1"
281     }
282    
283     is_kms_allowed() {
284     for driver in $KMS_DRIVERS; do
285     # Check all drivers for conflicts only.
286     check_xorg $driver 0 || return 1
287     done
288     return 0
289     }
290    
291     get_initrd_kms_drivers() {
292     local initrd="$1"
293    
294     local kms_drivers="$(echo "$KMS_DRIVERS" | tr " " "|")"
295     zcat "$initrd" | cpio -t --quiet | sed -nr "s,.*/($kms_drivers)\.ko.*$,\1,p"
296     }
297    
298     # Check that the initrd doesn't contain disabled modules
299     check_initrd() {
300     local initrd="$1"
301     local initrd_drivers="$(get_initrd_kms_drivers "$initrd")"
302     for driver in $initrd_drivers; do
303     check_driver "$driver" || return 1
304     done
305     for driver2 in $(get_active_kms_drivers); do
306     for driver in $initrd_drivers; do
307     [ "$driver" = "$driver2" ] && continue 2
308     done
309     # An enabled module for present hardware was not in initrd
310     return 1
311     done
312     return 0
313     }
314    
315     get_active_kms_drivers() {
316     local kms_drivers=
317     for device in $(grep -l 0x03 /sys/bus/pci/devices/0000\:0*/class); do
318     [ -e "$device" ] || continue
319     device="$(dirname $device)"
320     [ -f "$device/modalias" ] || continue
321     modalias="$(cat "$device/modalias")"
322 anssi 2245 for modulename in $(/sbin/modprobe -Rq "$modalias"); do
323 anssi 912 IS_KMS=
324     check_driver "$modulename" || continue
325     [ -n "$IS_KMS" ] && echo $modulename
326     done
327     done
328     }
329    
330     usage() {
331     cat <<EOF
332     Usage: $0 action [arguments]
333    
334     Known actions:
335    
336     --load MODALIAS
337     Load drivers matching MODALIAS, checking that they are enabled and
338     configured.
339    
340     --load-dkms-autoload MODNAME MODALIAS
341     Same as --load, but assume MODNAME is built and correct so that
342     checking dkms status is unnecessary.
343    
344     --is-disabled MODNAME
345     Checks whether the driver corresponding to MODNAME is disabled (e.g.
346     a conflicting driver is configured, etc.). Unknown MODNAMEs are
347     considered not disabled.
348    
349     --is-enabled-kms MODNAME
350     Checks whether the driver corresponding to MODNAME is enabled and
351     MODNAME is a known KMS module. Note that drivers may be enabled even
352     if there is no such hardware. This just checks that there are
353     no conflicting drivers in use etc.
354    
355     --is-kms-allowed
356     Checks whether it is ok to load KMS drivers in initrd. This returns
357     a failure when a conflicting driver is set up (vesa or a proprietary
358     one).
359    
360     --get-all-kms-drivers
361     Get a list of the known KMS drivers.
362    
363     --get-active-kms-drivers
364     Get a list of the known KMS drivers which are enabled and the hardware
365     is present.
366    
367     --get-initrd-kms-drivers INITRD
368     Get a list of the known KMS drivers in initrd INITRD.
369    
370     --check-dkms-status
371     Checks if there are no pending DKMS builds for the currently enabled
372     drivers.
373    
374     --check-loaded
375     Checks that there are no disabled drivers loaded.
376    
377     --check-speedboot
378     Does --check-dkms-status and --check-loaded.
379    
380     --check-loaded-strict
381     As --check-loaded, and consider ambigious cases (e.g. nvidia where
382     we can't detect if the loaded driver has the correct version) as
383     failure.
384    
385     --check-initrd INITRD
386     Check that INITRD doesn't contain disabled KMS drivers.
387     EOF
388     }
389    
390     # clear global variables
391    
392     # cache for check_gl()
393     GL_INODE=
394    
395     # cache for check_xorg()
396     XORG_DRIVERS=
397    
398     # The driver is a KMS enabled driver. This will cause the script to quit
399     # plymouth when a driver is loaded by --load and NEEDS_LOAD_NOW below is set.
400     # This is done as plymouth is still attached to the default framebuffer (the
401     # issues caused by not doing this don't seem to be fatal, though, but the
402     # display may be lost completely until plymouth eventually stops).
403     # There is no option in plymouth to "reload" a driver, it expects any KMS
404     # driver to be loaded be before starting it.
405     IS_KMS=
406    
407     # This KMS driver needs to be loaded before X server starts, so load it now
408     # even if we have to shut down plymouth (see above).
409     NEEDS_LOAD_NOW=
410    
411     # dkms module that was built when calling from DKMS
412     DKMS_AUTOLOAD_MODULE=
413    
414     # Set by check_loaded() when it can't be sure that the correct driver is loaded
415     # (e.g. in case of the multiple proprietary nvidia drivers which all identify as
416     # "nvidia" in loaded modules list).
417     UNSURE=
418    
419     case "$1" in
420     --load)
421     load_driver "$2"
422     ;;
423     --load-dkms-autoload)
424     DKMS_AUTOLOAD_MODULE="$2"
425     load_driver "$3"
426     ;;
427     --is-disabled)
428     check_driver "$2"
429     [ $? -eq 1 ]
430     # unknown (2) are not considered disabled :)
431     ;;
432     --is-enabled-kms)
433     check_driver "$2" && [ -n "$IS_KMS" ]
434     ;;
435     --is-kms-allowed)
436     is_kms_allowed
437     ;;
438     --check-dkms-status)
439     check_dkms_status
440     ;;
441     --get-all-kms-drivers)
442     echo $KMS_DRIVERS
443     ;;
444     --get-active-kms-drivers)
445     get_active_kms_drivers
446     ;;
447     --get-initrd-kms-drivers)
448     get_initrd_kms_drivers "$2"
449     ;;
450     --check-initrd)
451     check_initrd "$2"
452     ;;
453     --check-loaded)
454     check_loaded
455     ;;
456     --check-loaded-strict)
457     check_loaded && [ -z "$UNSURE" ]
458     ;;
459     --check-speedboot)
460     check_dkms_status && check_loaded
461     ;;
462     *)
463     usage
464     ;;
465     esac

  ViewVC Help
Powered by ViewVC 1.1.30