VirtualBox

Changeset 98476 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 3, 2023 7:36:11 PM (23 months ago)
Author:
vboxsync
Message:

Additions: Linux: rcvboxadd: Introduce 'reload' action, bugref:10359.

This commit makes rcvboxadd script to reload Guest Additions kernel modules
and user services without requiring guest reboot.

In addition, it allows to bypass forced kernel modules signature validation
if /etc/virtualbox-guest-additions.conf (needs to be created manually) contains:

VBOX_BYPASS_MODULES_SIGNATURE_CHECK="1"

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/installer/vboxadd.sh

    r98103 r98476  
    147147userdev=/dev/vboxuser
    148148config=/var/lib/VBoxGuestAdditions/config
     149user_config=/etc/virtualbox-guest-additions.conf
    149150owner=vboxadd
    150151group=1
     152
     153# Include custom user configuration file.
     154[ -r "$user_config" ] && . "$user_config"
    151155
    152156if test -r $config; then
     
    185189{
    186190    lsmod | grep -q "vboxvideo[^_-]"
     191}
     192
     193# Get version string of currently running kernel module.
     194running_module_version()
     195{
     196    mod=$1
     197    version_string_path="/sys/module/"$mod"/version"
     198
     199    [ -n "$mod" ] || return
     200    [ -r "$version_string_path" ] || return
     201
     202    cat "$version_string_path"
     203}
     204
     205# Check if currently loaded kernel module version matches to
     206# current Guest Additions installed version and revision.
     207check_running_module_version()
     208{
     209    mod=$1
     210    expected="$VBOX_VERSION $VBOX_REVISION"
     211
     212    [ -n "$mod" ] || return
     213    [ -n "$expected" ] || return
     214
     215    [ "$expected" = "$(running_module_version "$mod")" ] || return
    187216}
    188217
     
    644673    [ -n "$mod" ] || return
    645674
     675    # Be nice with distributions which do not provide tools which we
     676    # use in order to verify module signature. This variable needs to
     677    # be explicitly set by administrator. This script will look for it
     678    # in /etc/virtualbox-guest-additions.conf. Make sure that you know
     679    # what you do!
     680    if [ "$VBOX_BYPASS_MODULES_SIGNATURE_CHECK" = "1" ]; then
     681        echo "1"
     682        return
     683    fi
     684
    646685    extraction_tool=/lib/modules/"$(uname -r)"/build/scripts/extract-module-sig.pl
    647686    mod_path=$(module_path "$mod" 2>/dev/null)
     
    770809
    771810    if  running_vboxguest || running_vboxadd; then
    772         info "Running kernel modules will not be replaced until the system is restarted"
     811        # Only warn user if currently loaded modules version do not match Guest Additions Installation.
     812        check_running_module_version "vboxguest" || info "Running kernel modules will not be replaced until the system is restarted or 'rcvboxadd reload' triggered"
    773813    fi
    774814
     
    815855    # Check if kernel modules for currently running kernel are ready
    816856    # and rebuild them if needed.
    817     setup
     857    test "$(setup_complete)" = "1" || setup
    818858
    819859    # Warn if Secure Boot setup not yet complete.
     
    878918    fi
    879919    test -n "${INSTALL_NO_MODULE_BUILDS}" ||
    880         info "You may need to restart your guest system to finish removing guest drivers."
     920        info "You may need to restart your guest system to finish removing guest drivers or consider running 'rcvboxadd reload'."
    881921    return 0
     922}
     923
     924# Checks if systemctl is present and functional (i.e., systemd is the init process).
     925use_systemd()
     926{
     927    systemctl status >/dev/null 2>&1
     928}
     929
     930## Did we install a systemd service?
     931systemd_service_installed()
     932{
     933    ## Name of service to test.
     934    name="${1}"
     935
     936    test -f /lib/systemd/system/"${name}".service ||
     937        test -f /usr/lib/systemd/system/"${name}".service
     938}
     939
     940## Perform an action on a service
     941do_sysvinit_action()
     942{
     943    ## Name of service to start.
     944    name="${1}"
     945    ## The action to perform, normally "start", "stop" or "status".
     946    action="${2}"
     947
     948    if use_systemd -a systemd_service_installed "${name}"; then
     949        systemctl -q ${action} "${name}"
     950    elif test -x "/etc/rc.d/init.d/${name}"; then
     951        "/etc/rc.d/init.d/${name}" "${action}" quiet
     952    elif test -x "/etc/init.d/${name}"; then
     953        "/etc/init.d/${name}" "${action}" quiet
     954    fi
     955}
     956
     957# Check if process with this PID is running.
     958check_pid()
     959{
     960    pid=$1
     961
     962    [ -d "/proc/$pid" ] && true
     963}
     964
     965send_sig_usr1_by_pidfile()
     966{
     967    pidfile=$1
     968
     969    if [ -f "$pidfile" ]; then
     970        check_pid $(cat "$pidfile")
     971        if [ $? -eq 0 ]; then
     972            kill -USR1 $(cat "$pidfile") >/dev/null 2>&1
     973        else
     974            # Do not spoil $?.
     975            true
     976        fi
     977    else
     978        # Do not spoil $?.
     979        true
     980    fi
     981}
     982
     983# SIGUSR1 is used in order to notify VBoxClient processes that system
     984# update is started or kernel modules are going to be reloaded,
     985# so VBoxClient can release vboxguest.ko resources and then restart itself.
     986send_sig_usr1()
     987{
     988    # Specify whether we sending signal to VBoxClient parent (control)
     989    # process or a child (actual service) process.
     990    process_type="$1"
     991
     992    pidfile_postfix=""
     993    [ -z "$process_type" ] || pidfile_postfix="-$process_type"
     994
     995    for user_home in $(getent passwd | cut -d ':' -f 6); do
     996        if [ -d "$user_home" ]; then
     997
     998            for pid_file in "$user_home"/.vboxclient-*"$pidfile_postfix".pid; do
     999
     1000                # If process type was not specified, we assume that signal supposed
     1001                # to be sent to legacy VBoxClient processes which have different
     1002                # pidfile name pattern (it does not contain "control" or "service").
     1003                # Skip those pidfiles who has.
     1004                [ -z "$process_type" -a -n "$(echo "$pid_file" | grep "control")" ] && continue
     1005                [ -z "$process_type" -a -n "$(echo "$pid_file" | grep "service")" ] && continue
     1006
     1007                send_sig_usr1_by_pidfile "$pid_file"
     1008            done
     1009
     1010        fi
     1011    done
     1012}
     1013
     1014reload()
     1015{
     1016    begin "reloading kernel modules and services"
     1017
     1018    # Check if script was started with root privileges.
     1019    [ `id -u` -eq 0 ] || fail "root privileges are required"
     1020
     1021    # Check if modules were previously build.
     1022    [ "$(setup_complete)" = "1" ] || fail "kernel modules were set up yet, please consider running 'rcvboxadd setup' first."
     1023
     1024    # Stop VBoxService (systemctl stop vboxadd-service.service).
     1025    do_sysvinit_action vboxadd-service stop >/dev/null 2>&1
     1026
     1027    # Unmount Shared Folders.
     1028    [ $? -eq 0 ] && umount -a -t vboxsf >/dev/null 2>&1
     1029
     1030    # Stop VBoxDRMClient.
     1031    [ $? -eq 0 ] && send_sig_usr1_by_pidfile "/var/run/VBoxDRMClient"
     1032
     1033    if [ $? -eq 0 ]; then
     1034        # Tell legacy VBoxClient processes to release vboxguest.ko references.
     1035        send_sig_usr1 ""
     1036
     1037        # Tell compatible VBoxClient processes to release vboxguest.ko references.
     1038        send_sig_usr1 "service"
     1039
     1040        # Try unload.
     1041        for attempt in 1 2 3 4 5; do
     1042
     1043            # Give VBoxClient processes some time to close reference to vboxguest module.
     1044            [ $? -ne 0 ] && sleep 1
     1045
     1046            # Try unload drivers unconditionally (ignore previous command exit code).
     1047            # If final goal of unloading vboxguest.ko won't be met, we will fail on
     1048            # the next step anyway.
     1049            running_vboxvideo && modprobe -r vboxvideo >/dev/null  2>&1
     1050            running_vboxsf && modprobe -r vboxsf >/dev/null  2>&1
     1051            running_vboxguest
     1052            if [ $? -eq 0 ]; then
     1053                modprobe -r vboxguest >/dev/null  2>&1
     1054            else
     1055                # Do not spoil $?.
     1056                true
     1057            fi
     1058        done
     1059
     1060        # Check if we succeeded with unloading vboxguest after several attempts.
     1061        running_vboxguest
     1062        if [ $? -eq 0 ]; then
     1063            fail "Cannot reload kernel modules: one or more module(s) is still in use"
     1064        else
     1065            # Do not spoil $?.
     1066            true
     1067        fi
     1068
     1069        # Load drivers (skip vboxvideo since it is not loaded for very old guests).
     1070        [ $? -eq 0 ] && modprobe vboxguest >/dev/null 2>&1
     1071        [ $? -eq 0 ] && modprobe vboxsf >/dev/null 2>&1
     1072
     1073        # Start VBoxService and VBoxDRMClient (systemctl start vboxadd-service.service).
     1074        [ $? -eq 0 ] && do_sysvinit_action vboxadd-service start >/dev/null 2>&1
     1075
     1076        # Reload VBoxClient processes.
     1077        [ $? -eq 0 ] && send_sig_usr1 "control"
     1078    fi
     1079
     1080    if [ $? -eq 0 ]; then
     1081
     1082        # Check if we just loaded modules of correct version. Skip vboxvideo
     1083        # since it's not loaded for very old guests.
     1084        for mod in vboxguest vboxsf; do
     1085            check_running_module_version "$mod" || fail "currently loaded module $mod version ($(running_module_version "$mod") does not match to VirtualBox Guest Additions installation version ($VBOX_VERSION $VBOX_REVISION))"
     1086        done
     1087        # Take reported version of running Guest Additions from running vboxguest module (as a paranoia check).
     1088        info "kernel modules and services $(running_module_version "vboxguest") reloaded"
     1089        info "NOTE: you may still consider to re-login if some user session specific services (Shared Clipboard, Drag and Drop, Seamless or Guest Screen Resize) were not restarted automatically"
     1090    else
     1091        fail "cannot reload kernel modules and restart services"
     1092    fi
    8821093}
    8831094
     
    9081119restart)
    9091120    restart
     1121    ;;
     1122# Tries to reload kernel modules and restart user processes.
     1123reload)
     1124    reload
    9101125    ;;
    9111126# Setup does a clean-up (see below) and re-does all Additions-specific
     
    9381153    ;;
    9391154*)
    940     echo "Usage: $0 {start|stop|restart|status|setup|quicksetup|cleanup} [quiet]"
     1155    echo "Usage: $0 {start|stop|restart|reload|status|setup|quicksetup|cleanup} [quiet]"
    9411156    exit 1
    9421157esac
Note: See TracChangeset for help on using the changeset viewer.

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