VirtualBox

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

Last change on this file since 97014 was 97014, checked in by vboxsync, 3 years ago

Installer: Linux: rcvboxdrv.sh: Parse kernel config manually if /lib/modules/$(uname -r)/build/scripts/config tool is not available, bugref:10287.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette