VirtualBox

source: vbox/trunk/src/VBox/Installer/linux/vboxdrv.sh@ 98417

Last change on this file since 98417 was 98103, checked in by vboxsync, 20 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 28.6 KB
Line 
1#! /bin/sh
2# Oracle VM VirtualBox
3# Linux kernel module init script
4
5#
6# Copyright (C) 2006-2023 Oracle and/or its affiliates.
7#
8# This file is part of VirtualBox base platform packages, as
9# available from https://www.virtualbox.org.
10#
11# This program is free software; you can redistribute it and/or
12# modify it under the terms of the GNU General Public License
13# as published by the Free Software Foundation, in version 3 of the
14# License.
15#
16# This program is distributed in the hope that it will be useful, but
17# WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19# General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, see <https://www.gnu.org/licenses>.
23#
24# SPDX-License-Identifier: GPL-3.0-only
25#
26
27# chkconfig: 345 20 80
28# description: VirtualBox Linux kernel module
29#
30### BEGIN INIT INFO
31# Provides: vboxdrv
32# Required-Start: $syslog
33# Required-Stop:
34# Default-Start: 2 3 4 5
35# Default-Stop: 0 1 6
36# Short-Description: VirtualBox Linux kernel module
37### END INIT INFO
38
39## @todo This file duplicates a lot of script with vboxadd.sh. When making
40# changes please try to reduce differences between the two wherever possible.
41
42## @todo Remove the stop_vms target so that this script is only relevant to
43# kernel modules. Nice but not urgent.
44
45PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
46DEVICE=/dev/vboxdrv
47MODPROBE=/sbin/modprobe
48SCRIPTNAME=vboxdrv.sh
49
50# The below is GNU-specific. See VBox.sh for the longer Solaris/OS X version.
51TARGET=`readlink -e -- "${0}"` || exit 1
52SCRIPT_DIR="${TARGET%/[!/]*}"
53
54if $MODPROBE -c | grep -q '^allow_unsupported_modules *0'; then
55 MODPROBE="$MODPROBE --allow-unsupported-modules"
56fi
57
58setup_log()
59{
60 test -n "${LOG}" && return 0
61 # Rotate log files
62 LOG="/var/log/vbox-setup.log"
63 mv "${LOG}.3" "${LOG}.4" 2>/dev/null
64 mv "${LOG}.2" "${LOG}.3" 2>/dev/null
65 mv "${LOG}.1" "${LOG}.2" 2>/dev/null
66 mv "${LOG}" "${LOG}.1" 2>/dev/null
67}
68
69[ -f /etc/vbox/vbox.cfg ] && . /etc/vbox/vbox.cfg
70export VBOX_KBUILD_TYPE
71export USERNAME
72export USER=$USERNAME
73
74if test -n "${INSTALL_DIR}" && test -x "${INSTALL_DIR}/VirtualBox"; then
75 MODULE_SRC="${INSTALL_DIR}/src/vboxhost"
76elif test -x /usr/lib/virtualbox/VirtualBox; then
77 INSTALL_DIR=/usr/lib/virtualbox
78 MODULE_SRC="/usr/share/virtualbox/src/vboxhost"
79elif test -x "${SCRIPT_DIR}/VirtualBox"; then
80 # Executing from the build directory
81 INSTALL_DIR="${SCRIPT_DIR}"
82 MODULE_SRC="${INSTALL_DIR}/src"
83else
84 # Silently exit if the package was uninstalled but not purged.
85 # Applies to Debian packages only (but shouldn't hurt elsewhere)
86 exit 0
87fi
88VIRTUALBOX="${INSTALL_DIR}/VirtualBox"
89VBOXMANAGE="${INSTALL_DIR}/VBoxManage"
90BUILDINTMP="${MODULE_SRC}/build_in_tmp"
91if test -u "${VIRTUALBOX}"; then
92 GROUP=root
93 DEVICE_MODE=0600
94else
95 GROUP=vboxusers
96 DEVICE_MODE=0660
97fi
98
99KERN_VER=`uname -r`
100
101# Prepend PATH for building UEK7 on OL8 distribution.
102case "$KERN_VER" in
103 5.15.0-*.el8uek*) PATH="/opt/rh/gcc-toolset-11/root/usr/bin:$PATH";;
104esac
105
106if test -e "${MODULE_SRC}/vboxpci"; then
107 MODULE_LIST="vboxdrv vboxnetflt vboxnetadp vboxpci"
108else
109 MODULE_LIST="vboxdrv vboxnetflt vboxnetadp"
110fi
111# Secure boot state.
112case "`mokutil --sb-state 2>/dev/null`" in
113 *"disabled in shim"*) unset HAVE_SEC_BOOT;;
114 *"SecureBoot enabled"*) HAVE_SEC_BOOT=true;;
115 *) unset HAVE_SEC_BOOT;;
116esac
117# So far we can only sign modules on Ubuntu and on Debian 10 and later.
118DEB_PUB_KEY=/var/lib/shim-signed/mok/MOK.der
119DEB_PRIV_KEY=/var/lib/shim-signed/mok/MOK.priv
120unset HAVE_DEB_KEY
121case "`mokutil --test-key "$DEB_PUB_KEY" 2>/dev/null`" in
122 *"is already"*) DEB_KEY_ENROLLED=true;;
123 *) unset DEB_KEY_ENROLLED;;
124esac
125
126# Try to find a tool for modules signing.
127SIGN_TOOL=$(which kmodsign 2>/dev/null)
128# Attempt to use in-kernel signing tool if kmodsign not found.
129if test -z "$SIGN_TOOL"; then
130 if test -x "/lib/modules/$KERN_VER/build/scripts/sign-file"; then
131 SIGN_TOOL="/lib/modules/$KERN_VER/build/scripts/sign-file"
132 fi
133fi
134
135# Check if update-secureboot-policy tool supports required commandline options.
136update_secureboot_policy_supports()
137{
138 opt_name="$1"
139 [ -n "$opt_name" ] || return
140
141 [ -z "$(update-secureboot-policy --help 2>&1 | grep "$opt_name")" ] && return
142 echo "1"
143}
144
145HAVE_UPDATE_SECUREBOOT_POLICY_TOOL=
146if type update-secureboot-policy >/dev/null 2>&1; then
147 [ "$(update_secureboot_policy_supports new-key)" = "1" -a "$(update_secureboot_policy_supports enroll-key)" = "1" ] && \
148 HAVE_UPDATE_SECUREBOOT_POLICY_TOOL=true
149fi
150
151[ -r /etc/default/virtualbox ] && . /etc/default/virtualbox
152
153# Preamble for Gentoo
154if [ "`which $0`" = "/sbin/rc" ]; then
155 shift
156fi
157
158begin_msg()
159{
160 test -n "${2}" && echo "${SCRIPTNAME}: ${1}."
161 logger -t "${SCRIPTNAME}" "${1}."
162}
163
164succ_msg()
165{
166 logger -t "${SCRIPTNAME}" "${1}."
167}
168
169fail_msg()
170{
171 echo "${SCRIPTNAME}: failed: ${1}." >&2
172 logger -t "${SCRIPTNAME}" "failed: ${1}."
173}
174
175failure()
176{
177 fail_msg "$1"
178 exit 1
179}
180
181running()
182{
183 lsmod | grep -q "$1[^_-]"
184}
185
186log()
187{
188 setup_log
189 echo "${1}" >> "${LOG}"
190}
191
192module_build_log()
193{
194 setup_log
195 echo "${1}" | egrep -v \
196 "^test -e include/generated/autoconf.h|^echo >&2|^/bin/false\)$" \
197 >> "${LOG}"
198}
199
200# Detect VirtualBox version info or report error.
201VBOX_VERSION="`"$VBOXMANAGE" -v | cut -d r -f1`"
202[ -n "$VBOX_VERSION" ] || failure 'Cannot detect VirtualBox version number'
203VBOX_REVISION="r`"$VBOXMANAGE" -v | cut -d r -f2`"
204[ "$VBOX_REVISION" != "r" ] || failure 'Cannot detect VirtualBox revision number'
205
206## Output the vboxdrv part of our udev rule. This is redirected to the right file.
207udev_write_vboxdrv() {
208 VBOXDRV_GRP="$1"
209 VBOXDRV_MODE="$2"
210
211 echo "KERNEL==\"vboxdrv\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"$VBOXDRV_MODE\""
212 echo "KERNEL==\"vboxdrvu\", OWNER=\"root\", GROUP=\"root\", MODE=\"0666\""
213 echo "KERNEL==\"vboxnetctl\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"$VBOXDRV_MODE\""
214}
215
216## Output the USB part of our udev rule. This is redirected to the right file.
217udev_write_usb() {
218 INSTALLATION_DIR="$1"
219 USB_GROUP="$2"
220
221 echo "SUBSYSTEM==\"usb_device\", ACTION==\"add\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}${USB_GROUP}\""
222 echo "SUBSYSTEM==\"usb\", ACTION==\"add\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}${USB_GROUP}\""
223 echo "SUBSYSTEM==\"usb_device\", ACTION==\"remove\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\""
224 echo "SUBSYSTEM==\"usb\", ACTION==\"remove\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\""
225}
226
227## Generate our udev rule file. This takes a change in udev rule syntax in
228## version 55 into account. It only creates rules for USB for udev versions
229## recent enough to support USB device nodes.
230generate_udev_rule() {
231 VBOXDRV_GRP="$1" # The group owning the vboxdrv device
232 VBOXDRV_MODE="$2" # The access mode for the vboxdrv device
233 INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
234 USB_GROUP="$4" # The group that has permission to access USB devices
235 NO_INSTALL="$5" # Set this to "1" to remove but not re-install rules
236
237 # Extra space!
238 case "$USB_GROUP" in ?*) USB_GROUP=" $USB_GROUP" ;; esac
239 case "$NO_INSTALL" in "1") return ;; esac
240 udev_write_vboxdrv "$VBOXDRV_GRP" "$VBOXDRV_MODE"
241 udev_write_usb "$INSTALLATION_DIR" "$USB_GROUP"
242}
243
244## Install udev rule (disable with INSTALL_NO_UDEV=1 in
245## /etc/default/virtualbox).
246install_udev() {
247 VBOXDRV_GRP="$1" # The group owning the vboxdrv device
248 VBOXDRV_MODE="$2" # The access mode for the vboxdrv device
249 INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
250 USB_GROUP="$4" # The group that has permission to access USB devices
251 NO_INSTALL="$5" # Set this to "1" to remove but not re-install rules
252
253 if test -d /etc/udev/rules.d; then
254 generate_udev_rule "$VBOXDRV_GRP" "$VBOXDRV_MODE" "$INSTALLATION_DIR" \
255 "$USB_GROUP" "$NO_INSTALL"
256 fi
257 # Remove old udev description file
258 rm -f /etc/udev/rules.d/10-vboxdrv.rules 2> /dev/null
259}
260
261## Create a usb device node for a given sysfs path to a USB device.
262install_create_usb_node_for_sysfs() {
263 path="$1" # sysfs path for the device
264 usb_createnode="$2" # Path to the USB device node creation script
265 usb_group="$3" # The group to give ownership of the node to
266 if test -r "${path}/dev"; then
267 dev="`cat "${path}/dev" 2> /dev/null`"
268 major="`expr "$dev" : '\(.*\):' 2> /dev/null`"
269 minor="`expr "$dev" : '.*:\(.*\)' 2> /dev/null`"
270 class="`cat ${path}/bDeviceClass 2> /dev/null`"
271 sh "${usb_createnode}" "$major" "$minor" "$class" \
272 "${usb_group}" 2>/dev/null
273 fi
274}
275
276udev_rule_file=/etc/udev/rules.d/60-vboxdrv.rules
277sysfs_usb_devices="/sys/bus/usb/devices/*"
278
279## Install udev rules and create device nodes for usb access
280setup_usb() {
281 VBOXDRV_GRP="$1" # The group that should own /dev/vboxdrv
282 VBOXDRV_MODE="$2" # The mode to be used for /dev/vboxdrv
283 INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
284 USB_GROUP="$4" # The group that should own the /dev/vboxusb device
285 # nodes unless INSTALL_NO_GROUP=1 in
286 # /etc/default/virtualbox. Optional.
287 usb_createnode="$INSTALLATION_DIR/VBoxCreateUSBNode.sh"
288 # install udev rule (disable with INSTALL_NO_UDEV=1 in
289 # /etc/default/virtualbox)
290 if [ "$INSTALL_NO_GROUP" != "1" ]; then
291 usb_group=$USB_GROUP
292 vboxdrv_group=$VBOXDRV_GRP
293 else
294 usb_group=root
295 vboxdrv_group=root
296 fi
297 install_udev "${vboxdrv_group}" "$VBOXDRV_MODE" \
298 "$INSTALLATION_DIR" "${usb_group}" \
299 "$INSTALL_NO_UDEV" > ${udev_rule_file}
300 # Build our device tree
301 for i in ${sysfs_usb_devices}; do # This line intentionally without quotes.
302 install_create_usb_node_for_sysfs "$i" "${usb_createnode}" \
303 "${usb_group}"
304 done
305}
306
307cleanup_usb()
308{
309 # Remove udev description file
310 rm -f /etc/udev/rules.d/60-vboxdrv.rules
311 rm -f /etc/udev/rules.d/10-vboxdrv.rules
312
313 # Remove our USB device tree
314 rm -rf /dev/vboxusb
315}
316
317# Returns path to module file as seen by modinfo(8) or empty string.
318module_path()
319{
320 mod="$1"
321 [ -n "$mod" ] || return
322
323 modinfo "$mod" 2>/dev/null | grep -e "^filename:" | tr -s ' ' | cut -d " " -f2
324}
325
326# Returns module version if module is available or empty string.
327module_version()
328{
329 mod="$1"
330 [ -n "$mod" ] || return
331
332 modinfo "$mod" 2>/dev/null | grep -e "^version:" | tr -s ' ' | cut -d " " -f2
333}
334
335# Returns module revision if module is available in the system or empty string.
336module_revision()
337{
338 mod="$1"
339 [ -n "$mod" ] || return
340
341 modinfo "$mod" 2>/dev/null | grep -e "^version:" | tr -s ' ' | cut -d " " -f3
342}
343
344# Reads kernel configuration option.
345kernel_get_config_opt()
346{
347 opt_name="$1"
348 [ -n "$opt_name" ] || return
349
350 # Check if there is a kernel tool which can extract config option.
351 if test -x /lib/modules/"$KERN_VER"/build/scripts/config; then
352 /lib/modules/"$KERN_VER"/build/scripts/config \
353 --file /lib/modules/"$KERN_VER"/build/.config \
354 --state "$opt_name" 2>/dev/null
355 elif test -f /lib/modules/"$KERN_VER"/build/.config; then
356 # Extract config option manually.
357 grep "$opt_name" /lib/modules/"$KERN_VER"/build/.config | sed -e "s/^$opt_name=//" -e "s/\"//g"
358 fi
359}
360
361# Reads CONFIG_MODULE_SIG_HASH from kernel config.
362kernel_module_sig_hash()
363{
364 kernel_get_config_opt "CONFIG_MODULE_SIG_HASH"
365}
366
367# Returns "1" if kernel module signature hash algorithm
368# is supported by us. Or empty string otherwise.
369module_sig_hash_supported()
370{
371 sig_hashalgo="$1"
372 [ -n "$sig_hashalgo" ] || return
373
374 # Go through supported list.
375 [ "$sig_hashalgo" = "sha1" \
376 -o "$sig_hashalgo" = "sha224" \
377 -o "$sig_hashalgo" = "sha256" \
378 -o "$sig_hashalgo" = "sha384" \
379 -o "$sig_hashalgo" = "sha512" ] || return
380
381 echo "1"
382}
383
384# Returns "1" if module is signed and signature can be verified
385# with public key provided in DEB_PUB_KEY. Or empty string otherwise.
386module_signed()
387{
388 mod="$1"
389 [ -n "$mod" ] || return
390
391 extraction_tool=/lib/modules/"$(uname -r)"/build/scripts/extract-module-sig.pl
392 mod_path=$(module_path "$mod" 2>/dev/null)
393 openssl_tool=$(which openssl 2>/dev/null)
394 # Do not use built-in printf!
395 printf_tool=$(which printf 2>/dev/null)
396
397 # Make sure all the tools required for signature validation are available.
398 [ -x "$extraction_tool" ] || return
399 [ -n "$mod_path" ] || return
400 [ -n "$openssl_tool" ] || return
401 [ -n "$printf_tool" ] || return
402
403 # Make sure openssl can handle hash algorithm.
404 sig_hashalgo=$(modinfo -F sig_hashalgo "$mod" 2>/dev/null)
405 [ "$(module_sig_hash_supported $sig_hashalgo)" = "1" ] || return
406
407 # Generate file names for temporary stuff.
408 mod_pub_key=$(mktemp -u)
409 mod_signature=$(mktemp -u)
410 mod_unsigned=$(mktemp -u)
411
412 # Convert public key in DER format into X509 certificate form.
413 "$openssl_tool" x509 -pubkey -inform DER -in "$DEB_PUB_KEY" -out "$mod_pub_key" 2>/dev/null
414 # Extract raw module signature and convert it into binary format.
415 "$printf_tool" \\x$(modinfo -F signature "$mod" | sed -z 's/[ \t\n]//g' | sed -e "s/:/\\\x/g") 2>/dev/null > "$mod_signature"
416 # Extract unsigned module for further digest calculation.
417 "$extraction_tool" -0 "$mod_path" 2>/dev/null > "$mod_unsigned"
418
419 # Verify signature.
420 rc=""
421 "$openssl_tool" dgst "-$sig_hashalgo" -binary -verify "$mod_pub_key" -signature "$mod_signature" "$mod_unsigned" 2>&1 >/dev/null && rc="1"
422 # Clean up.
423 rm -f $mod_pub_key $mod_signature $mod_unsigned
424
425 # Check result.
426 [ "$rc" = "1" ] || return
427
428 echo "1"
429}
430
431# Returns "1" if externally built module is available in the system and its
432# version and revision number do match to current VirtualBox installation.
433# Or empty string otherwise.
434module_available()
435{
436 mod="$1"
437 [ -n "$mod" ] || return
438
439 [ "$VBOX_VERSION" = "$(module_version "$mod")" ] || return
440 [ "$VBOX_REVISION" = "$(module_revision "$mod")" ] || return
441
442 # Check if module belongs to VirtualBox installation.
443 #
444 # We have a convention that only modules from /lib/modules/*/misc
445 # belong to us. Modules from other locations are treated as
446 # externally built.
447 mod_path="$(module_path "$mod")"
448
449 # If module path points to a symbolic link, resolve actual file location.
450 [ -L "$mod_path" ] && mod_path="$(readlink -e -- "$mod_path")"
451
452 # File exists?
453 [ -f "$mod_path" ] || return
454
455 # Extract last component of module path and check whether it is located
456 # outside of /lib/modules/*/misc.
457 mod_dir="$(dirname "$mod_path" | sed 's;^.*/;;')"
458 [ "$mod_dir" = "misc" ] || return
459
460 # In case if system is running in Secure Boot mode, check if module is signed.
461 if test -n "$HAVE_SEC_BOOT"; then
462 [ "$(module_signed "$mod")" = "1" ] || return
463 fi
464
465 echo "1"
466}
467
468# Check if required modules are installed in the system and versions match.
469setup_complete()
470{
471 [ "$(module_available vboxdrv)" = "1" ] || return
472 [ "$(module_available vboxnetflt)" = "1" ] || return
473 [ "$(module_available vboxnetadp)" = "1" ] || return
474
475 # All modules are in place.
476 echo "1"
477}
478
479start()
480{
481 begin_msg "Starting VirtualBox services" console
482 if [ -d /proc/xen ]; then
483 failure "Running VirtualBox in a Xen environment is not supported"
484 fi
485 if test -n "$HAVE_SEC_BOOT" && test -z "$DEB_KEY_ENROLLED"; then
486 if test -n "$HAVE_DEB_KEY"; then
487 begin_msg "You must re-start your system to finish Debian secure boot set-up." console
488 else
489 begin_msg "You must sign these kernel modules before using VirtualBox:
490 $MODULE_LIST
491See the documentation for your Linux distribution." console
492 fi
493 fi
494
495 if ! running vboxdrv; then
496
497 # Check if system already has matching modules installed.
498 [ "$(setup_complete)" = "1" ] || setup
499
500 if ! rm -f $DEVICE; then
501 failure "Cannot remove $DEVICE"
502 fi
503 if ! $MODPROBE vboxdrv > /dev/null 2>&1; then
504 failure "modprobe vboxdrv failed. Please use 'dmesg' to find out why"
505 fi
506 sleep .2
507 fi
508 # ensure the character special exists
509 if [ ! -c $DEVICE ]; then
510 MAJOR=`sed -n 's;\([0-9]\+\) vboxdrv$;\1;p' /proc/devices`
511 if [ ! -z "$MAJOR" ]; then
512 MINOR=0
513 else
514 MINOR=`sed -n 's;\([0-9]\+\) vboxdrv$;\1;p' /proc/misc`
515 if [ ! -z "$MINOR" ]; then
516 MAJOR=10
517 fi
518 fi
519 if [ -z "$MAJOR" ]; then
520 rmmod vboxdrv 2>/dev/null
521 failure "Cannot locate the VirtualBox device"
522 fi
523 if ! mknod -m 0660 $DEVICE c $MAJOR $MINOR 2>/dev/null; then
524 rmmod vboxdrv 2>/dev/null
525 failure "Cannot create device $DEVICE with major $MAJOR and minor $MINOR"
526 fi
527 fi
528 # ensure permissions
529 if ! chown :"${GROUP}" $DEVICE 2>/dev/null; then
530 rmmod vboxpci 2>/dev/null
531 rmmod vboxnetadp 2>/dev/null
532 rmmod vboxnetflt 2>/dev/null
533 rmmod vboxdrv 2>/dev/null
534 failure "Cannot change group ${GROUP} for device $DEVICE"
535 fi
536 if ! $MODPROBE vboxnetflt > /dev/null 2>&1; then
537 failure "modprobe vboxnetflt failed. Please use 'dmesg' to find out why"
538 fi
539 if ! $MODPROBE vboxnetadp > /dev/null 2>&1; then
540 failure "modprobe vboxnetadp failed. Please use 'dmesg' to find out why"
541 fi
542 if test -e "${MODULE_SRC}/vboxpci" && ! $MODPROBE vboxpci > /dev/null 2>&1; then
543 failure "modprobe vboxpci failed. Please use 'dmesg' to find out why"
544 fi
545 # Create the /dev/vboxusb directory if the host supports that method
546 # of USB access. The USB code checks for the existance of that path.
547 if grep -q usb_device /proc/devices; then
548 mkdir -p -m 0750 /dev/vboxusb 2>/dev/null
549 chown root:vboxusers /dev/vboxusb 2>/dev/null
550 fi
551 # Remove any kernel modules left over from previously installed kernels.
552 cleanup only_old
553 succ_msg "VirtualBox services started"
554}
555
556stop()
557{
558 begin_msg "Stopping VirtualBox services" console
559
560 if running vboxpci; then
561 if ! rmmod vboxpci 2>/dev/null; then
562 failure "Cannot unload module vboxpci"
563 fi
564 fi
565 if running vboxnetadp; then
566 if ! rmmod vboxnetadp 2>/dev/null; then
567 failure "Cannot unload module vboxnetadp"
568 fi
569 fi
570 if running vboxdrv; then
571 if running vboxnetflt; then
572 if ! rmmod vboxnetflt 2>/dev/null; then
573 failure "Cannot unload module vboxnetflt"
574 fi
575 fi
576 if ! rmmod vboxdrv 2>/dev/null; then
577 failure "Cannot unload module vboxdrv"
578 fi
579 if ! rm -f $DEVICE; then
580 failure "Cannot unlink $DEVICE"
581 fi
582 fi
583 succ_msg "VirtualBox services stopped"
584}
585
586# enter the following variables in /etc/default/virtualbox:
587# SHUTDOWN_USERS="foo bar"
588# check for running VMs of user foo and user bar
589# SHUTDOWN=poweroff
590# SHUTDOWN=acpibutton
591# SHUTDOWN=savestate
592# select one of these shutdown methods for running VMs
593stop_vms()
594{
595 wait=0
596 for i in $SHUTDOWN_USERS; do
597 # don't create the ipcd directory with wrong permissions!
598 if [ -d /tmp/.vbox-$i-ipc ]; then
599 export VBOX_IPC_SOCKETID="$i"
600 VMS=`$VBOXMANAGE --nologo list runningvms | sed -e 's/^".*".*{\(.*\)}/\1/' 2>/dev/null`
601 if [ -n "$VMS" ]; then
602 if [ "$SHUTDOWN" = "poweroff" ]; then
603 begin_msg "Powering off remaining VMs"
604 for v in $VMS; do
605 $VBOXMANAGE --nologo controlvm $v poweroff
606 done
607 succ_msg "Remaining VMs powered off"
608 elif [ "$SHUTDOWN" = "acpibutton" ]; then
609 begin_msg "Sending ACPI power button event to remaining VMs"
610 for v in $VMS; do
611 $VBOXMANAGE --nologo controlvm $v acpipowerbutton
612 wait=30
613 done
614 succ_msg "ACPI power button event sent to remaining VMs"
615 elif [ "$SHUTDOWN" = "savestate" ]; then
616 begin_msg "Saving state of remaining VMs"
617 for v in $VMS; do
618 $VBOXMANAGE --nologo controlvm $v savestate
619 done
620 succ_msg "State of remaining VMs saved"
621 fi
622 fi
623 fi
624 done
625 # wait for some seconds when doing ACPI shutdown
626 if [ "$wait" -ne 0 ]; then
627 begin_msg "Waiting for $wait seconds for VM shutdown"
628 sleep $wait
629 succ_msg "Waited for $wait seconds for VM shutdown"
630 fi
631}
632
633cleanup()
634{
635 # If this is set, only remove kernel modules for no longer installed
636 # kernels. Note that only generated kernel modules should be placed
637 # in /lib/modules/*/misc. Anything that we should not remove automatically
638 # should go elsewhere.
639 only_old="${1}"
640 for i in /lib/modules/*; do
641 # Check whether we are only cleaning up for uninstalled kernels.
642 test -n "${only_old}" && test -e "${i}/kernel/drivers" && continue
643
644 unset do_update
645 for j in $MODULE_LIST; do
646 for mod_ext in ko ko.gz ko.xz ko.zst; do
647 test -f "${i}/misc/${j}.${mod_ext}" && do_update=1 && rm -f "${i}/misc/${j}.${mod_ext}"
648 done
649 done
650
651 # Trigger depmod(8) only in case if directory content was modified
652 # and save a bit of run time.
653 test -n "$do_update" && depmod -a "$(basename "$i")" && sync
654
655 # Remove the kernel version folder if it was empty except for us.
656 test "`echo ${i}/misc/* ${i}/misc/.?* ${i}/* ${i}/.?*`" \
657 = "${i}/misc/* ${i}/misc/.. ${i}/misc ${i}/.." &&
658 rmdir "${i}/misc" "${i}" # We used to leave empty folders.
659 done
660}
661
662# setup_script
663setup()
664{
665 begin_msg "Building VirtualBox kernel modules" console
666 log "Building the main VirtualBox module."
667
668 # Detect if kernel was built with clang.
669 unset LLVM
670 vbox_cc_is_clang=$(kernel_get_config_opt "CONFIG_CC_IS_CLANG")
671 if test "${vbox_cc_is_clang}" = "y"; then
672 log "Using clang compiler."
673 export LLVM=1
674 fi
675
676 if ! myerr=`$BUILDINTMP \
677 --save-module-symvers /tmp/vboxdrv-Module.symvers \
678 --module-source "$MODULE_SRC/vboxdrv" \
679 --no-print-directory install 2>&1`; then
680 "${INSTALL_DIR}/check_module_dependencies.sh" || exit 1
681 log "Error building the module:"
682 module_build_log "$myerr"
683 failure "Look at $LOG to find out what went wrong"
684 fi
685 log "Building the net filter module."
686 if ! myerr=`$BUILDINTMP \
687 --use-module-symvers /tmp/vboxdrv-Module.symvers \
688 --module-source "$MODULE_SRC/vboxnetflt" \
689 --no-print-directory install 2>&1`; then
690 log "Error building the module:"
691 module_build_log "$myerr"
692 failure "Look at $LOG to find out what went wrong"
693 fi
694 log "Building the net adaptor module."
695 if ! myerr=`$BUILDINTMP \
696 --use-module-symvers /tmp/vboxdrv-Module.symvers \
697 --module-source "$MODULE_SRC/vboxnetadp" \
698 --no-print-directory install 2>&1`; then
699 log "Error building the module:"
700 module_build_log "$myerr"
701 failure "Look at $LOG to find out what went wrong"
702 fi
703 if test -e "$MODULE_SRC/vboxpci"; then
704 log "Building the PCI pass-through module."
705 if ! myerr=`$BUILDINTMP \
706 --use-module-symvers /tmp/vboxdrv-Module.symvers \
707 --module-source "$MODULE_SRC/vboxpci" \
708 --no-print-directory install 2>&1`; then
709 log "Error building the module:"
710 module_build_log "$myerr"
711 failure "Look at $LOG to find out what went wrong"
712 fi
713 fi
714 rm -f /etc/vbox/module_not_compiled
715 depmod -a
716 sync
717 succ_msg "VirtualBox kernel modules built"
718
719 # Secure boot on Ubuntu, Debian and Oracle Linux.
720 if test -n "$HAVE_SEC_BOOT"; then
721 begin_msg "Signing VirtualBox kernel modules" console
722
723 # Generate new signing key if needed.
724 [ -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL" ] && SHIM_NOTRIGGER=y update-secureboot-policy --new-key
725
726 # Check if signing keys are in place.
727 if test ! -f "$DEB_PUB_KEY" || ! test -f "$DEB_PRIV_KEY"; then
728 # update-secureboot-policy tool present in the system, but keys were not generated.
729 [ -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL" ] && fail_msg "
730
731update-secureboot-policy tool does not generate signing keys
732in your distribution, see below on how to generate them manually
733"
734
735 # update-secureboot-policy not present in the system, recommend generate keys manually.
736 failure "
737
738System is running in Secure Boot mode, however your distribution
739does not provide tools for automatic generation of keys needed for
740modules signing. Please consider to generate and enroll them manually:
741
742 sudo mkdir -p /var/lib/shim-signed/mok
743 sudo openssl req -nodes -new -x509 -newkey rsa:2048 -outform DER -addext \"extendedKeyUsage=codeSigning\" -keyout $DEB_PRIV_KEY -out $DEB_PUB_KEY
744 sudo mokutil --import $DEB_PUB_KEY
745 sudo reboot
746
747Restart \"rcvboxdrv setup\" after system is rebooted
748"
749 fi
750
751 # Check if signing tool is available.
752 [ -n "$SIGN_TOOL" ] || failure "Unable to find signing tool"
753
754 # Get kernel signature hash algorithm from kernel config and validate it.
755 sig_hashalgo=$(kernel_module_sig_hash)
756 [ "$(module_sig_hash_supported $sig_hashalgo)" = "1" ] \
757 || failure "Unsupported kernel signature hash algorithm $sig_hashalgo"
758
759 # Sign modules.
760 for i in $MODULE_LIST; do
761 "$SIGN_TOOL" "$sig_hashalgo" "$DEB_PRIV_KEY" "$DEB_PUB_KEY" \
762 /lib/modules/"$KERN_VER"/misc/"$i".ko 2>/dev/null || failure "Unable to sign $i.ko"
763 done
764
765 # Enroll signing key if needed.
766 if test -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL"; then
767 # update-secureboot-policy "expects" DKMS modules.
768 # Work around this and talk to the authors as soon
769 # as possible to fix it.
770 mkdir -p /var/lib/dkms/vbox-temp
771 update-secureboot-policy --enroll-key 2>/dev/null ||
772 begin_msg "Failed to enroll secure boot key." console
773 rmdir -p /var/lib/dkms/vbox-temp 2>/dev/null
774
775 # Indicate that key has been enrolled and reboot is needed.
776 HAVE_DEB_KEY=true
777 fi
778 succ_msg "Signing completed"
779 fi
780}
781
782dmnstatus()
783{
784 if running vboxdrv; then
785 str="vboxdrv"
786 if running vboxnetflt; then
787 str="$str, vboxnetflt"
788 if running vboxnetadp; then
789 str="$str, vboxnetadp"
790 fi
791 fi
792 if running vboxpci; then
793 str="$str, vboxpci"
794 fi
795 echo "VirtualBox kernel modules ($str) are loaded."
796 for i in $SHUTDOWN_USERS; do
797 # don't create the ipcd directory with wrong permissions!
798 if [ -d /tmp/.vbox-$i-ipc ]; then
799 export VBOX_IPC_SOCKETID="$i"
800 VMS=`$VBOXMANAGE --nologo list runningvms | sed -e 's/^".*".*{\(.*\)}/\1/' 2>/dev/null`
801 if [ -n "$VMS" ]; then
802 echo "The following VMs are currently running:"
803 for v in $VMS; do
804 echo " $v"
805 done
806 fi
807 fi
808 done
809 else
810 echo "VirtualBox kernel module is not loaded."
811 fi
812}
813
814case "$1" in
815start)
816 start
817 ;;
818stop)
819 stop_vms
820 stop
821 ;;
822stop_vms)
823 stop_vms
824 ;;
825restart)
826 stop && start
827 ;;
828setup)
829 test -n "${2}" && export KERN_VER="${2}"
830 # Create udev rule and USB device nodes.
831 ## todo Wouldn't it make more sense to install the rule to /lib/udev? This
832 ## is not a user-created configuration file after all.
833 ## todo Do we need a udev rule to create /dev/vboxdrv[u] at all? We have
834 ## working fall-back code here anyway, and the "right" code is more complex
835 ## than the fall-back. Unnecessary duplication?
836 stop && cleanup
837 setup_usb "$GROUP" "$DEVICE_MODE" "$INSTALL_DIR"
838 start
839 ;;
840cleanup)
841 stop && cleanup
842 cleanup_usb
843 ;;
844force-reload)
845 stop
846 start
847 ;;
848status)
849 dmnstatus
850 ;;
851*)
852 echo "Usage: $0 {start|stop|stop_vms|restart|setup|cleanup|force-reload|status}"
853 exit 1
854esac
855
856exit 0
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