VirtualBox

source: vbox/trunk/src/VBox/Additions/linux/installer/vboxadd.sh@ 74891

Last change on this file since 74891 was 74891, checked in by vboxsync, 6 years ago

Additions/linux/installer: fix rebuilding modules for new kernels.
bugref:4567: Linux kernel driver maintenance
Red Hat derived distributions have been known, when upgrading kernel
packages, to call kernel module rebuild scripts before installing the
headers needed for the rebuild. So our rebuild script now waits in the
background for a while if the headers are not there.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 18.4 KB
Line 
1#! /bin/sh
2# $Id: vboxadd.sh 74891 2018-10-17 17:37:49Z vboxsync $
3## @file
4# Linux Additions kernel module init script ($Revision: 74891 $)
5#
6
7#
8# Copyright (C) 2006-2017 Oracle Corporation
9#
10# This file is part of VirtualBox Open Source Edition (OSE), as
11# available from http://www.virtualbox.org. This file is free software;
12# you can redistribute it and/or modify it under the terms of the GNU
13# General Public License (GPL) as published by the Free Software
14# Foundation, in version 2 as it comes in the "COPYING" file of the
15# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17#
18
19# X-Start-Before is a Debian Addition which we use when converting to
20# a systemd unit. X-Service-Type is our own invention, also for systemd.
21
22# chkconfig: 345 10 90
23# description: VirtualBox Linux Additions kernel modules
24#
25### BEGIN INIT INFO
26# Provides: vboxadd
27# Required-Start:
28# Required-Stop:
29# Default-Start: 2 3 4 5
30# Default-Stop: 0 1 6
31# X-Start-Before: display-manager
32# X-Service-Type: oneshot
33# Description: VirtualBox Linux Additions kernel modules
34### END INIT INFO
35
36## @todo This file duplicates a lot of script with vboxdrv.sh. When making
37# changes please try to reduce differences between the two wherever possible.
38
39# Testing:
40# * Should fail if the configuration file is missing or missing INSTALL_DIR or
41# INSTALL_VER entries.
42# * vboxadd user and vboxsf groups should be created if they do not exist - test
43# by removing them before installing.
44# * Shared folders can be mounted and auto-mounts accessible to vboxsf group,
45# including on recent Fedoras with SELinux.
46# * Setting INSTALL_NO_MODULE_BUILDS inhibits modules and module automatic
47# rebuild script creation; otherwise modules, user, group, rebuild script,
48# udev rule and shared folder mount helper should be created/set up.
49# * Setting INSTALL_NO_MODULE_BUILDS inhibits module load and unload on start
50# and stop.
51# * Uninstalling the Additions and re-installing them does not trigger warnings.
52
53export LC_ALL=C
54PATH=$PATH:/bin:/sbin:/usr/sbin
55PACKAGE=VBoxGuestAdditions
56MODPROBE=/sbin/modprobe
57OLDMODULES="vboxguest vboxadd vboxsf vboxvfs vboxvideo"
58SERVICE="VirtualBox Guest Additions"
59QUICKSETUP=
60## systemd logs information about service status, otherwise do that ourselves.
61QUIET=
62test -z "${KERN_VER}" && KERN_VER=`uname -r`
63
64setup_log()
65{
66 test -n "${LOG}" && return 0
67 # Rotate log files
68 LOG="/var/log/vboxadd-setup.log"
69 mv "${LOG}.3" "${LOG}.4" 2>/dev/null
70 mv "${LOG}.2" "${LOG}.3" 2>/dev/null
71 mv "${LOG}.1" "${LOG}.2" 2>/dev/null
72 mv "${LOG}" "${LOG}.1" 2>/dev/null
73}
74
75if $MODPROBE -c 2>/dev/null | grep -q '^allow_unsupported_modules *0'; then
76 MODPROBE="$MODPROBE --allow-unsupported-modules"
77fi
78
79# Check architecture
80cpu=`uname -m`;
81case "$cpu" in
82 i[3456789]86|x86)
83 cpu="x86"
84 ldconfig_arch="(libc6)"
85 lib_candidates="/usr/lib/i386-linux-gnu /usr/lib /lib"
86 ;;
87 x86_64|amd64)
88 cpu="amd64"
89 ldconfig_arch="(libc6,x86-64)"
90 lib_candidates="/usr/lib/x86_64-linux-gnu /usr/lib64 /usr/lib /lib64 /lib"
91 ;;
92esac
93for i in $lib_candidates; do
94 if test -d "$i/VBoxGuestAdditions"; then
95 lib_path=$i
96 break
97 fi
98done
99
100# Preamble for Gentoo
101if [ "`which $0`" = "/sbin/rc" ]; then
102 shift
103fi
104
105begin()
106{
107 test -z "${QUIET}" && echo "${SERVICE}: ${1}"
108}
109
110info()
111{
112 if test -z "${QUIET}"; then
113 echo "${SERVICE}: $1"
114 else
115 echo "$1"
116 fi
117}
118
119fail()
120{
121 log "${1}"
122 echo "$1" >&2
123 echo "The log file $LOG may contain further information." >&2
124 exit 1
125}
126
127log()
128{
129 setup_log
130 echo "${1}" >> "${LOG}"
131}
132
133module_build_log()
134{
135 log "Error building the module. Build output follows."
136 echo ""
137 echo "${1}" >> "${LOG}"
138}
139
140dev=/dev/vboxguest
141userdev=/dev/vboxuser
142config=/var/lib/VBoxGuestAdditions/config
143owner=vboxadd
144group=1
145
146if test -r $config; then
147 . $config
148else
149 fail "Configuration file $config not found"
150fi
151test -n "$INSTALL_DIR" -a -n "$INSTALL_VER" ||
152 fail "Configuration file $config not complete"
153
154running_vboxguest()
155{
156 lsmod | grep -q "vboxguest[^_-]"
157}
158
159running_vboxadd()
160{
161 lsmod | grep -q "vboxadd[^_-]"
162}
163
164running_vboxsf()
165{
166 lsmod | grep -q "vboxsf[^_-]"
167}
168
169running_vboxvideo()
170{
171 lsmod | grep -q "vboxvideo[^_-]"
172}
173
174do_vboxguest_non_udev()
175{
176 if [ ! -c $dev ]; then
177 maj=`sed -n 's;\([0-9]\+\) vboxguest;\1;p' /proc/devices`
178 if [ ! -z "$maj" ]; then
179 min=0
180 else
181 min=`sed -n 's;\([0-9]\+\) vboxguest;\1;p' /proc/misc`
182 if [ ! -z "$min" ]; then
183 maj=10
184 fi
185 fi
186 test -z "$maj" && {
187 rmmod vboxguest 2>/dev/null
188 fail "Cannot locate the VirtualBox device"
189 }
190
191 mknod -m 0664 $dev c $maj $min || {
192 rmmod vboxguest 2>/dev/null
193 fail "Cannot create device $dev with major $maj and minor $min"
194 }
195 fi
196 chown $owner:$group $dev 2>/dev/null || {
197 rm -f $dev 2>/dev/null
198 rm -f $userdev 2>/dev/null
199 rmmod vboxguest 2>/dev/null
200 fail "Cannot change owner $owner:$group for device $dev"
201 }
202
203 if [ ! -c $userdev ]; then
204 maj=10
205 min=`sed -n 's;\([0-9]\+\) vboxuser;\1;p' /proc/misc`
206 if [ ! -z "$min" ]; then
207 mknod -m 0666 $userdev c $maj $min || {
208 rm -f $dev 2>/dev/null
209 rmmod vboxguest 2>/dev/null
210 fail "Cannot create device $userdev with major $maj and minor $min"
211 }
212 chown $owner:$group $userdev 2>/dev/null || {
213 rm -f $dev 2>/dev/null
214 rm -f $userdev 2>/dev/null
215 rmmod vboxguest 2>/dev/null
216 fail "Cannot change owner $owner:$group for device $userdev"
217 }
218 fi
219 fi
220}
221
222start()
223{
224 begin "Starting."
225 # If we got this far assume that the slow set-up has been done.
226 QUICKSETUP=start
227 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
228 uname -r | grep -q -E '^2\.6|^3|^4' 2>/dev/null &&
229 ps -A -o comm | grep -q '/*udevd$' 2>/dev/null ||
230 no_udev=1
231 running_vboxguest || {
232 rm -f $dev || {
233 fail "Cannot remove $dev"
234 }
235
236 rm -f $userdev || {
237 fail "Cannot remove $userdev"
238 }
239
240 $MODPROBE vboxguest >/dev/null 2>&1 || {
241 setup
242 $MODPROBE vboxguest >/dev/null 2>&1 ||
243 fail "modprobe vboxguest failed"
244 }
245 case "$no_udev" in 1)
246 sleep .5;;
247 esac
248 }
249 case "$no_udev" in 1)
250 do_vboxguest_non_udev;;
251 esac
252
253 running_vboxsf || {
254 $MODPROBE vboxsf > /dev/null 2>&1 || {
255 if dmesg | grep "VbglR0SfConnect failed" > /dev/null 2>&1; then
256 info "Unable to start shared folders support. Make sure that your VirtualBox build supports this feature."
257 else
258 info "modprobe vboxsf failed"
259 fi
260 }
261 }
262 fi # INSTALL_NO_MODULE_BUILDS
263
264 # Put the X.Org driver in place. This is harmless if it is not needed.
265 myerr=`"${INSTALL_DIR}/init/vboxadd-x11" setup 2>&1`
266 test -z "${myerr}" || log "${myerr}"
267 # Install the guest OpenGL drivers. For now we don't support
268 # multi-architecture installations
269 rm -f /etc/ld.so.conf.d/00vboxvideo.conf
270 rm -Rf /var/lib/VBoxGuestAdditions/lib
271 if /usr/bin/VBoxClient --check3d 2>/dev/null; then
272 mkdir -p /var/lib/VBoxGuestAdditions/lib
273 ln -sf "${INSTALL_DIR}/lib/VBoxOGL.so" /var/lib/VBoxGuestAdditions/lib/libGL.so.1
274 # SELinux for the OpenGL libraries, so that gdm can load them during the
275 # acceleration support check. This prevents an "Oh no, something has gone
276 # wrong!" error when starting EL7 guests.
277 if test -e /etc/selinux/config; then
278 if command -v semanage > /dev/null; then
279 semanage fcontext -a -t lib_t "/var/lib/VBoxGuestAdditions/lib/libGL.so.1"
280 fi
281 chcon -h -t lib_t "/var/lib/VBoxGuestAdditions/lib/libGL.so.1"
282 fi
283 echo "/var/lib/VBoxGuestAdditions/lib" > /etc/ld.so.conf.d/00vboxvideo.conf
284 fi
285 ldconfig
286
287 # Mount all shared folders from /etc/fstab. Normally this is done by some
288 # other startup script but this requires the vboxdrv kernel module loaded.
289 # This isn't necessary anymore as the vboxsf module is autoloaded.
290 # mount -a -t vboxsf
291
292 return 0
293}
294
295stop()
296{
297 begin "Stopping."
298 if test -r /etc/ld.so.conf.d/00vboxvideo.conf; then
299 rm /etc/ld.so.conf.d/00vboxvideo.conf
300 ldconfig
301 fi
302 if ! umount -a -t vboxsf 2>/dev/null; then
303 fail "Cannot unmount vboxsf folders"
304 fi
305 test -n "${INSTALL_NO_MODULE_BUILDS}" ||
306 info "You may need to restart your guest system to finish removing the guest drivers."
307 return 0
308}
309
310restart()
311{
312 stop && start
313 return 0
314}
315
316## Update the initramfs. Debian and Ubuntu put the graphics driver in, and
317# need the touch(1) command below. Everyone else that I checked just need
318# the right module alias file from depmod(1) and only use the initramfs to
319# load the root filesystem, not the boot splash. update-initramfs works
320# for the first two and dracut for every one else I checked. We are only
321# interested in distributions recent enough to use the KMS vboxvideo driver.
322update_initramfs()
323{
324 ## kernel version to update for.
325 version="${1}"
326 depmod "${version}"
327 rm -f "/lib/modules/${version}/initrd/vboxvideo"
328 test -d "/lib/modules/${version}/initrd" &&
329 test -f "/lib/modules/${version}/misc/vboxvideo.ko" &&
330 touch "/lib/modules/${version}/initrd/vboxvideo"
331 if type dracut >/dev/null 2>&1; then
332 dracut -f --kver "${version}"
333 elif type update-initramfs >/dev/null 2>&1; then
334 update-initramfs -u -k "${version}"
335 fi
336}
337
338# Remove any existing VirtualBox guest kernel modules from the disk, but not
339# from the kernel as they may still be in use
340cleanup_modules()
341{
342 test "x${1}" = x--skip && skip_ver="${2}"
343 # Needed for Ubuntu and Debian, see update_initramfs
344 rm -f /lib/modules/*/initrd/vboxvideo
345 for i in /lib/modules/*/misc; do
346 kern_ver="${i%/misc}"
347 kern_ver="${kern_ver#/lib/modules/}"
348 unset do_update
349 for j in ${OLDMODULES}; do
350 test -f "${i}/${j}.ko" && do_update=1 && rm -f "${i}/${j}.ko"
351 done
352 test -n "${do_update}" && test "x${kern_ver}" != "x${skip_ver}" &&
353 update_initramfs "${kern_ver}"
354 # Remove empty /lib/modules folders which may have been kept around
355 rmdir -p "${i}" 2>/dev/null || true
356 unset keep
357 for j in /lib/modules/"${kern_ver}"/*; do
358 name="${j##*/}"
359 test -d "${name}" || test "${name%%.*}" != modules && keep=1
360 done
361 if test -z "${keep}"; then
362 rm -rf /lib/modules/"${kern_ver}"
363 rm -f /boot/initrd.img-"${kern_ver}"
364 fi
365 done
366 for i in ${OLDMODULES}; do
367 # We no longer support DKMS, remove any leftovers.
368 rm -rf "/var/lib/dkms/${i}"*
369 done
370 rm -f /etc/depmod.d/vboxvideo-upstream.conf
371}
372
373# Build and install the VirtualBox guest kernel modules
374setup_modules()
375{
376 # don't stop the old modules here -- they might be in use
377 test -z "${QUICKSETUP}" && cleanup_modules --skip "${KERN_VER}"
378 # This does not work for 2.4 series kernels. How sad.
379 test -n "${QUICKSETUP}" && test -f "${MODULE_DIR}/vboxguest.ko" && return 0
380 info "Building the VirtualBox Guest Additions kernel modules. This may take a while."
381
382 # If the kernel headers are not there, wait at bit in case they get
383 # installed. Package managers have been known to trigger module rebuilds
384 # before actually installing the headers.
385 for count in 1 2 3 4 5; do
386 test "x${QUICKSETUP}" = xyes || break
387 test -d "/lib/modules/${KERN_VER}/build" && break
388 printf "Kernel modules not yet installed, waiting five minutes (%s of 5)" "${count}"
389 sleep 300
390 done
391
392 log "Building the main Guest Additions module."
393 if ! myerr=`$BUILDINTMP \
394 --save-module-symvers /tmp/vboxguest-Module.symvers \
395 --module-source $MODULE_SRC/vboxguest \
396 --no-print-directory install 2>&1`; then
397 # If check_module_dependencies.sh fails it prints a message itself.
398 module_build_log "$myerr"
399 "${INSTALL_DIR}"/other/check_module_dependencies.sh 2>&1 &&
400 info "Look at $LOG to find out what went wrong"
401 update_initramfs "${KERN_VER}"
402 return 0
403 fi
404 log "Building the shared folder support module."
405 if ! myerr=`$BUILDINTMP \
406 --use-module-symvers /tmp/vboxguest-Module.symvers \
407 --module-source $MODULE_SRC/vboxsf \
408 --no-print-directory install 2>&1`; then
409 module_build_log "$myerr"
410 info "Look at $LOG to find out what went wrong"
411 update_initramfs "${KERN_VER}"
412 return 0
413 fi
414 log "Building the graphics driver module."
415 if ! myerr=`$BUILDINTMP \
416 --use-module-symvers /tmp/vboxguest-Module.symvers \
417 --module-source $MODULE_SRC/vboxvideo \
418 --no-print-directory install 2>&1`; then
419 module_build_log "$myerr"
420 info "Look at $LOG to find out what went wrong"
421 fi
422 [ -d /etc/depmod.d ] || mkdir /etc/depmod.d
423 echo "override vboxguest * misc" > /etc/depmod.d/vboxvideo-upstream.conf
424 echo "override vboxsf * misc" >> /etc/depmod.d/vboxvideo-upstream.conf
425 echo "override vboxvideo * misc" >> /etc/depmod.d/vboxvideo-upstream.conf
426 update_initramfs "${KERN_VER}"
427 depmod
428 return 0
429}
430
431create_vbox_user()
432{
433 # This is the LSB version of useradd and should work on recent
434 # distributions
435 useradd -d /var/run/vboxadd -g 1 -r -s /bin/false vboxadd >/dev/null 2>&1 || true
436 # And for the others, we choose a UID ourselves
437 useradd -d /var/run/vboxadd -g 1 -u 501 -o -s /bin/false vboxadd >/dev/null 2>&1 || true
438
439}
440
441create_udev_rule()
442{
443 # Create udev description file
444 if [ -d /etc/udev/rules.d ]; then
445 udev_call=""
446 udev_app=`which udevadm 2> /dev/null`
447 if [ $? -eq 0 ]; then
448 udev_call="${udev_app} version 2> /dev/null"
449 else
450 udev_app=`which udevinfo 2> /dev/null`
451 if [ $? -eq 0 ]; then
452 udev_call="${udev_app} -V 2> /dev/null"
453 fi
454 fi
455 udev_fix="="
456 if [ "${udev_call}" != "" ]; then
457 udev_out=`${udev_call}`
458 udev_ver=`expr "$udev_out" : '[^0-9]*\([0-9]*\)'`
459 if [ "$udev_ver" = "" -o "$udev_ver" -lt 55 ]; then
460 udev_fix=""
461 fi
462 fi
463 ## @todo 60-vboxadd.rules -> 60-vboxguest.rules ?
464 echo "KERNEL=${udev_fix}\"vboxguest\", NAME=\"vboxguest\", OWNER=\"vboxadd\", MODE=\"0660\"" > /etc/udev/rules.d/60-vboxadd.rules
465 echo "KERNEL=${udev_fix}\"vboxuser\", NAME=\"vboxuser\", OWNER=\"vboxadd\", MODE=\"0666\"" >> /etc/udev/rules.d/60-vboxadd.rules
466 fi
467}
468
469create_module_rebuild_script()
470{
471 # And a post-installation script for rebuilding modules when a new kernel
472 # is installed.
473 mkdir -p /etc/kernel/postinst.d /etc/kernel/prerm.d
474 cat << EOF > /etc/kernel/postinst.d/vboxadd
475#!/bin/sh
476# Run in the background so that we can wait in case the package installer has
477# not yet installed the kernel headers we need.
478KERN_VER="\${1}" /sbin/rcvboxadd quicksetup &
479exit 0
480EOF
481 cat << EOF > /etc/kernel/prerm.d/vboxadd
482#!/bin/sh
483for i in ${OLDMODULES}; do rm -f /lib/modules/"\${1}"/misc/"\${i}".ko; done
484rmdir -p /lib/modules/"\$1"/misc 2>/dev/null
485exit 0
486EOF
487 chmod 0755 /etc/kernel/postinst.d/vboxadd /etc/kernel/prerm.d/vboxadd
488}
489
490shared_folder_setup()
491{
492 # Add a group "vboxsf" for Shared Folders access
493 # All users which want to access the auto-mounted Shared Folders have to
494 # be added to this group.
495 groupadd -r -f vboxsf >/dev/null 2>&1
496
497 # Put the mount.vboxsf mount helper in the right place.
498 ## @todo It would be nicer if the kernel module just parsed parameters
499 # itself instead of needing a separate binary to do that.
500 ln -sf "${INSTALL_DIR}/other/mount.vboxsf" /sbin
501 # SELinux security context for the mount helper.
502 if test -e /etc/selinux/config; then
503 # This is correct. semanage maps this to the real path, and it aborts
504 # with an error, telling you what you should have typed, if you specify
505 # the real path. The "chcon" is there as a back-up for old guests.
506 command -v semanage > /dev/null &&
507 semanage fcontext -a -t mount_exec_t "${INSTALL_DIR}/other/mount.vboxsf"
508 chcon -t mount_exec_t "${INSTALL_DIR}/other/mount.vboxsf"
509 fi
510}
511
512# setup_script
513setup()
514{
515 export BUILD_TYPE
516 export USERNAME
517
518 MODULE_SRC="$INSTALL_DIR/src/vboxguest-$INSTALL_VER"
519 BUILDINTMP="$MODULE_SRC/build_in_tmp"
520 test -e /etc/selinux/config &&
521 chcon -t bin_t "$BUILDINTMP"
522
523 test -z "${INSTALL_NO_MODULE_BUILDS}" && setup_modules
524 create_vbox_user
525 create_udev_rule
526 test -z "${INSTALL_NO_MODULE_BUILDS}" && create_module_rebuild_script
527 test -n "${QUICKSETUP}" && return 0
528 shared_folder_setup
529 if running_vboxguest || running_vboxadd; then
530 info "Running kernel modules will not be replaced until the system is restarted"
531 fi
532 return 0
533}
534
535# cleanup_script
536cleanup()
537{
538 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
539 # Delete old versions of VBox modules.
540 cleanup_modules
541 depmod
542
543 # Remove old module sources
544 for i in $OLDMODULES; do
545 rm -rf /usr/src/$i-*
546 done
547 fi
548
549 # Clean-up X11-related bits
550 "${INSTALL_DIR}/init/vboxadd-x11" cleanup
551
552 # Remove other files
553 rm /sbin/mount.vboxsf 2>/dev/null
554 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
555 rm -f /etc/kernel/postinst.d/vboxadd /etc/kernel/prerm.d/vboxadd
556 rmdir -p /etc/kernel/postinst.d /etc/kernel/prerm.d 2>/dev/null
557 fi
558 rm /etc/udev/rules.d/60-vboxadd.rules 2>/dev/null
559}
560
561dmnstatus()
562{
563 if running_vboxguest; then
564 echo "The VirtualBox Additions are currently running."
565 else
566 echo "The VirtualBox Additions are not currently running."
567 fi
568}
569
570case "$2" in quiet)
571 QUIET=yes;;
572esac
573case "$1" in
574start)
575 start
576 ;;
577stop)
578 stop
579 ;;
580restart)
581 restart
582 ;;
583setup)
584 setup
585 start
586 ;;
587quicksetup)
588 QUICKSETUP=yes
589 setup
590 ;;
591cleanup)
592 cleanup
593 ;;
594status)
595 dmnstatus
596 ;;
597*)
598 echo "Usage: $0 {start|stop|restart|status|setup|quicksetup|cleanup} [quiet]"
599 exit 1
600esac
601
602exit
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette