On 07/21/2013 06:23 PM, Stephen P. Molnar wrote:
Stephen P. Molnar, Ph.D. Life is a fuzzy
set
Foundation for Chemistry Stochastic and
multivariate
www.FoundationForChemistry.com
(614)312-7528 (c)
Skype: smolnar1
-----Original Message-----
From: William Hopkins [mailto:we.hopk...@gmail.com]
Sent: Sunday, July 21, 2013 4:26 PM
To: debian-user@lists.debian.org
Subject: Re: Debian Testing VMWare-Tools Bad Variable Name
On 07/21/13 at 04:09pm, Stephen P. Molnar wrote:
In the case of Debian 7.1.0 the vmware tools installed without any
problems.
Unfortunately, this was not the case with Debian Testing. the tools
installed without any problems, but when the installer ran
/usr/bin/ware/vmware.config.tools.pl there were errors:
Starting VMware Tools services in the virtual machine:
Switching to guest configuration:[71G done
/etc/init.d/vmware-tools: 1090: local: ': bad variable name
/etc/init.d/vmware-tools: 1090: local: ': bad variable name
Blocking file system:[71Gfailed
/etc/init.d/vmware-tools: 1187: local: ': bad variable name
Guest operating system daemon:[71G done Unable to start services
for VMware Tools
The lines in question are:
1090 local run_kver=`get_version_integer`
and
1187 local run_kver=`get_version_integer`
Can you provide the vmware.config.tools.pl from your system?
Can you `type get_version_integer`? if it's referenced in that script, can
you provide it also? Sounds like an unescaped quote in one of these scripts,
might have to identify the maintainer and bugreport upstream.
Also, didn't you post this recently, with a longer log? Is this the same
issue?
--
William
Thanks for your reply. Yes, I did post this earlier, but, in my haste,
I missed some messages from the installer.
computation@inga:~$ type get_version_integer
bash: type: get_version_integer: not found
I've attached the file.
I really appreciate your assistance.
Again, thanks in advance.
#!/bin/sh
#
# Copyright (c) 1998-2013 VMware, Inc. All rights reserved.
#
# This script manages the services needed to run VMware software
### BEGIN INIT INFO
# Provides: vmware-tools
# Required-Start: $local_fs
# Required-Stop: $local_fs
# X-Start-Before: $network
# X-Stop-After: $network
# Default-Start: S
# Default-Stop: 0 6
# Short-Description: VMware Tools service
# Description: Manages the services needed to run VMware Tools
### END INIT INFO
# BEGINNING_OF_UTIL_DOT_SH
#!/bin/sh
#
# Copyright (c) 2005-2013 VMware, Inc. All rights reserved.
#
# A few utility functions used by our shell scripts. Some expect the settings
# database to already be loaded and evaluated.
vmblockmntpt="/proc/fs/vmblock/mountPoint"
vmblockfusemntpt="/var/run/vmblock-fuse"
vmware_failed() {
if [ "`type -t 'echo_failure' 2>/dev/null`" = 'function' ]; then
echo_failure
else
echo -n "$rc_failed"
fi
}
vmware_success() {
if [ "`type -t 'echo_success' 2>/dev/null`" = 'function' ]; then
echo_success
else
echo -n "$rc_done"
fi
}
# Execute a macro
vmware_exec() {
local msg="$1" # IN
local func="$2" # IN
shift 2
echo -n ' '"$msg"
# On Caldera 2.2, SIGHUP is sent to all our children when this script exits
# I wanted to use shopt -u huponexit instead but their bash version
# 1.14.7(1) is too old
#
# Ksh does not recognize the SIG prefix in front of a signal name
if [ "$VMWARE_DEBUG" = 'yes' ]; then
(trap '' HUP; "$func" "$@")
else
(trap '' HUP; "$func" "$@") >/dev/null 2>&1
fi
if [ "$?" -gt 0 ]; then
vmware_failed
echo
return 1
fi
vmware_success
echo
return 0
}
# Execute a macro in the background
vmware_bg_exec() {
local msg="$1" # IN
local func="$2" # IN
shift 2
if [ "$VMWARE_DEBUG" = 'yes' ]; then
# Force synchronism when debugging
vmware_exec "$msg" "$func" "$@"
else
echo -n ' '"$msg"' (background)'
# On Caldera 2.2, SIGHUP is sent to all our children when this script exits
# I wanted to use shopt -u huponexit instead but their bash version
# 1.14.7(1) is too old
#
# Ksh does not recognize the SIG prefix in front of a signal name
(trap '' HUP; "$func" "$@") 2>&1 | logger -t 'VMware[init]' -p daemon.err &
vmware_success
echo
return 0
fi
}
# This is a function in case a future product name contains language-specific
# escape characters.
vmware_product_name() {
echo 'VMware Tools'
exit 0
}
# This is a function in case a future product contains language-specific
# escape characters.
vmware_product() {
echo 'tools-for-linux'
exit 0
}
is_dsp()
{
# This is the current way of indicating it is part of a
# distribution-specific install. Currently only applies to Tools.
[ -e "$vmdb_answer_LIBDIR"/dsp ]
}
# They are a lot of small utility programs to create temporary files in a
# secure way, but none of them is standard. So I wrote this
make_tmp_dir() {
local dirname="$1" # OUT
local prefix="$2" # IN
local tmp
local serial
local loop
tmp="${TMPDIR:-/tmp}"
# Don't overwrite existing user data
# -> Create a directory with a name that didn't exist before
#
# This may never succeed (if we are racing with a malicious process), but at
# least it is secure
serial=0
loop='yes'
while [ "$loop" = 'yes' ]; do
# Check the validity of the temporary directory. We do this in the loop
# because it can change over time
if [ ! -d "$tmp" ]; then
echo 'Error: "'"$tmp"'" is not a directory.'
echo
exit 1
fi
if [ ! -w "$tmp" -o ! -x "$tmp" ]; then
echo 'Error: "'"$tmp"'" should be writable and executable.'
echo
exit 1
fi
# Be secure
# -> Don't give write access to other users (so that they can not use this
# directory to launch a symlink attack)
if mkdir -m 0755 "$tmp"'/'"$prefix$serial" >/dev/null 2>&1; then
loop='no'
else
serial=`expr $serial + 1`
serial_mod=`expr $serial % 200`
if [ "$serial_mod" = '0' ]; then
echo 'Warning: The "'"$tmp"'" directory may be under attack.'
echo
fi
fi
done
eval "$dirname"'="$tmp"'"'"'/'"'"'"$prefix$serial"'
}
# Removes "stale" device node
# On udev-based systems, this is never needed.
# On older systems, after an unclean shutdown, we might end up with
# a stale device node while the kernel driver has a new major/minor.
vmware_rm_stale_node() {
local node="$1" # IN
if [ -e "/dev/$node" -a "$node" != "" ]; then
local node_major=`ls -l "/dev/$node" | awk '{print \$5}' | sed -e s/,//`
local node_minor=`ls -l "/dev/$node" | awk '{print \$6}'`
if [ "$node_major" = "10" ]; then
local real_minor=`cat /proc/misc | grep "$node" | awk '{print \$1}'`
if [ "$node_minor" != "$real_minor" ]; then
rm -f "/dev/$node"
fi
else
local node_name=`echo $node | sed -e s/[0-9]*$//`
local real_major=`cat /proc/devices | grep "$node_name" | awk '{print
\$1}'`
if [ "$node_major" != "$real_major" ]; then
rm -f "/dev/$node"
fi
fi
fi
}
# Checks if the given pid represents a live process.
# Returns 0 if the pid is a live process, 1 otherwise
vmware_is_process_alive() {
local pid="$1" # IN
ps -p $pid | grep $pid > /dev/null 2>&1
}
# Check if the process associated to a pidfile is running.
# Return 0 if the pidfile exists and the process is running, 1 otherwise
vmware_check_pidfile() {
local pidfile="$1" # IN
local pid
pid=`cat "$pidfile" 2>/dev/null`
if [ "$pid" = '' ]; then
# The file probably does not exist or is empty. Failure
return 1
fi
# Keep only the first number we find, because some Samba pid files are really
# trashy: they end with NUL characters
# There is no double quote around $pid on purpose
set -- $pid
pid="$1"
vmware_is_process_alive $pid
}
# Note:
# . Each daemon must be started from its own directory to avoid busy devices
# . Each PID file doesn't need to be added to the installer database, because
# it is going to be automatically removed when it becomes stale (after a
# reboot). It must go directly under /var/run, or some distributions
# (RedHat 6.0) won't clean it
#
# Terminate a process synchronously
vmware_synchrone_kill() {
local pid="$1" # IN
local signal="$2" # IN
local second
kill -"$signal" "$pid"
# Wait a bit to see if the dirty job has really been done
for second in 0 1 2 3 4 5 6 7 8 9 10; do
vmware_is_process_alive "$pid"
if [ "$?" -ne 0 ]; then
# Success
return 0
fi
sleep 1
done
# Timeout
return 1
}
# Kill the process associated to a pidfile
vmware_stop_pidfile() {
local pidfile="$1" # IN
local pid
pid=`cat "$pidfile" 2>/dev/null`
if [ "$pid" = '' ]; then
# The file probably does not exist or is empty. Success
return 0
fi
# Keep only the first number we find, because some Samba pid files are really
# trashy: they end with NUL characters
# There is no double quote around $pid on purpose
set -- $pid
pid="$1"
# First try a nice SIGTERM
if vmware_synchrone_kill "$pid" 15; then
return 0
fi
# Then send a strong SIGKILL
if vmware_synchrone_kill "$pid" 9; then
return 0
fi
return 1
}
# Determine if SELinux is enabled
isSELinuxEnabled() {
if [ "`cat /selinux/enforce 2> /dev/null`" = "1" ]; then
echo "yes"
else
echo "no"
fi
}
# Runs a command and retries under the provided SELinux context if it fails
vmware_exec_selinux() {
local command="$1"
# XXX We should probably ask the user at install time what context to use
# when we retry commands. unconfined_t is the correct choice for Red Hat.
local context="unconfined_t"
local retval
$command
retval=$?
if [ $retval -ne 0 -a "`isSELinuxEnabled`" = 'yes' ]; then
runcon -t $context -- $command
retval=$?
fi
return $retval
}
# Start the blocking file system. This consists of loading the module and
# mounting the file system.
vmware_start_vmblock() {
mkdir -p -m 1777 /tmp/VMwareDnD
# Try FUSE first, fall back on in-kernel module.
vmware_start_vmblock_fuse && return 0
vmware_exec 'Loading module' vmware_load_module $vmblock
exitcode=`expr $exitcode + $?`
# Check to see if the file system is already mounted.
if grep -q " $vmblockmntpt vmblock " /etc/mtab; then
# If it is mounted, do nothing
true;
else
# If it's not mounted, mount it
vmware_exec_selinux "mount -t vmblock none $vmblockmntpt"
fi
}
# Stop the blocking file system
vmware_stop_vmblock() {
# Check if the file system is mounted and only unmount if so.
# Start with FUSE-based version first, then legacy one.
#
# Vmblock-fuse dev path could be /var/run/vmblock-fuse,
# or /run/vmblock-fuse. Bug 758526.
if grep -q "/run/vmblock-fuse fuse\.vmware-vmblock " /etc/mtab; then
# if it's mounted, then unmount it
vmware_exec_selinux "umount $vmblockfusemntpt"
fi
if grep -q " $vmblockmntpt vmblock " /etc/mtab; then
# if it's mounted, then unmount it
vmware_exec_selinux "umount $vmblockmntpt"
fi
# Unload the kernel module
vmware_unload_module $vmblock
}
# This is necessary to allow udev time to create a device node. If we don't
# wait then udev will override the permissions we choose when it creates the
# device node after us.
vmware_delay_for_node() {
local node="$1"
local delay="$2"
while [ ! -e $node -a ${delay} -gt 0 ]; do
delay=`expr $delay - 1`
sleep 1
done
}
# starts after vmci is loaded
vmware_start_vsock() {
if [ "`isLoaded "$vmci"`" = 'no' ]; then
# vsock depends on vmci
return 1
fi
vmware_load_module $vsock
vmware_rm_stale_node vsock
# Give udev 5 seconds to create our node
vmware_delay_for_node "/dev/vsock" 5
if [ ! -e /dev/vsock ]; then
local minor=`cat /proc/misc | grep vsock | awk '{print $1}'`
mknod --mode=666 /dev/vsock c 10 "$minor"
else
chmod 666 /dev/vsock
fi
return 0
}
# unloads before vmci
vmware_stop_vsock() {
vmware_unload_module $vsock
rm -f /dev/vsock
}
is_ESX_running() {
if [ ! -f "$vmdb_answer_SBINDIR"/vmware-checkvm ] ; then
echo no
return
fi
if "$vmdb_answer_SBINDIR"/vmware-checkvm -p | grep -q ESX; then
echo yes
else
echo no
fi
}
#
# Start vmblock only if ESX is not running and the config script
# built/loaded it (kernel is >= 2.4.0 and product is tools-for-linux).
#
is_vmblock_needed() {
if [ "`is_ESX_running`" = 'yes' ]; then
echo no
else
if [ "$vmdb_answer_VMBLOCK_CONFED" = 'yes' ]; then
echo yes
else
echo no
fi
fi
}
VMUSR_PATTERN="(vmtoolsd.*vmusr|vmware-user)"
vmware_signal_vmware_user() {
# Signal all running instances of the user daemon.
# Our pattern ensures that we won't touch the system daemon.
pkill -$1 -f "$VMUSR_PATTERN"
return 0
}
# A USR1 causes vmware-user to release any references to vmblock or
# /proc/fs/vmblock/mountPoint, allowing vmblock to unload, but vmware-user
# to continue running. This preserves the user context vmware-user is
# running within.
vmware_unblock_vmware_user() {
vmware_signal_vmware_user 'USR1'
}
# A USR2 causes vmware-user to relaunch itself, picking up vmblock anew.
# This preserves the user context vmware-user is running within.
vmware_restart_vmware_user() {
vmware_signal_vmware_user 'USR2'
}
# Checks if there an instance of vmware-user process exists in the system.
is_vmware_user_running() {
if pgrep -f "$VMUSR_PATTERN" > /dev/null 2>&1; then
echo yes
else
echo no
fi
}
wrap () {
AMSG="$1"
while [ `echo $AMSG | wc -c` -gt 75 ] ; do
AMSG1=`echo $AMSG | sed -e 's/\(.\{1,75\} \).*/\1/' -e 's/ [ ]*/ /'`
AMSG=`echo $AMSG | sed -e 's/.\{1,75\} //' -e 's/ [ ]*/ /'`
echo " $AMSG1"
done
echo " $AMSG"
echo " "
}
#---------------------------------------------------------------------------
#
# load_settings
#
# Load VMware Installer Service settings
#
# Returns:
# 0 on success, otherwise 1.
#
# Side Effects:
# vmdb_* variables are set.
#---------------------------------------------------------------------------
load_settings() {
local settings=`$DATABASE/vmis-settings`
if [ $? -eq 0 ]; then
eval "$settings"
return 0
else
return 1
fi
}
#---------------------------------------------------------------------------
#
# launch_binary
#
# Launch a binary with resolved dependencies.
#
# Returns:
# None.
#
# Side Effects:
# Process is replaced with the binary if successful,
# otherwise returns 1.
#---------------------------------------------------------------------------
launch_binary() {
local component="$1" # IN: component name
shift
local binary="$2" # IN: binary name
shift
local args="$@" # IN: arguments
shift
# Convert -'s in component name to _ and lookup its libdir
local component=`echo $component | tr '-' '_'`
local libdir="vmdb_$component_libdir"
exec "$libdir"'/bin/launcher.sh' \
"$libdir"'/lib' \
"$libdir"'/bin/'"$binary" \
"$libdir"'/libconf' "$args"
return 1
}
# END_OF_UTIL_DOT_SH
vmware_etc_dir=/etc/vmware-tools
# Since this script is installed, our main database should be installed too and
# should contain the basic information
vmware_db="$vmware_etc_dir"/locations
if [ ! -r "$vmware_db" ]; then
echo 'Warning: Unable to find '"`vmware_product_name`""'"'s main database
'"$vmware_db"'.'
echo
exit 1
fi
# BEGINNING_OF_DB_DOT_SH
#!/bin/sh
#
# Manage an installer database
#
# Add an answer to a database in memory
db_answer_add() {
local dbvar="$1" # IN/OUT
local id="$2" # IN
local value="$3" # IN
local answers
local i
eval "$dbvar"'_answer_'"$id"'="$value"'
eval 'answers="$'"$dbvar"'_answers"'
# There is no double quote around $answers on purpose
for i in $answers; do
if [ "$i" = "$id" ]; then
return
fi
done
answers="$answers"' '"$id"
eval "$dbvar"'_answers="$answers"'
}
# Remove an answer from a database in memory
db_answer_remove() {
local dbvar="$1" # IN/OUT
local id="$2" # IN
local new_answers
local answers
local i
eval 'unset '"$dbvar"'_answer_'"$id"
new_answers=''
eval 'answers="$'"$dbvar"'_answers"'
# There is no double quote around $answers on purpose
for i in $answers; do
if [ "$i" != "$id" ]; then
new_answers="$new_answers"' '"$i"
fi
done
eval "$dbvar"'_answers="$new_answers"'
}
# Load all answers from a database on stdin to memory (<dbvar>_answer_*
# variables)
db_load_from_stdin() {
local dbvar="$1" # OUT
eval "$dbvar"'_answers=""'
# read doesn't support -r on FreeBSD 3.x. For this reason, the following line
# is patched to remove the -r in case of FreeBSD tools build. So don't make
# changes to it.
while read -r action p1 p2; do
if [ "$action" = 'answer' ]; then
db_answer_add "$dbvar" "$p1" "$p2"
elif [ "$action" = 'remove_answer' ]; then
db_answer_remove "$dbvar" "$p1"
fi
done
}
# Load all answers from a database on disk to memory (<dbvar>_answer_*
# variables)
db_load() {
local dbvar="$1" # OUT
local dbfile="$2" # IN
db_load_from_stdin "$dbvar" < "$dbfile"
}
# Iterate through all answers in a database in memory, calling <func> with
# id/value pairs and the remaining arguments to this function
db_iterate() {
local dbvar="$1" # IN
local func="$2" # IN
shift 2
local answers
local i
local value
eval 'answers="$'"$dbvar"'_answers"'
# There is no double quote around $answers on purpose
for i in $answers; do
eval 'value="$'"$dbvar"'_answer_'"$i"'"'
"$func" "$i" "$value" "$@"
done
}
# If it exists in memory, remove an answer from a database (disk and memory)
db_remove_answer() {
local dbvar="$1" # IN/OUT
local dbfile="$2" # IN
local id="$3" # IN
local answers
local i
eval 'answers="$'"$dbvar"'_answers"'
# There is no double quote around $answers on purpose
for i in $answers; do
if [ "$i" = "$id" ]; then
echo 'remove_answer '"$id" >> "$dbfile"
db_answer_remove "$dbvar" "$id"
return
fi
done
}
# Add an answer to a database (disk and memory)
db_add_answer() {
local dbvar="$1" # IN/OUT
local dbfile="$2" # IN
local id="$3" # IN
local value="$4" # IN
db_remove_answer "$dbvar" "$dbfile" "$id"
echo 'answer '"$id"' '"$value" >> "$dbfile"
db_answer_add "$dbvar" "$id" "$value"
}
# Add a file to a database on disk
# 'file' is the file to put in the database (it may not exist on the disk)
# 'tsfile' is the file to get the timestamp from, '' if no timestamp
db_add_file() {
local dbfile="$1" # IN
local file="$2" # IN
local tsfile="$3" # IN
local date
if [ "$tsfile" = '' ]; then
echo 'file '"$file" >> "$dbfile"
else
# We cannot guarantee existence of GNU coreutils date on all platforms
# (e.g. Solaris). Ignore timestamps in that case.
date=`date -r "$tsfile" '+%s' 2> /dev/null` || true
if [ "$date" != '' ]; then
date=' '"$date"
fi
echo 'file '"$file$date" >> "$dbfile"
fi
}
# Remove file from database
db_remove_file() {
local dbfile="$1" # IN
local file="$2" # IN
echo "remove_file $file" >> "$dbfile"
}
# Add a directory to a database on disk
db_add_dir() {
local dbfile="$1" # IN
local dir="$2" # IN
echo 'directory '"$dir" >> "$dbfile"
}
# END_OF_DB_DOT_SH
db_load 'vmdb' "$vmware_db"
# 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 --hpreg.
# This defines echo_success() and echo_failure() on RedHat
if [ -r "$vmdb_answer_INITSCRIPTSDIR"'/functions' ]; then
. "$vmdb_answer_INITSCRIPTSDIR"'/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='[71G done'
rc_failed='[71Gfailed'
fi
#
# Global variables
#
vmmemctl="vmmemctl"
vmxnet="vmxnet"
vmxnet3="vmxnet3"
vmhgfs="vmhgfs"
subsys="vmware-tools"
vmblock="vmblock"
vmci="vmci"
vsock="vsock"
vmsync="vmsync"
acpi="acpiphp"
pvscsi="pvscsi"
vmhgfs_mnt="/mnt/hgfs"
#
# Utilities
#
# BEGINNING_OF_IPV4_DOT_SH
#!/bin/sh
#
# IPv4 address functions
#
# Thanks to Owen DeLong <o...@delong.com> for pointing me at bash's arithmetic
# expansion ability, which is a lot faster than using 'expr'
#
# Compute the subnet address associated to a couple IP/netmask
ipv4_subnet() {
local ip="$1"
local netmask="$2"
# Split quad-dotted addresses into bytes
# There is no double quote around the back-quoted expression on purpose
# There is no double quote around $ip and $netmask on purpose
set -- `IFS='.'; echo $ip $netmask`
echo $(($1 & $5)).$(($2 & $6)).$(($3 & $7)).$(($4 & $8))
}
# Compute the broadcast address associated to a couple IP/netmask
ipv4_broadcast() {
local ip="$1"
local netmask="$2"
# Split quad-dotted addresses into bytes
# There is no double quote around the back-quoted expression on purpose
# There is no double quote around $ip and $netmask on purpose
set -- `IFS='.'; echo $ip $netmask`
echo $(($1 | (255 - $5))).$(($2 | (255 - $6))).$(($3 | (255 - $7))).$(($4 |
(255 - $8)))
}
# END_OF_IPV4_DOT_SH
upperCase() {
echo "`echo $1|tr '[:lower:]' '[:upper:]'`"
}
kernAsKey() {
uname -r | tr -d '+-.'
}
vmware_getModName() {
local module=`upperCase $1`
local var='vmdb_answer_'"${module}_`kernAsKey`"'_NAME'
# Indirect references in sh. Oh sh, how I love thee...
eval result=\$$var
if [ "$result" != '' ]; then
echo "$result"
else
echo "$1"
fi
}
vmware_getModPath() {
local module=`upperCase $1`
local var='vmdb_answer_'"${module}_`kernAsKey`"'_PATH'
eval result=\$$var
if [ "$result" != '' ]; then
echo "$result"
else
echo "$1"
fi
}
if [ -e "$vmdb_answer_SBINDIR"/vmtoolsd ]; then
SYSTEM_DAEMON=vmtoolsd
else
SYSTEM_DAEMON=vmware-guestd
fi
# Are we running in a VM?
vmware_inVM() {
"$vmdb_answer_SBINDIR"/vmware-checkvm >/dev/null 2>&1
}
vmware_hwVersion() {
"$vmdb_answer_SBINDIR"/vmware-checkvm -h | grep hw | cut -d ' ' -f 5
}
# Is a given module loaded?
isLoaded() {
# Check for both the original module name and the newer module name
local module="$1"
local module_name="`vmware_getModName $1`"
/sbin/lsmod | awk 'BEGIN {n = "no";} {if ($1 == "'"$module"'") n = "yes";}
{if ($1 == "'"$module_name"'") n = "yes";} END {print n;}'
}
# Build a Linux kernel integer version
kernel_version_integer() {
echo $(((($1 * 256) + $2) * 256 + $3))
}
# Get the running kernel integer version
get_version_integer() {
local version_uts
local v1
local v2
local v3
version_uts=`uname -r`
# There is no double quote around the back-quoted expression on purpose
# There is no double quote around $version_uts on purpose
set `IFS='.'; echo $version_uts`
v1="$1"
v2="$2"
v3="$3"
# There is no double quote around the back-quoted expression on purpose
# There is no double quote around $v3 on purpose
set `IFS='-ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'; echo $v3`
v3="$1"
kernel_version_integer "$v1" "$v2" "$v3"
}
#
# We exit on failure because these functions are called within the
# context of vmware_exec, which sets up a trap that causes exit to jump
# back to vmware_exec, like an exception handler. On success, we return
# because our caller may want to perform additional instructions.
#
# XXX: This really belongs in util.sh but that requires reconciling
# the hosted scripts as well. It would also allow it to be easily
# overriden by the DSP init script.
vmware_load_module() {
local moduleName=`vmware_getModName $1`
vmware_unload_module $1
vmware_insmod $1
return 0
}
vmware_insmod() {
local module_path="`vmware_getModPath $1`"
local module_name="`vmware_getModName $1`"
/sbin/insmod -s -f "$module_path" >/dev/null 2>&1 || \
/sbin/insmod -s -f "$module_name" >/dev/null 2>&1 || exit 1
return 0
}
vmware_unload_module() {
local module="$1"
local module_name="`vmware_getModName $1`"
if [ "`isLoaded "$1"`" = 'yes' ]; then
/sbin/rmmod "$module" >/dev/null 2>&1 || \
/sbin/rmmod "$module_name" >/dev/null 2>&1 || exit 1
fi
return 0
}
#
# Note:
# . Each daemon must be started from its own directory to avoid busy devices
# . Each PID file doesn't need to be added to the installer database, because
# it is going to be automatically removed when it becomes stale (after a
# reboot). It must go directly under /var/run, or some distributions
# (RedHat 6.0) won't clean it
#
vmware_start_daemon() {
[ ! -d $vmdb_answer_SBINDIR ] && return 1
command="$vmdb_answer_SBINDIR/$1 --background /var/run/$1.pid"
vmware_exec_selinux "$command"
}
vmware_stop_daemon() {
local pidfile="/var/run/$1.pid"
if vmware_stop_pidfile $pidfile; then
rm -f $pidfile
fi
}
vmware_daemon_status() {
echo -n "$1 "
if vmware_check_pidfile "/var/run/$1.pid"; then
echo 'is running'
else
echo 'is not running'
exitcode=$(($exitcode + 1))
fi
}
# Start the virtual ethernet kernel service
vmware_start_vmxnet() {
# only load vmxnet if it's not already loaded
if [ "`isLoaded "$vmxnet"`" = 'no' ]; then
vmware_load_module $vmxnet
fi
}
vmware_start_vmxnet3() {
# only load vmxnet3 if it's not already loaded
if [ "`isLoaded "$vmxnet3"`" = 'no' ]; then
vmware_load_module $vmxnet3
fi
}
vmware_switch() {
"$vmdb_answer_BINDIR"/vmware-config-tools.pl --switch
return 0
}
# Start the guest virtual memory manager
vmware_start_vmmemctl() {
vmware_load_module $vmmemctl
}
# Stop the guest virtual memory manager
vmware_stop_vmmemctl() {
vmware_unload_module $vmmemctl
}
# Start the guest vmci driver
vmware_start_vmci() {
# only load vmci if it's not already loaded
if [ "`isLoaded "$vmci"`" = 'no' ]; then
vmware_load_module $vmci
fi
# Give udev 5 seconds to create our node
vmware_delay_for_node "/dev/vmci" 5
if [ ! -e /dev/vmci ]; then
# VMCI used to be registered with /proc/devices, but is now
# registered with /proc/misc. Check both for the major device
# node so we can create /dev/vmci.
local major=`cat /proc/misc /proc/devices |grep vmci | awk '{print $1}'`
# If there was no major number available, exit with an error
if [ -z "$major" ]; then
exit 1
fi
# Otherwise create the device node
mknod --mode=600 /dev/vmci c $major 0
else
chmod 600 /dev/vmci
fi
}
# unmount it
vmware_stop_vmci() {
if [ "`isLoaded "$vsock"`" = 'yes' ]; then
vmware_stop_vsock
fi
vmware_unload_module $vmci
rm -f /dev/vmci
}
# Identify whether there's a mount mounted on the default hgfs mountpoint
is_vmhgfs_mounted() {
# if [ `grep -q " $vmhgfs_mnt vmhgfs " /etc/mtab` ];
# Using this method instead as it is more robust. The above
# line has the possibility of ALWAYS returning a failure.
if grep -q " $vmhgfs_mnt vmhgfs " /etc/mtab; then
echo "yes"
else
echo "no"
fi
}
# Mount all hgfs filesystems
vmware_mount_vmhgfs() {
if [ "`is_vmhgfs_mounted`" = "no" ]; then
vmware_exec_selinux "mount -t vmhgfs .host:/ $vmhgfs_mnt"
fi
}
# Start the guest filesystem driver and mount it
vmware_start_vmhgfs() {
# only load vmhgfs if it's not already loaded
if [ "`isLoaded "$vmhgfs"`" = 'no' -a "`isLoaded "$vmci"`" = 'yes' ]; then
vmware_load_module $vmhgfs
fi
}
# Unmount all hgfs filesystems left mounted
vmware_unmount_vmhgfs() {
if [ "`is_vmhgfs_mounted`" = "yes" ]; then
vmware_exec_selinux "umount $vmhgfs_mnt"
fi
}
# Stop the guest filesystem driver
vmware_stop_vmhgfs() {
vmware_unload_module $vmhgfs
}
vmware_thinprint_get_tty() {
"$vmdb_answer_SBINDIR"/$SYSTEM_DAEMON --cmd 'info-get
guestinfo.vprint.thinprintBackend' | \
sed -e s/serial/ttyS/
}
# Load the vmsync driver
vmware_start_vmsync() {
vmware_load_module $vmsync
}
# Unload the vmsync driver
vmware_stop_vmsync() {
vmware_unload_module $vmsync
}
vmware_start_acpi_hotplug() {
if [ `isLoaded $acpi` = 'yes' ]; then
# acpiphp is already loaded. Success.
return 0
fi
# Don't allow pciehp and acpiphp to overlap. Also don't unload
# pciehp in order to then load acpiphp as this won't avoid acpiphp
# crashing while trying to register a device node pciehp already has.
# All this only before 2.6.17 - since 2.6.17 pciehp and acpiphp can
# coexist.
if [ `isLoaded pciehp` = 'yes' ]; then
local ok_kver=`kernel_version_integer '2' '6' '17'`
local run_kver=`get_version_integer`
if [ $run_kver -lt $ok_kver ]; then
return 1
fi
fi
modprobe $acpi
return 0
}
vmware_stop_acpi_hotplug() {
vmware_unload_module $acpi
}
# Don't use vmware_load_module() because it first
# tries to unload the module which we don't want here.
vmware_start_pvscsi() {
if ! /sbin/modinfo $pvscsi ; then
# Apparently pvscsi does not exist on this system, so punt.
return 0
fi
if [ `isLoaded $pvscsi` != 'yes' ]; then
vmware_insmod $pvscsi
fi
}
vmware_stop_pvscsi() {
vmware_unload_module $pvscsi
}
is_vmhgfs_needed() {
local min_kver=`kernel_version_integer '2' '4' '0'`
local run_kver=`get_version_integer`
if [ $min_kver -le $run_kver -a "$vmdb_answer_VMHGFS_CONFED" = 'yes' ]; then
echo yes
else
echo no
fi
}
is_vmmemctl_needed() {
if [ "$vmdb_answer_VMMEMCTL_CONFED" = 'yes' ]; then
echo yes
else
echo no
fi
}
is_pvscsi_needed() {
if [ "$vmdb_answer_PVSCSI_CONFED" = 'yes' ]; then
echo yes
else
echo no
fi
}
is_acpi_hotplug_needed() {
# Must have DVHP in ACPI tables. There are now two places we need to check
for it.
dev=''
for path in /proc/acpi/dsdt /sys/firmware/acpi/tables/DSDT; do
if [ -e $path ]; then
dev="$path"
fi
done
# If neither of those paths exist, return no
if [ -z "$dev" ]; then
echo no
return
fi
# Otherwise search for DVHP
if grep -q DVHP $dev; then
# Look for bridge, PCI-PCI is 0790, PCIe is 07a0.
cat /proc/bus/pci/devices | grep -qi "^[0-9a-f]* 15ad07[9a]0 "
if [ "$?" -eq 0 ]; then
echo yes
return
fi
fi
echo no
}
is_vmxnet_needed() {
# First try vmxnet's vendor/device ID's
cat /proc/bus/pci/devices | grep -qi "^[0-9a-f]* 15ad0720 "
if [ "$?" -eq 0 -a "$vmdb_answer_VMXNET_CONFED" = 'yes' ]; then
echo yes
else
# Now try pcnet32's vendor/device ID's...see bug 79352
# We only accept pcnet32 if the HW version of the VM is ws50 or later
local hwver=`vmware_hwVersion`
cat /proc/bus/pci/devices | grep -qi "^[0-9a-f]* 10222000 "
if [ "$?" -eq 0 -a "$vmdb_answer_VMXNET_CONFED" = 'yes' -a \
$hwver -ge 4 ]; then
echo yes
else
echo no
fi
fi
}
is_vmxnet3_needed() {
cat /proc/bus/pci/devices | grep -qi "^[0-9a-f]* 15ad07b0 "
if [ "$?" -eq 0 -a "$vmdb_answer_VMXNET3_CONFED" = 'yes' ]; then
echo yes
else
echo no
fi
}
is_vmci_needed() {
if [ "`is_vsock_needed`" = 'yes' -o "`is_vmhgfs_needed`" = 'yes' \
-o "$vmdb_answer_VMCI_CONFED" = 'yes' ]; then
echo yes
else
echo no
fi
}
is_vsock_needed() {
if [ "$vmdb_answer_VSOCK_CONFED" = 'yes' ]; then
echo yes
else
echo no
fi
}
is_vmsync_needed() {
local min_kver=`kernel_version_integer '2' '6' '6'`
local run_kver=`get_version_integer`
if [ $min_kver -le $run_kver -a "$vmdb_answer_VMSYNC_CONFED" = 'yes' ]; then
echo yes
else
echo no
fi
}
vmware_start_vmblock_fuse() {
# 2.6.27 is pretty arbitrary but we already have in-kernel
# vmblock for earlier versions
local ok_kver=`kernel_version_integer '2' '6' '27'`
local run_kver=`get_version_integer`
if [ $run_kver -lt $ok_kver ]; then
return 1
fi
if ! grep -q "fuse" /proc/filesystems; then
# Try to load fuse module if it is not there yet.
modprobe fuse > /dev/null 2>&1 || return 1
fi
# Vmblock-fuse dev path could be /var/run/vmblock-fuse
# or /run/vmblock-fuse. Bug 758526.
if grep -q "/run/vmblock-fuse fuse\.vmware-vmblock " /etc/mtab; then
true;
else
mkdir -p $vmblockfusemntpt
vmware_exec_selinux "$vmdb_answer_SBINDIR/vmware-vmblock-fuse \
-o subtype=vmware-vmblock,default_permissions,allow_other \
$vmblockfusemntpt"
fi
}
vmware_auto_kmods_enabled() {
echo "$vmdb_answer_AUTO_KMODS_ENABLED"
}
vmware_auto_kmods() {
# Check if mods are confed, but not installed.
vmware_exec_selinux "$vmdb_answer_LIBDIR/sbin/vmware-modconfig-console \
--configured-mods-installed" && exit 0
# Check that we have PBMs, of if not, then kernel headers and gcc.
Otherwise don't waste time
if ! vmware_exec_selinux "$vmdb_answer_LIBDIR/sbin/vmware-modconfig-console
--pbm-available vmmemctl"; then
vmware_exec_selinux "$vmdb_answer_LIBDIR/sbin/vmware-modconfig-console \
--get-kernel-headers" || (echo "No kernel headers"
&& exit 1)
vmware_exec_selinux "$vmdb_answer_LIBDIR/sbin/vmware-modconfig-console \
--get-gcc" || (echo "No gcc" && exit 1)
fi
# We assume config.pl has already been run since our init script is at this
point.
# If so, then lets build whatever mods are configured.
vmware_exec_selinux "$vmdb_answer_BINDIR/vmware-config-tools.pl --default
--modules-only --skip-stop-start"
}
main()
{
# See how we were called.
case "$1" in
start)
# If the service has already been started exit right away
[ -f /var/lock/subsys/"$subsys" ] && exit 0
exitcode='0'
if [ "`is_acpi_hotplug_needed`" = 'yes' ]; then
vmware_exec "Checking acpi hot plug" vmware_start_acpi_hotplug
fi
if vmware_inVM; then
if ! is_dsp && [ -e "$vmware_etc_dir"/not_configured ]; then
echo "`vmware_product_name`"' is installed, but it has not been '
echo '(correctly) configured for the running kernel.'
echo 'To (re-)configure it, invoke the following command: '
echo "$vmdb_answer_BINDIR"'/vmware-config-tools.pl.'
echo
exit 1
fi
echo 'Starting VMware Tools services in the virtual machine:'
vmware_exec 'Switching to guest configuration:' vmware_switch
exitcode=$(($exitcode + $?))
if [ "`vmware_auto_kmods_enabled`" = 'yes' ] &&
! grep -q "vmw_no_akmod" /proc/cmdline; then
vmware_exec 'VMware Automatic Kmods:' vmware_auto_kmods
fi
if [ "`is_pvscsi_needed`" = 'yes' ]; then
vmware_exec 'Paravirtual SCSI module:' vmware_start_pvscsi
exitcode=$(($exitcode + $?))
fi
if [ "`is_vmmemctl_needed`" = 'yes' ]; then
vmware_exec 'Guest memory manager:' vmware_start_vmmemctl
exitcode=$(($exitcode + $?))
fi
if [ "`is_vmxnet_needed`" = 'yes' ]; then
vmware_exec 'Guest vmxnet fast network device:'
vmware_start_vmxnet
exitcode=$(($exitcode + $?))
fi
if [ "`is_vmxnet3_needed`" = 'yes' ]; then
vmware_exec 'Driver for the VMXNET 3 virtual network card:'
vmware_start_vmxnet3
exitcode=$(($exitcode + $?))
fi
if [ "`is_vmci_needed`" = 'yes' ]; then
vmware_exec 'VM communication interface:' vmware_start_vmci
fi
# vsock needs vmci started first
if [ "`is_vsock_needed`" = 'yes' ]; then
vmware_exec 'VM communication interface socket family:'
vmware_start_vsock
exitcode=$(($exitcode + $?))
fi
# vmhgfs needs vmci started first
if [ "`is_vmhgfs_needed`" = 'yes' -a "`is_ESX_running`" = 'no' ];
then
vmware_exec 'Guest filesystem driver:' vmware_start_vmhgfs
exitcode=$(($exitcode + $?))
vmware_exec 'Mounting HGFS shares:' vmware_mount_vmhgfs
# Ignore the exitcode. The mount may fail if HGFS is disabled
# in the host, in which case requiring a rerun of the Tools
# configurator is useless.
fi
if [ "`is_vmblock_needed`" = 'yes' ] ; then
vmware_exec 'Blocking file system:' vmware_start_vmblock
exitcode=$(($exitcode + $?))
fi
# Signal vmware-user to relaunch itself and maybe restore
# contact with the blocking file system.
if [ "`is_vmware_user_running`" = 'yes' ]; then
vmware_exec 'VMware User Agent:' vmware_restart_vmware_user
fi
if [ "`is_vmsync_needed`" = 'yes' ] ; then
vmware_exec 'File system sync driver:' vmware_start_vmsync
exitcode=$(($exitcode + $?))
fi
vmware_exec 'Guest operating system daemon:' vmware_start_daemon
$SYSTEM_DAEMON
exitcode=$(($exitcode + $?))
else
echo 'Starting VMware Tools services on the host:'
vmware_exec 'Switching to host config:' vmware_switch
exitcode=$(($exitcode + $?))
fi
if ! is_dsp && [ "$exitcode" -gt 0 ]; then
exit 1
fi
[ -d /var/lock/subsys ] || mkdir -p /var/lock/subsys
touch /var/lock/subsys/"$subsys"
;;
stop)
exitcode='0'
if vmware_inVM; then
echo 'Stopping VMware Tools services in the virtual machine:'
vmware_exec 'Guest operating system daemon:' vmware_stop_daemon
$SYSTEM_DAEMON
exitcode=$(($exitcode + $?))
if [ "`is_vmblock_needed`" = 'yes' ] ; then
# Signal vmware-user to release any contact with the blocking fs.
vmware_exec 'VMware User Agent (vmware-user):'
vmware_unblock_vmware_user
rv=$?
exitcode=$(($exitcode + $rv))
# If unblocking vmware-user fails then stopping and unloading vmblock
# probably will also fail.
if [ $rv -eq 0 ]; then
vmware_exec 'Blocking file system:' vmware_stop_vmblock
exitcode=$(($exitcode + $?))
fi
fi
vmware_exec 'Unmounting HGFS shares:' vmware_unmount_vmhgfs
rv=$?
vmware_exec 'Guest filesystem driver:' vmware_stop_vmhgfs
rv=$(($rv + $?))
if [ "`is_vmhgfs_needed`" = 'yes' ]; then
exitcode=$(($exitcode + $rv))
fi
if [ "`is_vmmemctl_needed`" = 'yes' ]; then
vmware_exec 'Guest memory manager:' vmware_stop_vmmemctl
exitcode=$(($exitcode + $?))
fi
# vsock requires vmci to work so it must be unloaded before vmci
if [ "`is_vsock_needed`" = 'yes' ]; then
vmware_exec 'VM communication interface socket family:'
vmware_stop_vsock
exitcode=$(($exitcode + $?))
fi
if [ "`is_vmci_needed`" = 'yes' ]; then
vmware_exec 'VM communication interface:' vmware_stop_vmci
exitcode=$(($exitcode + $?))
fi
if [ "`is_vmsync_needed`" = 'yes' ] ; then
vmware_exec 'File system sync driver:' vmware_stop_vmsync
exitcode=$(($exitcode + $?))
fi
else
echo -n 'Skipping VMware Tools services shutdown on the host:'
vmware_success
echo
fi
if [ "$exitcode" -gt 0 ]; then
exit 1
fi
rm -f /var/lock/subsys/"$subsys"
;;
status)
exitcode='0'
vmware_daemon_status $SYSTEM_DAEMON
exitcode=$(($exitcode + $?))
if [ "$exitcode" -ne 0 ]; then
exit 1
fi
;;
restart | force-reload)
"$0" stop && "$0" start
;;
source)
# Used to source the script so that functions can be
# selectively overriden.
return 0
;;
*)
echo "Usage: `basename "$0"` {start|stop|status|restart|force-reload}"
exit 1
esac
exit 0
}
main "$@"