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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.30