VirtualBox

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

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

scm --update-copyright-year

  • 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 76553 2019-01-01 01:45:53Z vboxsync $
3## @file
4# Linux Additions kernel module init script ($Revision: 76553 $)
5#
6
7#
8# Copyright (C) 2006-2019 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