Skip to content

Instantly share code, notes, and snippets.

@higebu
Created September 7, 2014 04:47
Show Gist options
  • Save higebu/0f27b88dd723460cb44c to your computer and use it in GitHub Desktop.
Save higebu/0f27b88dd723460cb44c to your computer and use it in GitHub Desktop.
/etc/vmware-tools/scripts/vmware/network for the OS doesn't have ifup command.
#!/bin/sh
##########################################################
# Copyright (C) 2001-2010 VMware, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation version 2.1 and no later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
##########################################################
#
# network (Linux)
#
# Using a combination of a system networking script, ifconfig
# attempt to release and renew DHCP leases upon receipt of suspend and resume
# events, respectively.
#
echo `date` ": Executing '$0'"
echo
. `dirname "$0"`/../../statechange.subr
#
# find_networking_script --
#
# Searches common Linux distro init/rc paths to find a singular network
# services script.
#
# Result:
# Returns a valid networking script path on success or "error" on failure.
#
# Side effects:
# None.
#
find_networking_script() {
local script="error"
for dir in "/etc/init.d" "/sbin/init.d" "/etc" "/etc/rc.d" ; do
if [ -d "$dir/rc0.d" ] &&
[ -d "$dir/rc1.d" ] &&
[ -d "$dir/rc2.d" ] &&
[ -d "$dir/rc3.d" ] &&
[ -d "$dir/rc4.d" ] &&
[ -d "$dir/rc5.d" ] &&
[ -d "$dir/rc6.d" ]; then
# Now find the appropriate networking script.
if [ -d "$dir/init.d" ]; then
if [ -x "$dir/init.d/network" ]; then
script="$dir/init.d/network"
elif [ -x "$dir/init.d/networking" ]; then
script="$dir/init.d/networking"
fi
else
if [ -x "$dir/network" ]; then
script="$dir/network"
elif [ -x "$dir/networking" ]; then
script="$dir/networking"
fi
fi
fi
done
echo "$script"
}
#
# run_network_script --
#
# Finds out how to run the system's script used to control networking, and
# runs it with the given argument (which should be one of the usual SysV
# init script arguments).
#
run_network_script()
{
script=`find_networking_script`
[ "$script" != "error" ] || Panic "Cannot find system networking script."
# Using SysV "service" if it exists, otherwise fall back to run the script directly
service=`which service 2>/dev/null`
if [ $? = 0 -a -n "$service" ]; then
serviceName=`basename "$script"`
"$service" "$serviceName" "$1"
else
"$script" "$1"
fi
}
#
# save_active_NIC_list --
#
# Records a list of every active NIC to /var/run/vmware-active-nics.
#
# XXX What's the story on aliases? Should they still be included, or will
# they be recreated automatically upon resume?
#
# Results:
# $activeList has, one per line, a list of all active NICs.
#
# Side effects:
# None.
#
save_active_NIC_list() {
>$activeList
for nic in `ifconfig | awk '/^eth/ { print $1 }'`; do
ifconfig $nic | egrep -q '\bUP\b' && echo $nic >> $activeList
exitCode=`expr $exitCode \| $?`
done
}
#
# rescue_NIC --
#
# For each NIC recorded in $activeList that is not currently "up", run
# "ifconfig $nic up".
#
# Results:
# All downed NICs should be active.
#
rescue_NIC() {
if [ -f "$activeList" ]; then
while read nic; do
if ifconfig $nic | egrep -q '\bUP\b'; then
echo `date` "[rescue_nic] $nic is already active."
else
echo `date` "[rescue_nic] activating $nic ..."
ifconfig $nic up
exitCode=`expr $exitCode \| $?`
fi
done < $activeList
rm -f $activeList
fi
}
#
# TranquilizeNetworkManager --
#
# Put the NetworkManager daemon to sleep (maybe).
#
# See http://projects.gnome.org/NetworkManager/developers/spec.html .
#
# Results:
# Sleep(true) request is sent to the NetworkManager D-Bus interface.
#
# Side effects:
# None.
#
TranquilizeNetworkManager()
{
# `which' may be a bit noisy, so we'll shush it.
dbusSend=`which dbus-send 2>/dev/null`
rc=$?
if [ $rc -ne 0 ]; then
return $rc
fi
# Check NetworkManager state before disabling it.
nm_state=`$dbusSend --system --print-reply \
--dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
org.freedesktop.DBus.Properties.Get \
string:'org.freedesktop.NetworkManager' \
string:'State' \
| awk '/variant/ {print $3;}'`
if [ -z "$nm_state" ]; then
return 1
fi
# NetworkManager API 0.7/0.8 0.9
# NM_STATE_ASLEEP 1 10
# NM_STATE_DISCONNECTED 4 20
case $nm_state in
1|4|10|20)
# Nothing needs to be done.
return 0
;;
esac
# NetworkManager 0.8.0 and above
$dbusSend --system --print-reply \
--dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
org.freedesktop.NetworkManager.Enable boolean:false
rc=$?
if [ $rc -eq 0 ]; then
return $rc
fi
# NetworkManager 0.7.0
$dbusSend --system --print-reply \
--dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
org.freedesktop.NetworkManager.Sleep boolean:true
rc=$?
if [ $rc -eq 0 ]; then
return $rc
fi
# NetworkManager 0.6
$dbusSend --system --print-reply \
--dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
org.freedesktop.NetworkManager.sleep
rc=$?
return $rc
}
#
# WakeNetworkManager --
#
# Wake the NetworkManager daemon (maybe).
#
# See http://projects.gnome.org/NetworkManager/developers/spec.html .
#
# Results:
# Sleep(false)request is sent to the NetworkManager D-Bus interface.
#
# Side effects:
# None.
#
WakeNetworkManager()
{
# `which' may be a bit noisy, so we'll shush it.
dbusSend=`which dbus-send 2>/dev/null`
rc=$?
if [ $rc = 0 ]; then
# NetworkManager 0.8.0
$dbusSend --system --print-reply \
--dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
org.freedesktop.NetworkManager.Enable boolean:true
rc=$?
if [ $rc = 0 ]; then
return $rc
fi
# NetworkManager 0.7.0
$dbusSend --system --print-reply \
--dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
org.freedesktop.NetworkManager.Sleep boolean:false
rc=$?
if [ $rc = 0 ]; then
return $rc
fi
# NetworkManager 0.6
$dbusSend --system --print-reply \
--dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
org.freedesktop.NetworkManager.wake
rc=$?
fi
return $rc
}
#
# main --
#
# Main entry point. Perform some sanity checking, then map state change
# events to relevant networking operations.
#
# Results:
# See comment at top of file.
#
main() {
exitCode=0
activeList=/var/run/vmware-active-nics
# XXX Are these really necessary? If so, we should have seen customer
# complaints by now.
which ifconfig >/dev/null 2>&1 || Panic "ifconfig not in search path."
case "$1" in
poweron-vm)
rm -f $activeList
;;
suspend-vm)
TranquilizeNetworkManager
exitCode=$?
if [ $exitCode != 0 ]; then
save_active_NIC_list
run_network_script stop
exitCode=$?
fi
;;
resume-vm)
WakeNetworkManager
exitCode=$?
if [ $exitCode != 0 ]; then
# According to hfu, "/etc/init.d/networking restart" on Debian 5.0
# may bring down ethernet interfaces tagged as "allow-hotplug" without
# bringing them back up.
#
# This is especially a problem when reverting to a live, running
# VM snapshot where an active NIC list hadn't yet been generated,
# resulting in sudden loss of an otherwise operational NIC.
#
# So, if the active list doesn't exist, assume we're coming back to
# a live snapshot and capture the current active list now for
# rescue later.
if [ ! -s $activeList ]; then
save_active_NIC_list
fi
# We shall use start not restart here. Otherwise we may not be able
# to bring back active list on distros like sles11sp2
# -- PR 816791
run_network_script start
rescue_NIC
exitCode=$?
fi
;;
*) ;;
esac
return $exitCode
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment