VirtualBox

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

Last change on this file since 97635 was 97603, checked in by vboxsync, 2 years ago

Linux: Adjust startup scripts for building kernel modules for UEK7 on OL8 distribution, @bugdbref{34811820}.

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