VirtualBox

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

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

bugref:8051: Installers: unify Linux host installers as far as possible: revert r103461: check the version and support driver version of currently installed kernel modules. We can get the same result for normal users with simpler code by always deleting old modules during installation. Developers can deal with making sure the right version is loaded.

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