VirtualBox

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

Last change on this file since 58271 was 58271, checked in by vboxsync, 9 years ago

Installer/linux (host): check the version and support driver version of currently installed kernel modules.

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