VirtualBox

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

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

Linux Additions installer: revive initramfs support.
bugref:3809: Linux installer maintenance
Testing showed that with recent Linux guests our kernel modules are only used
(after all) after we rebuild the guest initramfs. We previously stopped doing
that because it caused installation and uninstallation of the Additions to
take an unreasonably long time. This second attempt at support reduces that
by putting more effort into only rebuilding initramfs images which we really
need to rebuild. It also adds support for openSUSE.
I also added some small fixes in the change to that rcvboxadd can run under
sh -e and cleaned up removal of old kernel modules and leftovers on Ubuntu
and Debian further.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 17.8 KB
Line 
1#! /bin/sh
2# $Id: vboxadd.sh 74579 2018-10-02 13:28:15Z vboxsync $
3## @file
4# Linux Additions kernel module init script ($Revision: 74579 $)
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=yes
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 log "Building the main Guest Additions module."
383 if ! myerr=`$BUILDINTMP \
384 --save-module-symvers /tmp/vboxguest-Module.symvers \
385 --module-source $MODULE_SRC/vboxguest \
386 --no-print-directory install 2>&1`; then
387 # If check_module_dependencies.sh fails it prints a message itself.
388 module_build_log "$myerr"
389 "${INSTALL_DIR}"/other/check_module_dependencies.sh 2>&1 &&
390 info "Look at $LOG to find out what went wrong"
391 update_initramfs "${KERN_VER}"
392 return 0
393 fi
394 log "Building the shared folder support module."
395 if ! myerr=`$BUILDINTMP \
396 --use-module-symvers /tmp/vboxguest-Module.symvers \
397 --module-source $MODULE_SRC/vboxsf \
398 --no-print-directory install 2>&1`; then
399 module_build_log "$myerr"
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 graphics driver module."
405 if ! myerr=`$BUILDINTMP \
406 --use-module-symvers /tmp/vboxguest-Module.symvers \
407 --module-source $MODULE_SRC/vboxvideo \
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 fi
412 [ -d /etc/depmod.d ] || mkdir /etc/depmod.d
413 echo "override vboxguest * misc" > /etc/depmod.d/vboxvideo-upstream.conf
414 echo "override vboxsf * misc" >> /etc/depmod.d/vboxvideo-upstream.conf
415 echo "override vboxvideo * misc" >> /etc/depmod.d/vboxvideo-upstream.conf
416 update_initramfs "${KERN_VER}"
417 depmod
418 return 0
419}
420
421create_vbox_user()
422{
423 # This is the LSB version of useradd and should work on recent
424 # distributions
425 useradd -d /var/run/vboxadd -g 1 -r -s /bin/false vboxadd >/dev/null 2>&1 || true
426 # And for the others, we choose a UID ourselves
427 useradd -d /var/run/vboxadd -g 1 -u 501 -o -s /bin/false vboxadd >/dev/null 2>&1 || true
428
429}
430
431create_udev_rule()
432{
433 # Create udev description file
434 if [ -d /etc/udev/rules.d ]; then
435 udev_call=""
436 udev_app=`which udevadm 2> /dev/null`
437 if [ $? -eq 0 ]; then
438 udev_call="${udev_app} version 2> /dev/null"
439 else
440 udev_app=`which udevinfo 2> /dev/null`
441 if [ $? -eq 0 ]; then
442 udev_call="${udev_app} -V 2> /dev/null"
443 fi
444 fi
445 udev_fix="="
446 if [ "${udev_call}" != "" ]; then
447 udev_out=`${udev_call}`
448 udev_ver=`expr "$udev_out" : '[^0-9]*\([0-9]*\)'`
449 if [ "$udev_ver" = "" -o "$udev_ver" -lt 55 ]; then
450 udev_fix=""
451 fi
452 fi
453 ## @todo 60-vboxadd.rules -> 60-vboxguest.rules ?
454 echo "KERNEL=${udev_fix}\"vboxguest\", NAME=\"vboxguest\", OWNER=\"vboxadd\", MODE=\"0660\"" > /etc/udev/rules.d/60-vboxadd.rules
455 echo "KERNEL=${udev_fix}\"vboxuser\", NAME=\"vboxuser\", OWNER=\"vboxadd\", MODE=\"0666\"" >> /etc/udev/rules.d/60-vboxadd.rules
456 fi
457}
458
459create_module_rebuild_script()
460{
461 # And a post-installation script for rebuilding modules when a new kernel
462 # is installed.
463 mkdir -p /etc/kernel/postinst.d /etc/kernel/prerm.d
464 cat << EOF > /etc/kernel/postinst.d/vboxadd
465#!/bin/sh
466test -d "/lib/modules/\${1}/build" || exit 0
467KERN_VER="\${1}" /sbin/rcvboxadd quicksetup
468exit 0
469EOF
470 cat << EOF > /etc/kernel/prerm.d/vboxadd
471#!/bin/sh
472for i in ${OLDMODULES}; do rm -f /lib/modules/"\${1}"/misc/"\${i}".ko; done
473rmdir -p /lib/modules/"\$1"/misc 2>/dev/null
474exit 0
475EOF
476 chmod 0755 /etc/kernel/postinst.d/vboxadd /etc/kernel/prerm.d/vboxadd
477}
478
479shared_folder_setup()
480{
481 # Add a group "vboxsf" for Shared Folders access
482 # All users which want to access the auto-mounted Shared Folders have to
483 # be added to this group.
484 groupadd -r -f vboxsf >/dev/null 2>&1
485
486 # Put the mount.vboxsf mount helper in the right place.
487 ## @todo It would be nicer if the kernel module just parsed parameters
488 # itself instead of needing a separate binary to do that.
489 ln -sf "${INSTALL_DIR}/other/mount.vboxsf" /sbin
490 # SELinux security context for the mount helper.
491 if test -e /etc/selinux/config; then
492 # This is correct. semanage maps this to the real path, and it aborts
493 # with an error, telling you what you should have typed, if you specify
494 # the real path. The "chcon" is there as a back-up for old guests.
495 command -v semanage > /dev/null &&
496 semanage fcontext -a -t mount_exec_t "${INSTALL_DIR}/other/mount.vboxsf"
497 chcon -t mount_exec_t "${INSTALL_DIR}/other/mount.vboxsf"
498 fi
499}
500
501# setup_script
502setup()
503{
504 export BUILD_TYPE
505 export USERNAME
506
507 MODULE_SRC="$INSTALL_DIR/src/vboxguest-$INSTALL_VER"
508 BUILDINTMP="$MODULE_SRC/build_in_tmp"
509 test -e /etc/selinux/config &&
510 chcon -t bin_t "$BUILDINTMP"
511
512 test -z "${INSTALL_NO_MODULE_BUILDS}" && setup_modules
513 create_vbox_user
514 create_udev_rule
515 test -z "${INSTALL_NO_MODULE_BUILDS}" && create_module_rebuild_script
516 test -n "${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 rm /sbin/mount.vboxsf 2>/dev/null
543 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
544 rm -f /etc/kernel/postinst.d/vboxadd /etc/kernel/prerm.d/vboxadd
545 rmdir -p /etc/kernel/postinst.d /etc/kernel/prerm.d 2>/dev/null
546 fi
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 QUICKSETUP=yes
578 setup
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