forked from pool/virtualbox
593b34655b
- Setting 0660 as permissions of /dev/vboxusb directory itself was preventing access to this directory by any non-root user, even if member of vboxusers. This results in VBox UI failing to enable USB passthrough. Fix issue by removing all the workarounds for /dev/vboxusb/* as they should no longer be required. I have verified that with this USB passhtrough works on today's TW (real machine), as well as Leap 15.5 (on a VM) and today's Leap 15.6 beta (unfortunately, I couldn't get a nested VM to work on 15.6 at all -- but with this fix the UI can enumerate USB devices at least). Without this fix, VBox always shows "VirtualBox is not currently allowed to access USB devices. You can change this by adding your user to vboxusers [....]", and the UI cannot enumerate USB devices at all. OBS-URL: https://build.opensuse.org/request/show/1163957 OBS-URL: https://build.opensuse.org/package/show/Virtualization/virtualbox?expand=0&rev=732
376 lines
12 KiB
Bash
376 lines
12 KiB
Bash
#! /bin/sh
|
|
# Oracle VM VirtualBox
|
|
# Linux kernel module init script
|
|
|
|
#
|
|
# Copyright (C) 2006-2015 Oracle Corporation
|
|
#
|
|
# This file is part of VirtualBox Open Source Edition (OSE), as
|
|
# available from http://www.virtualbox.org. This file is free software;
|
|
# you can redistribute it and/or modify it under the terms of the GNU
|
|
# General Public License (GPL) as published by the Free Software
|
|
# Foundation, in version 2 as it comes in the "COPYING" file of the
|
|
# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
|
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
|
#
|
|
|
|
# chkconfig: 345 20 80
|
|
# description: VirtualBox Linux kernel module
|
|
#
|
|
### BEGIN INIT INFO
|
|
# Provides: vboxdrv
|
|
# Required-Start: $syslog $remote_fs
|
|
# Required-Stop: $syslog $remote_fs
|
|
# Default-Start: 2 3 5
|
|
# Default-Stop: 0 1 6
|
|
# Short-Description: VirtualBox Linux module
|
|
# Description: VirtualBox Linux kernel module
|
|
### END INIT INFO
|
|
|
|
PATH=/usr/sbin:/usr/bin:$PATH
|
|
DEVICE=/dev/vboxdrv
|
|
LOG="/var/log/vbox-install.log"
|
|
MODPROBE=/usr/sbin/modprobe
|
|
SCRIPTNAME=vboxdrv.sh
|
|
INSTALL_DIR=/usr/lib/virtualbox
|
|
|
|
# The below is GNU-specific. See VBox.sh for the longer Solaris/OS X version.
|
|
TARGET=`readlink -e -- "${0}"` || exit 1
|
|
SCRIPT_DIR="${TARGET%/[!/]*}"
|
|
|
|
if $MODPROBE -c | grep -q '^allow_unsupported_modules *0'; then
|
|
MODPROBE="$MODPROBE --allow-unsupported-modules"
|
|
fi
|
|
|
|
[ -f /etc/vbox/vbox.cfg ] && . /etc/vbox/vbox.cfg
|
|
export BUILD_TYPE
|
|
export USERNAME
|
|
export USER=$USERNAME
|
|
|
|
VIRTUALBOX="${INSTALL_DIR}/VirtualBox"
|
|
VBOXMANAGE="${INSTALL_DIR}/VBoxManage"
|
|
BUILDINTMP="${MODULE_SRC}/build_in_tmp"
|
|
if test -u "${VBOXMANAGE}"; then
|
|
GROUP=root
|
|
DEVICE_MODE=0600
|
|
else
|
|
GROUP=vboxusers
|
|
DEVICE_MODE=0660
|
|
fi
|
|
|
|
[ -r /etc/default/virtualbox ] && . /etc/default/virtualbox
|
|
|
|
begin_msg()
|
|
{
|
|
test -n "${2}" && echo "${SCRIPTNAME}: ${1}."
|
|
logger -t "${SCRIPTNAME}" "${1}."
|
|
}
|
|
|
|
succ_msg()
|
|
{
|
|
logger -t "${SCRIPTNAME}" "${1}."
|
|
}
|
|
|
|
fail_msg()
|
|
{
|
|
echo "${SCRIPTNAME}: failed: ${1}." >&2
|
|
logger -t "${SCRIPTNAME}" "failed: ${1}."
|
|
}
|
|
|
|
failure()
|
|
{
|
|
fail_msg "$1"
|
|
exit 1
|
|
}
|
|
|
|
running()
|
|
{
|
|
lsmod | grep -q "$1[^_-]"
|
|
}
|
|
|
|
## Output the vboxdrv part of our udev rule. This is redirected to the right file.
|
|
udev_write_vboxdrv() {
|
|
VBOXDRV_GRP="$1"
|
|
VBOXDRV_MODE="$2"
|
|
|
|
echo "KERNEL==\"vboxdrv\", NAME=\"vboxdrv\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"$VBOXDRV_MODE\""
|
|
echo "KERNEL==\"vboxdrvu\", NAME=\"vboxdrvu\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"0660\""
|
|
echo "KERNEL==\"vboxnetctl\", NAME=\"vboxnetctl\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"$VBOXDRV_MODE\""
|
|
}
|
|
|
|
## Output the USB part of our udev rule. This is redirected to the right file.
|
|
udev_write_usb() {
|
|
INSTALLATION_DIR="$1"
|
|
USB_GROUP="$2"
|
|
|
|
echo "SUBSYSTEM==\"usb_device\", ACTION==\"add\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}${USB_GROUP}\""
|
|
echo "SUBSYSTEM==\"usb\", ACTION==\"add\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}${USB_GROUP}\""
|
|
echo "SUBSYSTEM==\"usb_device\", ACTION==\"remove\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\""
|
|
echo "SUBSYSTEM==\"usb\", ACTION==\"remove\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\""
|
|
}
|
|
|
|
## Generate our udev rule file. This takes a change in udev rule syntax in
|
|
## version 55 into account. It only creates rules for USB for udev versions
|
|
## recent enough to support USB device nodes.
|
|
generate_udev_rule() {
|
|
VBOXDRV_GRP="$1" # The group owning the vboxdrv device
|
|
VBOXDRV_MODE="$2" # The access mode for the vboxdrv device
|
|
INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
|
|
USB_GROUP="$4" # The group that has permission to access USB devices
|
|
NO_INSTALL="$5" # Set this to "1" to remove but not re-install rules
|
|
|
|
# Extra space!
|
|
case "$USB_GROUP" in ?*) USB_GROUP=" $USB_GROUP" ;; esac
|
|
case "$NO_INSTALL" in "1") return ;; esac
|
|
udev_write_vboxdrv "$VBOXDRV_GRP" "$VBOXDRV_MODE"
|
|
udev_write_usb "$INSTALLATION_DIR" "$USB_GROUP"
|
|
}
|
|
|
|
## Install udev rule (disable with INSTALL_NO_UDEV=1 in
|
|
## /etc/default/virtualbox).
|
|
install_udev() {
|
|
VBOXDRV_GRP="$1" # The group owning the vboxdrv device
|
|
VBOXDRV_MODE="$2" # The access mode for the vboxdrv device
|
|
INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
|
|
USB_GROUP="$4" # The group that has permission to access USB devices
|
|
NO_INSTALL="$5" # Set this to "1" to remove but not re-install rules
|
|
|
|
if test -d /etc/udev/rules.d; then
|
|
generate_udev_rule "$VBOXDRV_GRP" "$VBOXDRV_MODE" "$INSTALLATION_DIR" \
|
|
"$USB_GROUP" "$NO_INSTALL"
|
|
fi
|
|
# Remove old udev description file
|
|
rm -f /etc/udev/rules.d/10-vboxdrv.rules 2> /dev/null
|
|
}
|
|
|
|
## Create a usb device node for a given sysfs path to a USB device.
|
|
install_create_usb_node_for_sysfs() {
|
|
path="$1" # sysfs path for the device
|
|
usb_createnode="$2" # Path to the USB device node creation script
|
|
usb_group="$3" # The group to give ownership of the node to
|
|
if test -r "${path}/dev"; then
|
|
dev="`cat "${path}/dev" 2> /dev/null`"
|
|
major="`expr "$dev" : '\(.*\):' 2> /dev/null`"
|
|
minor="`expr "$dev" : '.*:\(.*\)' 2> /dev/null`"
|
|
class="`cat ${path}/bDeviceClass 2> /dev/null`"
|
|
sh "${usb_createnode}" "$major" "$minor" "$class" \
|
|
"${usb_group}" 2>/dev/null
|
|
fi
|
|
}
|
|
|
|
udev_rule_file=/etc/udev/rules.d/60-vboxdrv.rules
|
|
sysfs_usb_devices="/sys/bus/usb/devices/*"
|
|
|
|
## Install udev rules and create device nodes for usb access
|
|
setup_usb() {
|
|
VBOXDRV_GRP="$1" # The group that should own /dev/vboxdrv
|
|
VBOXDRV_MODE="$2" # The mode to be used for /dev/vboxdrv
|
|
INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
|
|
USB_GROUP="$4" # The group that should own the /dev/vboxusb device
|
|
# nodes unless INSTALL_NO_GROUP=1 in
|
|
# /etc/default/virtualbox. Optional.
|
|
usb_createnode="$INSTALLATION_DIR/VBoxCreateUSBNode.sh"
|
|
# install udev rule (disable with INSTALL_NO_UDEV=1 in
|
|
# /etc/default/virtualbox)
|
|
if [ "$INSTALL_NO_GROUP" != "1" ]; then
|
|
usb_group=$USB_GROUP
|
|
vboxdrv_group=$VBOXDRV_GRP
|
|
else
|
|
usb_group=root
|
|
vboxdrv_group=root
|
|
fi
|
|
install_udev "${vboxdrv_group}" "$VBOXDRV_MODE" \
|
|
"$INSTALLATION_DIR" "${usb_group}" \
|
|
"$INSTALL_NO_UDEV" > ${udev_rule_file}
|
|
# Build our device tree
|
|
for i in ${sysfs_usb_devices}; do # This line intentionally without quotes.
|
|
install_create_usb_node_for_sysfs "$i" "${usb_createnode}" \
|
|
"${usb_group}"
|
|
done
|
|
}
|
|
|
|
cleanup_usb()
|
|
{
|
|
# Remove udev description file
|
|
rm -f /etc/udev/rules.d/60-vboxdrv.rules
|
|
rm -f /etc/udev/rules.d/10-vboxdrv.rules
|
|
|
|
# Remove our USB device tree
|
|
rm -rf /dev/vboxusb
|
|
}
|
|
|
|
start_drv()
|
|
{
|
|
begin_msg "Starting VirtualBox services" console
|
|
if [ -d /proc/xen ]; then
|
|
failure "Running VirtualBox in a Xen environment is not supported"
|
|
fi
|
|
if ! running vboxdrv; then
|
|
if ! rm -f $DEVICE; then
|
|
failure "Cannot remove $DEVICE"
|
|
fi
|
|
if ! $MODPROBE vboxdrv > /dev/null 2>&1; then
|
|
/usr/sbin/vboxconfig
|
|
if ! $MODPROBE vboxdrv > /dev/null 2>&1; then
|
|
failure "modprobe vboxdrv failed. Please use 'dmesg' to find out why"
|
|
fi
|
|
fi
|
|
sleep .2
|
|
fi
|
|
# ensure the character special exists
|
|
if [ ! -c $DEVICE ]; then
|
|
MAJOR=`sed -n 's;\([0-9]\+\) vboxdrv$;\1;p' /proc/devices`
|
|
if [ ! -z "$MAJOR" ]; then
|
|
MINOR=0
|
|
else
|
|
MINOR=`sed -n 's;\([0-9]\+\) vboxdrv$;\1;p' /proc/extra`
|
|
if [ ! -z "$MINOR" ]; then
|
|
MAJOR=10
|
|
fi
|
|
fi
|
|
if [ -z "$MAJOR" ]; then
|
|
rmmod vboxdrv 2>/dev/null
|
|
failure "Cannot locate the VirtualBox device"
|
|
fi
|
|
if ! mknod -m 0660 $DEVICE c $MAJOR $MINOR 2>/dev/null; then
|
|
rmmod vboxdrv 2>/dev/null
|
|
failure "Cannot create device $DEVICE with major $MAJOR and minor $MINOR"
|
|
fi
|
|
fi
|
|
# ensure permissions
|
|
if ! $MODPROBE vboxnetflt > /dev/null 2>&1; then
|
|
failure "modprobe vboxnetflt failed. Please use 'dmesg' to find out why"
|
|
fi
|
|
if ! $MODPROBE vboxnetadp > /dev/null 2>&1; then
|
|
failure "modprobe vboxnetadp failed. Please use 'dmesg' to find out why"
|
|
fi
|
|
# Create the /dev/vboxusb directory if the host supports that method
|
|
# of USB access. The USB code checks for the existance of that path.
|
|
if grep -q usb_device /proc/devices; then
|
|
mkdir -p -m 0750 /dev/vboxusb 2>/dev/null
|
|
chown root:vboxusers /dev/vboxusb 2>/dev/null
|
|
fi
|
|
succ_msg "VirtualBox services started"
|
|
}
|
|
|
|
stop_drv()
|
|
{
|
|
begin_msg "Stopping VirtualBox services" console
|
|
|
|
if running vboxnetadp; then
|
|
if ! rmmod vboxnetadp 2>/dev/null; then
|
|
failure "Cannot unload module vboxnetadp"
|
|
fi
|
|
fi
|
|
if running vboxdrv; then
|
|
if running vboxnetflt; then
|
|
if ! rmmod vboxnetflt 2>/dev/null; then
|
|
failure "Cannot unload module vboxnetflt"
|
|
fi
|
|
fi
|
|
if ! rmmod vboxdrv 2>/dev/null; then
|
|
failure "Cannot unload module vboxdrv"
|
|
fi
|
|
if ! rm -f $DEVICE; then
|
|
failure "Cannot unlink $DEVICE"
|
|
fi
|
|
fi
|
|
succ_msg "VirtualBox services stopped"
|
|
}
|
|
|
|
cleanup_vb()
|
|
{
|
|
for i in /lib/modules/*; do
|
|
# We could just do "rm -f", but we only want to try deleting folders if
|
|
# we are sure they were ours, i.e. they had our modules in beforehand.
|
|
if test -e "${i}/extra/vboxdrv.ko" \
|
|
|| test -e "${i}/extra/vboxnetadp.ko" \
|
|
|| test -e "${i}/extra/vboxnetflt.ko"; then
|
|
rm -f "${i}/extra/vboxdrv.ko" "${i}/extra/vboxnetadp.ko" \
|
|
"${i}/extra/vboxnetflt.ko"
|
|
# Remove the kernel version folder if it was empty except for us.
|
|
test "`echo ${i}/extra/* ${i}/extra/.?* ${i}/* ${i}/.?*`" \
|
|
= "${i}/extra/* ${i}/extra/.. ${i}/extra ${i}/.." &&
|
|
rmdir "${i}/extra" "${i}" # We used to leave empty folders.
|
|
version=`expr "${i}" : "/lib/modules/\(.*\)"`
|
|
depmod -a "${version}"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# setup_script
|
|
setup_vb()
|
|
{
|
|
# Try to build the host kernel modules in case prepackaging has failed
|
|
/usr/sbin/vboxconfig
|
|
}
|
|
|
|
dmnstatus()
|
|
{
|
|
if running vboxdrv; then
|
|
str="vboxdrv"
|
|
if running vboxnetflt; then
|
|
str="$str, vboxnetflt"
|
|
if running vboxnetadp; then
|
|
str="$str, vboxnetadp"
|
|
fi
|
|
fi
|
|
echo "VirtualBox kernel modules ($str) are loaded."
|
|
for i in $SHUTDOWN_USERS; do
|
|
# don't create the ipcd directory with wrong permissions!
|
|
if [ -d /tmp/.vbox-$i-ipc ]; then
|
|
export VBOX_IPC_SOCKETID="$i"
|
|
VMS=`$VBOXMANAGE --nologo list runningvms | sed -e 's/^".*".*{\(.*\)}/\1/' 2>/dev/null`
|
|
if [ -n "$VMS" ]; then
|
|
echo "The following VMs are currently running:"
|
|
for v in $VMS; do
|
|
echo " $v"
|
|
done
|
|
fi
|
|
fi
|
|
done
|
|
else
|
|
echo "VirtualBox kernel module is not loaded."
|
|
fi
|
|
}
|
|
|
|
case "$1" in
|
|
start)
|
|
start_drv
|
|
;;
|
|
stop)
|
|
stop_drv
|
|
;;
|
|
restart)
|
|
"$0" stop && "$0" start
|
|
;;
|
|
setup)
|
|
# Create udev rule and USB device nodes.
|
|
## todo Wouldn't it make more sense to install the rule to /lib/udev? This
|
|
## is not a user-created configuration file after all.
|
|
## todo Do we need a udev rule to create /dev/vboxdrv[u] at all? We have
|
|
## working fall-back code here anyway, and the "right" code is more complex
|
|
## than the fall-back. Unnecessary duplication?
|
|
stop_drv && cleanup_vb
|
|
setup_usb "$GROUP" "$DEVICE_MODE" "$INSTALL_DIR"
|
|
setup_vb && start_drv
|
|
;;
|
|
cleanup)
|
|
stop_drv && cleanup_vb
|
|
cleanup_usb
|
|
;;
|
|
force-reload)
|
|
"$0" stop
|
|
"$0" start
|
|
;;
|
|
status)
|
|
dmnstatus
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {start|stop|stop_vms|restart|force-reload|status}"
|
|
exit 1
|
|
esac
|
|
|
|
exit 0
|
|
|