Subversion Repositories configs

Rev

Blame | Last modification | View Log | RSS feed

#!/usr/bin/env bash
#
# Copyright 1998-2020 VMware, Inc.  All rights reserved.
#
# This script manages the services needed to run VMware software.
#

# Basic support for IRIX style chkconfig
# chkconfig: 235 19 8
# description: This service starts and stops VMware services


ETCDIR=/etc/vmware

. $ETCDIR/bootstrap
libdir="$LIBDIR"/vmware

. "$libdir"/scripts/util.sh

load_settings "$libdir" || exit 1

VNETLIB_LOG=/var/log/vnetlib
PRODUCT_NAME="vmware-vmx"
COMPONENT_NAME="vmware-vmx"

# This comment is a hack to prevent RedHat distributions from outputing
# "Starting <basename of this script>" when running this startup script.
# We just need to write the word daemon followed by a space

# This defines echo_success() and echo_failure() on RedHat
if [ -r "$INITSCRIPTDIR"'/functions' ]; then
   . "$INITSCRIPTDIR"'/functions'
fi

# This defines $rc_done and $rc_failed on S.u.S.E.
if [ -f /etc/rc.config ]; then
   # Don't include the entire file: there could be conflicts
   rc_done=`(. /etc/rc.config; echo "$rc_done")`
   rc_failed=`(. /etc/rc.config; echo "$rc_failed")`
else
   # Make sure the ESC byte is literal: Ash does not support echo -e
   rc_done=' done'
   rc_failed='failed'
fi

subsys=vmware
driver=vmmon
vnet=vmnet
vmci=vmci
vmci_alias='pci:v000015ADd00000740sv*sd*bc*sc*i*'
vmhgfs=vmhgfs
vsock=vsock
vsock_alias=vmware_vsock

# SHM settings
shmmaxPath=/proc/sys/kernel/shmmax
shmmaxMinValue=268435456 # 256MB

#
# Are we running in a VM?
#
vmwareInVM() {
   "$BINDIR"/checkvm >/dev/null 2>&1
}

#
# Report a positive number if there are any VMs running.
# May not be the actual vmmon reference count.
#
vmmonUseCount() {
   local count
   # Beware of module dependencies here. An exact match is important
   count=`/sbin/lsmod | awk 'BEGIN {n = 0} {if ($1 == "'"$driver"'") n = $3} END {print n}'`
   # If CONFIG_MODULE_UNLOAD is not set in the kernel, lsmod prints '-' instead of the
   # reference count, so ask vmrun, or if we don't have vmrun, look for running vmx processes
   if [ x${count} = "x-" ]
   then
      type vmrun > /dev/null 2>&1
      if [ $? -eq 0 ]
      then
         count=`vmrun list | awk 'BEGIN {n=0} /^Total running VMs:/ {n = $4} END {print n}'`
      else
         count=`ps -afe | grep "/bin/vmware-vmx" | grep -v grep | wc -l`
      fi
   fi
   echo $count
}

# Is a given module loaded?
isLoaded() {
   local module="$1"

   /sbin/lsmod | awk 'BEGIN {n = "no";} {if ($1 == "'"$module"'") n = "yes";} END {print n;}'
}

vmwareLoadModule() {
   /sbin/modprobe "$1" || exit 1
}

vmwareUnloadModule() {
   [ "`isLoaded "$1"`" = 'no' ] && return 0
   # if we ran depmod after removing the modules modprobe -r will not work:
   /sbin/modprobe -r "$1" || /sbin/rmmod $1 || exit 1
}

# Start the virtual machine monitor kernel service
vmwareStartVmmon() {
   vmwareLoadModule $driver
}

# Stop the virtual machine monitor kernel service
vmwareStopVmmon() {
   vmwareUnloadModule $driver
}

# Start the virtual ethernet kernel service
vmwareStartVmnet() {
   vmwareLoadModule $vnet
   "$BINDIR"/vmware-networks --start >> $VNETLIB_LOG 2>&1
}

# Stop the virtual ethernet kernel service
vmwareStopVmnet() {
   "$BINDIR"/vmware-networks --stop >> $VNETLIB_LOG 2>&1
   vmwareUnloadModule $vnet
}

# Returns 0 if networking is enabled, otherwise 1
vmwareIsNetworkingEnabled() {
  [ "$vmdb_NETWORKING" = 'yes' ]
  return
}

vmwareRealModName() {
   # modprobe might be old and not understand the -R option, or
   # there might not be an alias. In both cases we assume
   # that the module is not upstreamed.
   mod=$1
   mod_alias=$2
   alias_file="/lib/modules/$(uname -r)/modules.alias"

   modname=$(/sbin/modprobe -R ${mod_alias} 2>/dev/null)
   if [ $? = 0 -a "$modname" != "" ] ; then
      echo $modname
   elif grep -F ${mod_alias} ${alias_file} >/dev/null 2>&1 ; then
      echo $(grep -F ${mod_alias} ${alias_file} | awk '{print $3}')
   else
      echo $mod
   fi
}

# Ensure the virtual machine communication interface kernel service is present.
vmwareProbeVmci() {
   mod=$(vmwareRealModName $vmci $vmci_alias)

   # only load vmci if it's not already loaded
   if [ "`isLoaded "$mod"`" = 'no' ]; then
      vmwareLoadModule "$mod"
   fi

   return 0
}

# Make sure the system has enough shared memory available to cover shmmaxMinValue.
vmwareCheckSharedMemory() {
   if [ -f "$shmmaxPath" ]; then
      shmmax=`cat $shmmaxPath`
      # If the following arithmetic evaluation overflows, shmmax will certainly
      # be high enough for our needs.
      if [ "$shmmax" == $((shmmax)) ] ; then
         if [ "$shmmax" -lt "$shmmaxMinValue" ] ; then
            echo ""
            echo "Setting the max shared memory the system will allow to $shmmaxMinValue."
            echo ""
            echo "$shmmaxMinValue" > "$shmmaxPath"
         fi
      fi
   fi
   return 0
}


# Probe after vmci is loaded
vmwareProbeVsock() {
   mod=$(vmwareRealModName $vsock $vsock_alias)
   # only load vsock if it's not already loaded
   if [ "`isLoaded "$mod"`" = 'no' ]; then
      vmwareLoadModule "$mod"
   fi

   return 0
}

vmware_start_authdlauncher() {
   vmware_bg_exec "`vmware_product_name` Authentication Daemon" \
      "$SBINDIR/vmware-authdlauncher"
}

vmware_stop_authdlauncher() {
   local launcherpid=`pidof vmware-authdlauncher`
   if [ -n "$launcherpid" ]; then
      vmware_synchrone_kill $launcherpid "TERM"
   fi
}

