VirtualBox

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

Last change on this file since 69428 was 69428, checked in by vboxsync, 7 years ago

Installer/linux/vboxdrv.sh: always clean up empty kernel driver misc folders.
bugref:3809: Linux installer maintenance
When we clean up and remove our host kernel drivers, we also check to see if
we are leaving behind an empty misc folder in the kernel driver tree, and if
so we delete it. However we were not always as careful in the past, with
the result that many systems have a number of driver folders for different
kernel versions, empty except for an empty misc folder. This change makes
us delete those if we find them during clean-up.

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 17.1 KB
Line 
1#! /bin/sh
2# Oracle VM VirtualBox
3# Linux kernel module init script
4
5#
6# Copyright (C) 2006-2015 Oracle Corporation
7#
8# This file is part of VirtualBox Open Source Edition (OSE), as
9# available from http://www.virtualbox.org. This file is free software;
10# you can redistribute it and/or modify it under the terms of the GNU
11# General Public License (GPL) as published by the Free Software
12# Foundation, in version 2 as it comes in the "COPYING" file of the
13# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15#
16
17# chkconfig: 345 20 80
18# description: VirtualBox Linux kernel module
19#
20### BEGIN INIT INFO
21# Provides: vboxdrv
22# Required-Start: $syslog
23# Required-Stop:
24# Default-Start: 2 3 4 5
25# Default-Stop: 0 1 6
26# Short-Description: VirtualBox Linux kernel module
27### END INIT INFO
28
29## @todo This file duplicates a lot of script with vboxadd.sh. When making
30# changes please try to reduce differences between the two wherever possible.
31
32## @todo Remove the stop_vms target so that this script is only relevant to
33# kernel modules. Nice but not urgent.
34
35PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
36DEVICE=/dev/vboxdrv
37LOG="/var/log/vbox-install.log"
38MODPROBE=/sbin/modprobe
39SCRIPTNAME=vboxdrv.sh
40
41# The below is GNU-specific. See VBox.sh for the longer Solaris/OS X version.
42TARGET=`readlink -e -- "${0}"` || exit 1
43SCRIPT_DIR="${TARGET%/[!/]*}"
44
45if $MODPROBE -c | grep -q '^allow_unsupported_modules *0'; then
46 MODPROBE="$MODPROBE --allow-unsupported-modules"
47fi
48
49[ -f /etc/vbox/vbox.cfg ] && . /etc/vbox/vbox.cfg
50export BUILD_TYPE
51export USERNAME
52export USER=$USERNAME
53
54if test -n "${INSTALL_DIR}" && test -x "${INSTALL_DIR}/VirtualBox"; then
55 MODULE_SRC="${INSTALL_DIR}/src/vboxhost"
56elif test -x /usr/lib/virtualbox/VirtualBox; then
57 INSTALL_DIR=/usr/lib/virtualbox
58 MODULE_SRC="/usr/share/virtualbox/src/vboxhost"
59elif test -x "${SCRIPT_DIR}/VirtualBox"; then
60 # Executing from the build directory
61 INSTALL_DIR="${SCRIPT_DIR}"
62 MODULE_SRC="${INSTALL_DIR}/src"
63else
64 # Silently exit if the package was uninstalled but not purged.
65 # Applies to Debian packages only (but shouldn't hurt elsewhere)
66 exit 0
67fi
68VIRTUALBOX="${INSTALL_DIR}/VirtualBox"
69VBOXMANAGE="${INSTALL_DIR}/VBoxManage"
70BUILDINTMP="${MODULE_SRC}/build_in_tmp"
71if test -u "${VIRTUALBOX}"; then
72 GROUP=root
73 DEVICE_MODE=0600
74else
75 GROUP=vboxusers
76 DEVICE_MODE=0660
77fi
78
79[ -r /etc/default/virtualbox ] && . /etc/default/virtualbox
80
81# Preamble for Gentoo
82if [ "`which $0`" = "/sbin/rc" ]; then
83 shift
84fi
85
86begin_msg()
87{
88 test -n "${2}" && echo "${SCRIPTNAME}: ${1}."
89 logger -t "${SCRIPTNAME}" "${1}."
90}
91
92succ_msg()
93{
94 logger -t "${SCRIPTNAME}" "${1}."
95}
96
97fail_msg()
98{
99 echo "${SCRIPTNAME}: failed: ${1}." >&2
100 logger -t "${SCRIPTNAME}" "failed: ${1}."
101}
102
103failure()
104{
105 fail_msg "$1"
106 exit 1
107}
108
109running()
110{
111 lsmod | grep -q "$1[^_-]"
112}
113
114## Output the vboxdrv part of our udev rule. This is redirected to the right file.
115udev_write_vboxdrv() {
116 VBOXDRV_GRP="$1"
117 VBOXDRV_MODE="$2"
118
119 echo "KERNEL==\"vboxdrv\", NAME=\"vboxdrv\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"$VBOXDRV_MODE\""
120 echo "KERNEL==\"vboxdrvu\", NAME=\"vboxdrvu\", OWNER=\"root\", GROUP=\"root\", MODE=\"0666\""
121 echo "KERNEL==\"vboxnetctl\", NAME=\"vboxnetctl\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"$VBOXDRV_MODE\""
122}
123
124## Output the USB part of our udev rule. This is redirected to the right file.
125udev_write_usb() {
126 INSTALLATION_DIR="$1"
127 USB_GROUP="$2"
128
129 echo "SUBSYSTEM==\"usb_device\", ACTION==\"add\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}${USB_GROUP}\""
130 echo "SUBSYSTEM==\"usb\", ACTION==\"add\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}${USB_GROUP}\""
131 echo "SUBSYSTEM==\"usb_device\", ACTION==\"remove\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\""
132 echo "SUBSYSTEM==\"usb\", ACTION==\"remove\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\""
133}
134
135## Generate our udev rule file. This takes a change in udev rule syntax in
136## version 55 into account. It only creates rules for USB for udev versions
137## recent enough to support USB device nodes.
138generate_udev_rule() {
139 VBOXDRV_GRP="$1" # The group owning the vboxdrv device
140 VBOXDRV_MODE="$2" # The access mode for the vboxdrv device
141 INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
142 USB_GROUP="$4" # The group that has permission to access USB devices
143 NO_INSTALL="$5" # Set this to "1" to remove but not re-install rules
144
145 # Extra space!
146 case "$USB_GROUP" in ?*) USB_GROUP=" $USB_GROUP" ;; esac
147 case "$NO_INSTALL" in "1") return ;; esac
148 udev_write_vboxdrv "$VBOXDRV_GRP" "$VBOXDRV_MODE"
149 udev_write_usb "$INSTALLATION_DIR" "$USB_GROUP"
150}
151
152## Install udev rule (disable with INSTALL_NO_UDEV=1 in
153## /etc/default/virtualbox).
154install_udev() {
155 VBOXDRV_GRP="$1" # The group owning the vboxdrv device
156 VBOXDRV_MODE="$2" # The access mode for the vboxdrv device
157 INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
158 USB_GROUP="$4" # The group that has permission to access USB devices
159 NO_INSTALL="$5" # Set this to "1" to remove but not re-install rules
160
161 if test -d /etc/udev/rules.d; then
162 generate_udev_rule "$VBOXDRV_GRP" "$VBOXDRV_MODE" "$INSTALLATION_DIR" \
163 "$USB_GROUP" "$NO_INSTALL"
164 fi
165 # Remove old udev description file
166 rm -f /etc/udev/rules.d/10-vboxdrv.rules 2> /dev/null
167}
168
169## Create a usb device node for a given sysfs path to a USB device.
170install_create_usb_node_for_sysfs() {
171 path="$1" # sysfs path for the device
172 usb_createnode="$2" # Path to the USB device node creation script
173 usb_group="$3" # The group to give ownership of the node to
174 if test -r "${path}/dev"; then
175 dev="`cat "${path}/dev" 2> /dev/null`"
176 major="`expr "$dev" : '\(.*\):' 2> /dev/null`"
177 minor="`expr "$dev" : '.*:\(.*\)' 2> /dev/null`"
178 class="`cat ${path}/bDeviceClass 2> /dev/null`"
179 sh "${usb_createnode}" "$major" "$minor" "$class" \
180 "${usb_group}" 2>/dev/null
181 fi
182}
183
184udev_rule_file=/etc/udev/rules.d/60-vboxdrv.rules
185sysfs_usb_devices="/sys/bus/usb/devices/*"
186
187## Install udev rules and create device nodes for usb access
188setup_usb() {
189 VBOXDRV_GRP="$1" # The group that should own /dev/vboxdrv
190 VBOXDRV_MODE="$2" # The mode to be used for /dev/vboxdrv
191 INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
192 USB_GROUP="$4" # The group that should own the /dev/vboxusb device
193 # nodes unless INSTALL_NO_GROUP=1 in
194 # /etc/default/virtualbox. Optional.
195 usb_createnode="$INSTALLATION_DIR/VBoxCreateUSBNode.sh"
196 # install udev rule (disable with INSTALL_NO_UDEV=1 in
197 # /etc/default/virtualbox)
198 if [ "$INSTALL_NO_GROUP" != "1" ]; then
199 usb_group=$USB_GROUP
200 vboxdrv_group=$VBOXDRV_GRP
201 else
202 usb_group=root
203 vboxdrv_group=root
204 fi
205 install_udev "${vboxdrv_group}" "$VBOXDRV_MODE" \
206 "$INSTALLATION_DIR" "${usb_group}" \
207 "$INSTALL_NO_UDEV" > ${udev_rule_file}
208 # Build our device tree
209 for i in ${sysfs_usb_devices}; do # This line intentionally without quotes.
210 install_create_usb_node_for_sysfs "$i" "${usb_createnode}" \
211 "${usb_group}"
212 done
213}
214
215cleanup_usb()
216{
217 # Remove udev description file
218 rm -f /etc/udev/rules.d/60-vboxdrv.rules
219 rm -f /etc/udev/rules.d/10-vboxdrv.rules
220
221 # Remove our USB device tree
222 rm -rf /dev/vboxusb
223}
224
225start()
226{
227 begin_msg "Starting VirtualBox services" console
228 if [ -d /proc/xen ]; then
229 failure "Running VirtualBox in a Xen environment is not supported"
230 fi
231 if ! running vboxdrv; then
232 if ! rm -f $DEVICE; then
233 failure "Cannot remove $DEVICE"
234 fi
235 if ! $MODPROBE vboxdrv > /dev/null 2>&1; then
236 setup
237 if ! $MODPROBE vboxdrv > /dev/null 2>&1; then
238 failure "modprobe vboxdrv failed. Please use 'dmesg' to find out why"
239 fi
240 fi
241 sleep .2
242 fi
243 # ensure the character special exists
244 if [ ! -c $DEVICE ]; then
245 MAJOR=`sed -n 's;\([0-9]\+\) vboxdrv$;\1;p' /proc/devices`
246 if [ ! -z "$MAJOR" ]; then
247 MINOR=0
248 else
249 MINOR=`sed -n 's;\([0-9]\+\) vboxdrv$;\1;p' /proc/misc`
250 if [ ! -z "$MINOR" ]; then
251 MAJOR=10
252 fi
253 fi
254 if [ -z "$MAJOR" ]; then
255 rmmod vboxdrv 2>/dev/null
256 failure "Cannot locate the VirtualBox device"
257 fi
258 if ! mknod -m 0660 $DEVICE c $MAJOR $MINOR 2>/dev/null; then
259 rmmod vboxdrv 2>/dev/null
260 failure "Cannot create device $DEVICE with major $MAJOR and minor $MINOR"
261 fi
262 fi
263 # ensure permissions
264 if ! chown :"${GROUP}" $DEVICE 2>/dev/null; then
265 rmmod vboxpci 2>/dev/null
266 rmmod vboxnetadp 2>/dev/null
267 rmmod vboxnetflt 2>/dev/null
268 rmmod vboxdrv 2>/dev/null
269 failure "Cannot change group ${GROUP} for device $DEVICE"
270 fi
271 if ! $MODPROBE vboxnetflt > /dev/null 2>&1; then
272 failure "modprobe vboxnetflt failed. Please use 'dmesg' to find out why"
273 fi
274 if ! $MODPROBE vboxnetadp > /dev/null 2>&1; then
275 failure "modprobe vboxnetadp failed. Please use 'dmesg' to find out why"
276 fi
277 if ! $MODPROBE vboxpci > /dev/null 2>&1; then
278 failure "modprobe vboxpci failed. Please use 'dmesg' to find out why"
279 fi
280 # Create the /dev/vboxusb directory if the host supports that method
281 # of USB access. The USB code checks for the existance of that path.
282 if grep -q usb_device /proc/devices; then
283 mkdir -p -m 0750 /dev/vboxusb 2>/dev/null
284 chown root:vboxusers /dev/vboxusb 2>/dev/null
285 fi
286 # Remove any kernel modules left over from previously installed kernels.
287 cleanup only_old
288 succ_msg "VirtualBox services started"
289}
290
291stop()
292{
293 begin_msg "Stopping VirtualBox services" console
294
295 if running vboxpci; then
296 if ! rmmod vboxpci 2>/dev/null; then
297 failure "Cannot unload module vboxpci"
298 fi
299 fi
300 if running vboxnetadp; then
301 if ! rmmod vboxnetadp 2>/dev/null; then
302 failure "Cannot unload module vboxnetadp"
303 fi
304 fi
305 if running vboxdrv; then
306 if running vboxnetflt; then
307 if ! rmmod vboxnetflt 2>/dev/null; then
308 failure "Cannot unload module vboxnetflt"
309 fi
310 fi
311 if ! rmmod vboxdrv 2>/dev/null; then
312 failure "Cannot unload module vboxdrv"
313 fi
314 if ! rm -f $DEVICE; then
315 failure "Cannot unlink $DEVICE"
316 fi
317 fi
318 succ_msg "VirtualBox services stopped"
319}
320
321# enter the following variables in /etc/default/virtualbox:
322# SHUTDOWN_USERS="foo bar"
323# check for running VMs of user foo and user bar
324# SHUTDOWN=poweroff
325# SHUTDOWN=acpibutton
326# SHUTDOWN=savestate
327# select one of these shutdown methods for running VMs
328stop_vms()
329{
330 wait=0
331 for i in $SHUTDOWN_USERS; do
332 # don't create the ipcd directory with wrong permissions!
333 if [ -d /tmp/.vbox-$i-ipc ]; then
334 export VBOX_IPC_SOCKETID="$i"
335 VMS=`$VBOXMANAGE --nologo list runningvms | sed -e 's/^".*".*{\(.*\)}/\1/' 2>/dev/null`
336 if [ -n "$VMS" ]; then
337 if [ "$SHUTDOWN" = "poweroff" ]; then
338 begin_msg "Powering off remaining VMs"
339 for v in $VMS; do
340 $VBOXMANAGE --nologo controlvm $v poweroff
341 done
342 succ_msg "Remaining VMs powered off"
343 elif [ "$SHUTDOWN" = "acpibutton" ]; then
344 begin_msg "Sending ACPI power button event to remaining VMs"
345 for v in $VMS; do
346 $VBOXMANAGE --nologo controlvm $v acpipowerbutton
347 wait=30
348 done
349 succ_msg "ACPI power button event sent to remaining VMs"
350 elif [ "$SHUTDOWN" = "savestate" ]; then
351 begin_msg "Saving state of remaining VMs"
352 for v in $VMS; do
353 $VBOXMANAGE --nologo controlvm $v savestate
354 done
355 succ_msg "State of remaining VMs saved"
356 fi
357 fi
358 fi
359 done
360 # wait for some seconds when doing ACPI shutdown
361 if [ "$wait" -ne 0 ]; then
362 begin_msg "Waiting for $wait seconds for VM shutdown"
363 sleep $wait
364 succ_msg "Waited for $wait seconds for VM shutdown"
365 fi
366}
367
368cleanup()
369{
370 # If this is set, only remove kernel modules for no longer installed
371 # kernels. Note that only generated kernel modules should be placed
372 # in /lib/modules/*/misc. Anything that we should not remove automatically
373 # should go elsewhere.
374 only_old="${1}"
375 for i in /lib/modules/*; do
376 # Check whether we are only cleaning up for uninstalled kernels.
377 test -n "${only_old}" && test -e "${i}/kernel/drivers" && continue
378 # We could just do "rm -f", but we only want to try deleting folders if
379 # we are sure they were ours, i.e. they had our modules in beforehand.
380 if test -e "${i}/misc/vboxdrv.ko" \
381 || test -e "${i}/misc/vboxnetadp.ko" \
382 || test -e "${i}/misc/vboxnetflt.ko" \
383 || test -e "${i}/misc/vboxpci.ko"; then
384 rm -f "${i}/misc/vboxdrv.ko" "${i}/misc/vboxnetadp.ko" \
385 "${i}/misc/vboxnetflt.ko" "${i}/misc/vboxpci.ko"
386 version=`expr "${i}" : "/lib/modules/\(.*\)"`
387 depmod -a "${version}"
388 fi
389 # Remove the kernel version folder if it was empty except for us.
390 test "`echo ${i}/misc/* ${i}/misc/.?* ${i}/* ${i}/.?*`" \
391 = "${i}/misc/* ${i}/misc/.. ${i}/misc ${i}/.." &&
392 rmdir "${i}/misc" "${i}" # We used to leave empty folders.
393 done
394}
395
396# setup_script
397setup()
398{
399 begin_msg "Building VirtualBox kernel modules" console
400 if ! $BUILDINTMP \
401 --save-module-symvers /tmp/vboxdrv-Module.symvers \
402 --module-source "$MODULE_SRC/vboxdrv" \
403 --no-print-directory install >> $LOG 2>&1; then
404 "${INSTALL_DIR}/check_module_dependencies.sh" || exit 1
405 failure "Look at $LOG to find out what went wrong"
406 fi
407 if ! $BUILDINTMP \
408 --use-module-symvers /tmp/vboxdrv-Module.symvers \
409 --module-source "$MODULE_SRC/vboxnetflt" \
410 --no-print-directory install >> $LOG 2>&1; then
411 failure "Look at $LOG to find out what went wrong"
412 fi
413 if ! $BUILDINTMP \
414 --use-module-symvers /tmp/vboxdrv-Module.symvers \
415 --module-source "$MODULE_SRC/vboxnetadp" \
416 --no-print-directory install >> $LOG 2>&1; then
417 failure "Look at $LOG to find out what went wrong"
418 fi
419 if ! $BUILDINTMP \
420 --use-module-symvers /tmp/vboxdrv-Module.symvers \
421 --module-source "$MODULE_SRC/vboxpci" \
422 --no-print-directory install >> $LOG 2>&1; then
423 failure "Look at $LOG to find out what went wrong"
424 fi
425 rm -f /etc/vbox/module_not_compiled
426 depmod -a
427 succ_msg "VirtualBox kernel modules built"
428}
429
430dmnstatus()
431{
432 if running vboxdrv; then
433 str="vboxdrv"
434 if running vboxnetflt; then
435 str="$str, vboxnetflt"
436 if running vboxnetadp; then
437 str="$str, vboxnetadp"
438 fi
439 fi
440 if running vboxpci; then
441 str="$str, vboxpci"
442 fi
443 echo "VirtualBox kernel modules ($str) are loaded."
444 for i in $SHUTDOWN_USERS; do
445 # don't create the ipcd directory with wrong permissions!
446 if [ -d /tmp/.vbox-$i-ipc ]; then
447 export VBOX_IPC_SOCKETID="$i"
448 VMS=`$VBOXMANAGE --nologo list runningvms | sed -e 's/^".*".*{\(.*\)}/\1/' 2>/dev/null`
449 if [ -n "$VMS" ]; then
450 echo "The following VMs are currently running:"
451 for v in $VMS; do
452 echo " $v"
453 done
454 fi
455 fi
456 done
457 else
458 echo "VirtualBox kernel module is not loaded."
459 fi
460}
461
462case "$1" in
463start)
464 start
465 ;;
466stop)
467 stop_vms
468 stop
469 ;;
470stop_vms)
471 stop_vms
472 ;;
473restart)
474 stop && start
475 ;;
476setup)
477 # Create udev rule and USB device nodes.
478 ## todo Wouldn't it make more sense to install the rule to /lib/udev? This
479 ## is not a user-created configuration file after all.
480 ## todo Do we need a udev rule to create /dev/vboxdrv[u] at all? We have
481 ## working fall-back code here anyway, and the "right" code is more complex
482 ## than the fall-back. Unnecessary duplication?
483 stop && cleanup
484 setup_usb "$GROUP" "$DEVICE_MODE" "$INSTALL_DIR"
485 setup && start
486 ;;
487cleanup)
488 stop && cleanup
489 cleanup_usb
490 ;;
491force-reload)
492 stop
493 start
494 ;;
495status)
496 dmnstatus
497 ;;
498*)
499 echo "Usage: $0 {start|stop|stop_vms|restart|force-reload|status}"
500 exit 1
501esac
502
503exit 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