VirtualBox

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

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

Additions/linux/installer: still use the DKMS hooks as well to rebuild drivers.
bugref:3809: Linux installer maintenance
The last change removed the DKMS hooks for rebuilding kernel modules as they
were not reliable, and replaced them with something more reliable but not
quite as nice. But actually having both will not hurt anyone, so restore
the hooks again.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 17.7 KB
Line 
1#! /bin/sh
2# $Id: vboxadd.sh 75963 2018-12-05 09:53:40Z vboxsync $
3## @file
4# Linux Additions kernel module init script ($Revision: 75963 $)
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 "${TARGET_VER}" && TARGET_VER=`uname -r`
63# Marker to ignore a particular kernel version which was already installed.
64SKIPFILE_BASE=/var/lib/VBoxGuestAdditions/skip
65
66setup_log()
67{
68 test -z "${LOG}" || return 0
69 # Rotate log files
70 LOG="/var/log/vboxadd-setup.log"
71 mv "${LOG}.3" "${LOG}.4" 2>/dev/null
72 mv "${LOG}.2" "${LOG}.3" 2>/dev/null
73 mv "${LOG}.1" "${LOG}.2" 2>/dev/null
74 mv "${LOG}" "${LOG}.1" 2>/dev/null
75}
76
77if $MODPROBE -c 2>/dev/null | grep -q '^allow_unsupported_modules *0'; then
78 MODPROBE="$MODPROBE --allow-unsupported-modules"
79fi
80
81# Check architecture
82cpu=`uname -m`;
83case "$cpu" in
84 i[3456789]86|x86)
85 cpu="x86"
86 ldconfig_arch="(libc6)"
87 lib_candidates="/usr/lib/i386-linux-gnu /usr/lib /lib"
88 ;;
89 x86_64|amd64)
90 cpu="amd64"
91 ldconfig_arch="(libc6,x86-64)"
92 lib_candidates="/usr/lib/x86_64-linux-gnu /usr/lib64 /usr/lib /lib64 /lib"
93 ;;
94esac
95for i in $lib_candidates; do
96 if test -d "$i/VBoxGuestAdditions"; then
97 lib_path=$i
98 break
99 fi
100done
101
102# Preamble for Gentoo
103if [ "`which $0`" = "/sbin/rc" ]; then
104 shift
105fi
106
107begin()
108{
109 test -n "${QUIET}" || echo "${SERVICE}: ${1}"
110}
111
112info()
113{
114 if test -z "${QUIET}"; then
115 echo "${SERVICE}: $1"
116 else
117 echo "$1"
118 fi
119}
120
121fail()
122{
123 log "${1}"
124 echo "$1" >&2
125 echo "The log file $LOG may contain further information." >&2
126 exit 1
127}
128
129log()
130{
131 setup_log
132 echo "${1}" >> "${LOG}"
133}
134
135module_build_log()
136{
137 log "Error building the module. Build output follows."
138 echo ""
139 echo "${1}" >> "${LOG}"
140}
141
142dev=/dev/vboxguest
143userdev=/dev/vboxuser
144config=/var/lib/VBoxGuestAdditions/config
145owner=vboxadd
146group=1
147
148if test -r $config; then
149 . $config
150else
151 fail "Configuration file $config not found"
152fi
153test -n "$INSTALL_DIR" -a -n "$INSTALL_VER" ||
154 fail "Configuration file $config not complete"
155
156running_vboxguest()
157{
158 lsmod | grep -q "vboxguest[^_-]"
159}
160
161running_vboxadd()
162{
163 lsmod | grep -q "vboxadd[^_-]"
164}
165
166running_vboxsf()
167{
168 lsmod | grep -q "vboxsf[^_-]"
169}
170
171running_vboxvideo()
172{
173 lsmod | grep -q "vboxvideo[^_-]"
174}
175
176do_vboxguest_non_udev()
177{
178 if [ ! -c $dev ]; then
179 maj=`sed -n 's;\([0-9]\+\) vboxguest;\1;p' /proc/devices`
180 if [ ! -z "$maj" ]; then
181 min=0
182 else
183 min=`sed -n 's;\([0-9]\+\) vboxguest;\1;p' /proc/misc`
184 if [ ! -z "$min" ]; then
185 maj=10
186 fi
187 fi
188 test -n "$maj" || {
189 rmmod vboxguest 2>/dev/null
190 fail "Cannot locate the VirtualBox device"
191 }
192
193 mknod -m 0664 $dev c $maj $min || {
194 rmmod vboxguest 2>/dev/null
195 fail "Cannot create device $dev with major $maj and minor $min"
196 }
197 fi
198 chown $owner:$group $dev 2>/dev/null || {
199 rm -f $dev 2>/dev/null
200 rm -f $userdev 2>/dev/null
201 rmmod vboxguest 2>/dev/null
202 fail "Cannot change owner $owner:$group for device $dev"
203 }
204
205 if [ ! -c $userdev ]; then
206 maj=10
207 min=`sed -n 's;\([0-9]\+\) vboxuser;\1;p' /proc/misc`
208 if [ ! -z "$min" ]; then
209 mknod -m 0666 $userdev c $maj $min || {
210 rm -f $dev 2>/dev/null
211 rmmod vboxguest 2>/dev/null
212 fail "Cannot create device $userdev with major $maj and minor $min"
213 }
214 chown $owner:$group $userdev 2>/dev/null || {
215 rm -f $dev 2>/dev/null
216 rm -f $userdev 2>/dev/null
217 rmmod vboxguest 2>/dev/null
218 fail "Cannot change owner $owner:$group for device $userdev"
219 }
220 fi
221 fi
222}
223
224start()
225{
226 begin "Starting."
227 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
228 setup --quick
229 test -d /sys &&
230 ps -A -o comm | grep -q '/*udevd$' 2>/dev/null ||
231 no_udev=1
232 running_vboxguest || {
233 rm -f $dev || {
234 fail "Cannot remove $dev"
235 }
236 rm -f $userdev || {
237 fail "Cannot remove $userdev"
238 }
239 $MODPROBE vboxguest >/dev/null 2>&1 ||
240 fail "modprobe vboxguest failed"
241 case "$no_udev" in 1)
242 sleep .5;;
243 esac
244 }
245 case "$no_udev" in 1)
246 do_vboxguest_non_udev;;
247 esac
248
249 running_vboxsf || {
250 $MODPROBE vboxsf > /dev/null 2>&1 ||
251 info "modprobe vboxsf failed"
252 }
253 fi # INSTALL_NO_MODULE_BUILDS
254
255 # Put the X.Org driver in place. This is harmless if it is not needed.
256 # Also set up the OpenGL library.
257 myerr=`"${INSTALL_DIR}/init/vboxadd-x11" setup 2>&1`
258 test -z "${myerr}" || log "${myerr}"
259
260 # Mount all shared folders from /etc/fstab. Normally this is done by some
261 # other startup script but this requires the vboxdrv kernel module loaded.
262 # This isn't necessary anymore as the vboxsf module is autoloaded.
263 # mount -a -t vboxsf
264
265 return 0
266}
267
268stop()
269{
270 begin "Stopping."
271 test -n "${INSTALL_NO_MODULE_BUILDS}" || setup --quick
272 if test -r /etc/ld.so.conf.d/00vboxvideo.conf; then
273 rm /etc/ld.so.conf.d/00vboxvideo.conf
274 ldconfig
275 fi
276 if ! umount -a -t vboxsf 2>/dev/null; then
277 fail "Cannot unmount vboxsf folders"
278 fi
279 test -n "${INSTALL_NO_MODULE_BUILDS}" ||
280 info "You may need to restart your guest system to finish removing the guest drivers."
281 return 0
282}
283
284restart()
285{
286 stop && start
287 return 0
288}
289
290## Update the initramfs. Debian and Ubuntu put the graphics driver in, and
291# need the touch(1) command below. Everyone else that I checked just need
292# the right module alias file from depmod(1) and only use the initramfs to
293# load the root filesystem, not the boot splash. update-initramfs works
294# for the first two and dracut for every one else I checked. We are only
295# interested in distributions recent enough to use the KMS vboxvideo driver.
296update_initramfs()
297{
298 ## kernel version to update for.
299 version="${1}"
300 depmod "${version}"
301 rm -f "/lib/modules/${version}/initrd/vboxvideo"
302 test ! -d "/lib/modules/${version}/initrd" ||
303 test ! -f "/lib/modules/${version}/misc/vboxvideo.ko" ||
304 touch "/lib/modules/${version}/initrd/vboxvideo"
305
306 # Systems without systemd-inhibit probably don't need their initramfs
307 # rebuild here anyway.
308 type systemd-inhibit >/dev/null 2>&1 || return
309 if type dracut >/dev/null 2>&1; then
310 systemd-inhibit --why="Installing VirtualBox Guest Additions" \
311 dracut -f --kver "${version}"
312 elif type update-initramfs >/dev/null 2>&1; then
313 systemd-inhibit --why="Installing VirtualBox Guest Additions" \
314 update-initramfs -u -k "${version}"
315 fi
316}
317
318# Remove any existing VirtualBox guest kernel modules from the disk, but not
319# from the kernel as they may still be in use
320cleanup_modules()
321{
322 # Needed for Ubuntu and Debian, see update_initramfs
323 rm -f /lib/modules/*/initrd/vboxvideo
324 for i in /lib/modules/*/misc; do
325 KERN_VER="${i%/misc}"
326 KERN_VER="${KERN_VER#/lib/modules/}"
327 unset do_update
328 for j in ${OLDMODULES}; do
329 test -f "${i}/${j}.ko" && do_update=1 && rm -f "${i}/${j}.ko"
330 done
331 test -z "$do_update" || update_initramfs "$KERN_VER"
332 # Remove empty /lib/modules folders which may have been kept around
333 rmdir -p "${i}" 2>/dev/null || true
334 unset keep
335 for j in /lib/modules/"${KERN_VER}"/*; do
336 name="${j##*/}"
337 test -d "${name}" || test "${name%%.*}" != modules && keep=1
338 done
339 if test -z "${keep}"; then
340 rm -rf /lib/modules/"${KERN_VER}"
341 rm -f /boot/initrd.img-"${KERN_VER}"
342 fi
343 done
344 for i in ${OLDMODULES}; do
345 # We no longer support DKMS, remove any leftovers.
346 rm -rf "/var/lib/dkms/${i}"*
347 done
348 rm -f /etc/depmod.d/vboxvideo-upstream.conf
349 rm -f "$SKIPFILE_BASE"-*
350}
351
352# Build and install the VirtualBox guest kernel modules
353setup_modules()
354{
355 KERN_VER="$1"
356 test -n "$KERN_VER" || return 1
357 test ! -f /lib/modules/"$KERN_VER"/misc/vboxguest.ko || return 0
358 test ! -f /lib/modules/"$KERN_VER"/misc/vboxguest.o || return 0
359 test -d /lib/modules/"$KERN_VER"/build || return 0
360 test ! -f "$SKIPFILE_BASE"-"$KERN_VER" || return 0
361 export KERN_VER
362 info "Building the modules for kernel $KERN_VER."
363
364 log "Building the main Guest Additions module for kernel $KERN_VER."
365 if ! myerr=`$BUILDINTMP \
366 --save-module-symvers /tmp/vboxguest-Module.symvers \
367 --module-source $MODULE_SRC/vboxguest \
368 --no-print-directory install 2>&1`; then
369 # If check_module_dependencies.sh fails it prints a message itself.
370 module_build_log "$myerr"
371 "${INSTALL_DIR}"/other/check_module_dependencies.sh 2>&1 &&
372 info "Look at $LOG to find out what went wrong"
373 return 0
374 fi
375 log "Building the shared folder support module."
376 if ! myerr=`$BUILDINTMP \
377 --use-module-symvers /tmp/vboxguest-Module.symvers \
378 --module-source $MODULE_SRC/vboxsf \
379 --no-print-directory install 2>&1`; then
380 module_build_log "$myerr"
381 info "Look at $LOG to find out what went wrong"
382 return 0
383 fi
384 log "Building the graphics driver module."
385 if ! myerr=`$BUILDINTMP \
386 --use-module-symvers /tmp/vboxguest-Module.symvers \
387 --module-source $MODULE_SRC/vboxvideo \
388 --no-print-directory install 2>&1`; then
389 module_build_log "$myerr"
390 info "Look at $LOG to find out what went wrong"
391 fi
392 [ -d /etc/depmod.d ] || mkdir /etc/depmod.d
393 echo "override vboxguest * misc" > /etc/depmod.d/vboxvideo-upstream.conf
394 echo "override vboxsf * misc" >> /etc/depmod.d/vboxvideo-upstream.conf
395 echo "override vboxvideo * misc" >> /etc/depmod.d/vboxvideo-upstream.conf
396 update_initramfs "${KERN_VER}"
397 return 0
398}
399
400create_vbox_user()
401{
402 # This is the LSB version of useradd and should work on recent
403 # distributions
404 useradd -d /var/run/vboxadd -g 1 -r -s /bin/false vboxadd >/dev/null 2>&1 || true
405 # And for the others, we choose a UID ourselves
406 useradd -d /var/run/vboxadd -g 1 -u 501 -o -s /bin/false vboxadd >/dev/null 2>&1 || true
407
408}
409
410create_udev_rule()
411{
412 # Create udev description file
413 if [ -d /etc/udev/rules.d ]; then
414 udev_call=""
415 udev_app=`which udevadm 2> /dev/null`
416 if [ $? -eq 0 ]; then
417 udev_call="${udev_app} version 2> /dev/null"
418 else
419 udev_app=`which udevinfo 2> /dev/null`
420 if [ $? -eq 0 ]; then
421 udev_call="${udev_app} -V 2> /dev/null"
422 fi
423 fi
424 udev_fix="="
425 if [ "${udev_call}" != "" ]; then
426 udev_out=`${udev_call}`
427 udev_ver=`expr "$udev_out" : '[^0-9]*\([0-9]*\)'`
428 if [ "$udev_ver" = "" -o "$udev_ver" -lt 55 ]; then
429 udev_fix=""
430 fi
431 fi
432 ## @todo 60-vboxadd.rules -> 60-vboxguest.rules ?
433 echo "KERNEL=${udev_fix}\"vboxguest\", NAME=\"vboxguest\", OWNER=\"vboxadd\", MODE=\"0660\"" > /etc/udev/rules.d/60-vboxadd.rules
434 echo "KERNEL=${udev_fix}\"vboxuser\", NAME=\"vboxuser\", OWNER=\"vboxadd\", MODE=\"0666\"" >> /etc/udev/rules.d/60-vboxadd.rules
435 fi
436}
437
438create_module_rebuild_script()
439{
440 # And a post-installation script for rebuilding modules when a new kernel
441 # is installed.
442 mkdir -p /etc/kernel/postinst.d /etc/kernel/prerm.d
443 cat << EOF > /etc/kernel/postinst.d/vboxadd
444#!/bin/sh
445# This only works correctly on Debian derivatives - Red Hat calls it before
446# installing the right header files.
447/sbin/rcvboxadd quicksetup "\${1}"
448exit 0
449EOF
450 cat << EOF > /etc/kernel/prerm.d/vboxadd
451#!/bin/sh
452for i in ${OLDMODULES}; do rm -f /lib/modules/"\${1}"/misc/"\${i}".ko; done
453rmdir -p /lib/modules/"\$1"/misc 2>/dev/null
454exit 0
455EOF
456 chmod 0755 /etc/kernel/postinst.d/vboxadd /etc/kernel/prerm.d/vboxadd
457}
458
459shared_folder_setup()
460{
461 # Add a group "vboxsf" for Shared Folders access
462 # All users which want to access the auto-mounted Shared Folders have to
463 # be added to this group.
464 groupadd -r -f vboxsf >/dev/null 2>&1
465
466 # Put the mount.vboxsf mount helper in the right place.
467 ## @todo It would be nicer if the kernel module just parsed parameters
468 # itself instead of needing a separate binary to do that.
469 ln -sf "${INSTALL_DIR}/other/mount.vboxsf" /sbin
470 # SELinux security context for the mount helper.
471 if test -e /etc/selinux/config; then
472 # This is correct. semanage maps this to the real path, and it aborts
473 # with an error, telling you what you should have typed, if you specify
474 # the real path. The "chcon" is there as a back-up for old guests.
475 command -v semanage > /dev/null &&
476 semanage fcontext -a -t mount_exec_t "${INSTALL_DIR}/other/mount.vboxsf"
477 chcon -t mount_exec_t "${INSTALL_DIR}/other/mount.vboxsf"
478 fi
479}
480
481# setup_script
482setup()
483{
484 export BUILD_TYPE
485 export USERNAME
486
487 test x"$1" != x--quick || QUICKSETUP=true
488 test -n "$QUICKSETUP" || cleanup
489 MODULE_SRC="$INSTALL_DIR/src/vboxguest-$INSTALL_VER"
490 BUILDINTMP="$MODULE_SRC/build_in_tmp"
491 test ! -e /etc/selinux/config ||
492 chcon -t bin_t "$BUILDINTMP"
493
494 if test -z "$INSTALL_NO_MODULE_BUILDS"; then
495 if test -z "$QUICKSETUP"; then
496 info "Building the VirtualBox Guest Additions kernel modules. This may take a while."
497 info "To build modules for other installed kernels, run"
498 info " /sbin/rcvboxadd quicksetup <version>"
499 for setupi in /lib/modules/*; do
500 KERN_VER="${setupi##*/}"
501 # For a full setup, mark kernels we do not want to build.
502 touch "$SKIPFILE_BASE"-"$KERN_VER"
503 done
504 fi
505 # That is, we mark all but the requested kernel.
506 rm -f "$SKIPFILE_BASE"-"$TARGET_VER"
507 for setupi in /lib/modules/*; do
508 KERN_VER="${setupi##*/}"
509 setup_modules "$KERN_VER"
510 done
511 depmod
512 fi
513 create_vbox_user
514 create_udev_rule
515 test -n "${INSTALL_NO_MODULE_BUILDS}" || create_module_rebuild_script
516 test -z "$QUICKSETUP" || return 0
517 shared_folder_setup
518 if running_vboxguest || running_vboxadd; then
519 info "Running kernel modules will not be replaced until the system is restarted"
520 fi
521 return 0
522}
523
524# cleanup_script
525cleanup()
526{
527 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
528 # Delete old versions of VBox modules.
529 cleanup_modules
530 depmod
531
532 # Remove old module sources
533 for i in $OLDMODULES; do
534 rm -rf /usr/src/$i-*
535 done
536 fi
537
538 # Clean-up X11-related bits
539 "${INSTALL_DIR}/init/vboxadd-x11" cleanup
540
541 # Remove other files
542 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
543 rm -f /etc/kernel/postinst.d/vboxadd /etc/kernel/prerm.d/vboxadd
544 rmdir -p /etc/kernel/postinst.d /etc/kernel/prerm.d 2>/dev/null
545 fi
546 rm /sbin/mount.vboxsf 2>/dev/null
547 rm /etc/udev/rules.d/60-vboxadd.rules 2>/dev/null
548}
549
550dmnstatus()
551{
552 if running_vboxguest; then
553 echo "The VirtualBox Additions are currently running."
554 else
555 echo "The VirtualBox Additions are not currently running."
556 fi
557}
558
559case "$2" in quiet)
560 QUIET=yes;;
561esac
562case "$1" in
563start)
564 start
565 ;;
566stop)
567 stop
568 ;;
569restart)
570 restart
571 ;;
572setup)
573 setup
574 start
575 ;;
576quicksetup)
577 test -z "$2" || test ! -d /lib/modules/"$2"/build || TARGET_VER="$2"
578 setup --quick
579 ;;
580cleanup)
581 cleanup
582 ;;
583status)
584 dmnstatus
585 ;;
586*)
587 echo "Usage: $0 {start|stop|restart|status|setup|quicksetup|cleanup} [quiet]"
588 exit 1
589esac
590
591exit
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