vmwareService() {
   case "$1" in
      start)
         if vmwareInVM; then
            # Refuse to start services in a VM: they are useless
            exit 1
         fi

         echo 'Starting VMware services:'
         exitcode='0'

         vmware_exec 'Virtual machine monitor' vmwareStartVmmon
         exitcode=$(($exitcode + $?))

         vmware_exec 'Virtual machine communication interface' vmwareProbeVmci
         exitcode=$(($exitcode + $?))

         # vsock needs vmci started first
         vmware_exec 'VM communication interface socket family' vmwareProbeVsock
         # a vsock failure to load shouldn't cause the init to fail completely.

         if [ "`is_vmblock_needed`" = 'yes' ] ; then
            vmware_exec 'Blocking file system' vmware_start_vmblock
            exitcode=$(($exitcode + $?))
         fi

         # Try to load parport_pc.
         /sbin/modprobe parport_pc >/dev/null 2>&1

         if vmwareIsNetworkingEnabled; then
            vmware_exec 'Virtual ethernet' vmwareStartVmnet
            exitcode=$(($exitcode + $?))
         fi

         vmware_exec 'VMware Authentication Daemon' vmware_start_authdlauncher

         if [ "$exitcode" -gt 0 ]; then
            exit 1
         fi

         [ -d /var/lock/subsys ] || mkdir -p /var/lock/subsys
         touch /var/lock/subsys/"$subsys"

         vmware_exec "Shared Memory Available"  vmwareCheckSharedMemory
      ;;

      stop)
         echo 'Stopping VMware services:'
         exitcode='0'

         vmware_exec 'VMware Authentication Daemon' vmware_stop_authdlauncher

         # If the 'K' version of this script is running, the system is
         # stoping services not because the user is running vmware-config.pl
         # or running the initscript directly but because the user wants to
         # shutdown.  Suspend all VMs.
         if [ "`echo $BASENAME | sed -ne '/^K[0-9].vmware/p'`" ] ; then
            if [ -x "$BINDIR"/vmrun ] ; then
               for i in `pidof vmware-vmx` ; do
                  "$BINDIR"/vmrun suspend `ps -p $i -f | \
                       sed -ne '/vmware/s/.* \(\/.*\.vmx\)/\1/p'` 2> /dev/null
               done
            fi

         fi

         if [ "`vmmonUseCount`" -gt 0 ]; then
            echo 'At least one instance of '"$PRODUCT_NAME"' is still running.' 1>&2
            echo 'Please stop all running instances of '"$PRODUCT_NAME"' first.' 1>&2
            echo " " >&2

            # Since we stopped authdlauncher to prevent new connections before disabling
            # any vmxs, need to restart it here to restore the environment back to
            # what it was before this init script ran.
            vmware_exec 'VMware Authentication Daemon' vmware_start_authdlauncher

            # The unconfigurator handle this exit code differently
            exit 2
         fi

         vmware_exec 'Virtual machine monitor' vmwareStopVmmon
         exitcode=$(($exitcode + $?))

         if [ "`is_vmblock_needed`" = 'yes' ] ; then
            vmware_exec 'Blocking file system' vmware_stop_vmblock
            exitcode=$(($exitcode + $?))
         fi

         # Try to unload parport_pc. Failure is allowed as it does not
         # exist on kernels 2.0, and some other process could be using
         # it.
         /sbin/modprobe -r parport_pc >/dev/null 2>&1

         if vmwareIsNetworkingEnabled; then
            vmwareStopVmnet
         fi

         # The vmware and vmware-tray processes don't terminate automatically
         # when the other services are shutdown.  They persist after calling
         # 'init.d/vmware stop' and will happily keep going through an init
         # start command, continuing to minimally function, blissfully ignorant.
         # Time for a buzzkill.
         for i in `pidof vmware vmware-tray` ; do
            vmware_synchrone_kill $i "INT"
         done

         if [ "$exitcode" -gt 0 ]; then
            exit 1
         fi

         rm -f /var/lock/subsys/"$subsys"
      ;;

      status)
         if [ "`vmmonUseCount`" -gt 0 ]; then
            echo 'At least one instance of '"$PRODUCT_NAME"' is still running.'
            echo
            if [ "$2" = "vmcount" ]; then
               exit 2
            fi
         fi
         if [ "$2" = "vmcount" ]; then
               exit 0
         fi

         exitcode='0'

         echo -n "Module $driver "
         [ "`isLoaded "$driver"`" = 'yes' ] && echo loaded || echo "not loaded"
         if vmwareIsNetworkingEnabled; then
            echo -n "Module $vnet "
            [ "`isLoaded "$vnet"`" = 'yes' ] && echo loaded || echo "not loaded"
         fi

         if [ "$exitcode" -gt 0 ]; then
            exit 1
         fi
      ;;

      restart)
         "$SCRIPTNAME" stop && "$SCRIPTNAME" start
      ;;

      # Called to make sure script is in a runnable state.
      validate)
         exit 100
      ;;

      stoppable)
         [ "`vmmonUseCount`" -lt 1 ]
         exit
      ;;

      *)
         echo "Usage: "$BASENAME" {start|stop|status|restart|stoppable}"
         exit 1
   esac
}

SCRIPTNAME="$0"
BASENAME=`basename "$SCRIPTNAME"`

# Check permissions
if [ "`id -ur`" != '0' ]; then
   echo 'Error: you must be root.'
   echo
   exit 1
fi

vmwareService "$1"

exit 0