-
-
Save alexmerser/1fb6e27df5bafd8c33ae to your computer and use it in GitHub Desktop.
/etc/init.d/vz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Copyright (C) 2000-2009, Parallels, Inc. All rights reserved. | |
# | |
# This program is free software; you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation; either version 2 of the License, or | |
# (at your option) any 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 | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, write to the Free Software | |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
# | |
# | |
# OpenVZ startup script, used for redhat and debian related distributions. | |
### | |
# chkconfig: 2345 96 88 | |
# description: OpenVZ startup script. | |
### | |
### BEGIN INIT INFO | |
# Provides: vz | |
# Required-start: $network $remote_fs $syslog | |
# Required-stop: $network $remote_fs $syslog | |
# Should-Start: sshd vzeventd | |
# Should-Stop: sshd vzeventd | |
# Default-Start: 2 3 4 5 | |
# Default-Stop: 0 1 6 | |
# Short-Description: OpenVZ startup script | |
# Description: OpenVZ startup script. | |
### END INIT INFO | |
# This line is needed to cheat /etc/init.d/rc who expects action word | |
. /usr/lib/vzctl/scripts/initd-functions | |
VZQUOTA=/usr/sbin/vzquota | |
CONFIG_DIR=/etc/vz/conf | |
LOCKFILE=$VARLOCK/vz_lock | |
SUBSYS_VZ=$VARLOCK/vz | |
VESTAT=/proc/vz/vestat | |
#VZDEV=venet0 | |
PRELOAD_MODULES= | |
MODULES= | |
MODULES_OTHER= | |
NET_MODULES= | |
IPT_MODULES= | |
if [ "${MODULES_DISABLED}" != "yes" ]; then | |
PRELOAD_MODULES="af_packet" | |
MODULES="vzmon vzdquota vzdev" | |
CPT_MODULES="vzcpt vzrst" | |
MODULES_OTHER="vzcompat ${CPT_MODULES}" | |
VNET_MODULES="vznetdev vznet" | |
VETH_MODULES="vzethdev" | |
NET_MODULES="${VNET_MODULES} ${VETH_MODULES}" | |
if [ "${VZWDOG}" = "yes" ]; then | |
MODULES="${MODULES} vzwdog" | |
fi | |
IPT_MODULES="ip_tables ${IPTABLES} xt_tcpudp" | |
if [ "${IPV6}" = "yes" ]; then | |
IPT_MODULES="${IPT_MODULES} ${IP6TABLES}" | |
fi | |
VZFS_MODULES="simfs" | |
fi | |
VEINFO="" | |
RETVAL=0 | |
# Number of the containers to stop in parallel. | |
# In case of empty value the number of CTs is calculated as 'num_cpu * 4' | |
PARALLEL= | |
cd / | |
check_kernel() | |
{ | |
if ! test -d /proc/vz ; then | |
print_failure "Running kernel is not OpenVZ kernel." | |
exit 1 | |
fi | |
} | |
get_kernel_version() | |
{ | |
[ ! -z "$KERNEL_MAJOR" ] && return | |
local ver=$(uname -r) | |
local kernel=$(echo $ver | sed s/[-+].*//) | |
KERNEL_MAJOR=$(echo $kernel | awk -F . '{print $1}') | |
KERNEL_MINOR=$(echo $kernel | awk -F . '{print $2}') | |
KERNEL_PATCHLEVEL=$(echo $kernel | awk -F . '{print $3}') | |
} | |
check_kernel_config() | |
{ | |
test -r /proc/config.gz || return 0 | |
local conf opt err=0 | |
local opt_must="SIM_FS VE VE_CALLS VZ_GENCALLS" | |
get_kernel_version | |
# For kernels >= 2.6.9 VZ_DEV must be set. | |
test "${KERNEL_MINOR}" -ge 6 && | |
test "${KERNEL_PATCHLEVEL}" -gt 9 && | |
opt_must="${opt_must} VZ_DEV" | |
# local opt_rec="SCHED_VCPU FAIRSCHED VZ_QUOTA VZ_QUOTA_UGID VE_NETDEV VE_ETHDEV | |
# VE_IPTABLES VZ_CHECKPOINT VZ_WDOG" | |
conf="`zcat /proc/config.gz 2>/dev/null | grep -E -v '^#|^$'`" | |
for opt in $opt_must; do | |
if ! echo "$conf" 2>/dev/null | grep -q "$opt="; then | |
echo "ERROR: Missing kernel config option: CONFIG_$opt" | |
err=1 | |
fi | |
done | |
if [ $err != 0 ]; then | |
print_failure "Please recompile your kernel." | |
exit 1 | |
fi | |
} | |
get_parallel() | |
{ | |
[ -n "${PARALLEL}" ] && return | |
PARALLEL=`awk ' | |
BEGIN { num=0; } | |
$1 == "processor" { num++; } | |
END { print num * 4; }' /proc/cpuinfo` | |
} | |
get_veinfo() | |
{ | |
if [ -f /proc/vz/veinfo ]; then | |
VEINFO=/proc/vz/veinfo | |
elif [ -f /proc/veinfo ]; then | |
VEINFO=/proc/veinfo | |
elif [ ! -f $VESTAT ]; then | |
return 1 | |
fi | |
return 0 | |
} | |
is_running() | |
{ | |
get_veinfo || return 1 | |
[ -f $SUBSYS_VZ ] || return 1 | |
} | |
status() | |
{ | |
check_kernel | |
if is_running; then | |
echo "OpenVZ is running..." | |
return 0 | |
else | |
echo "OpenVZ is stopped." | |
return 3 | |
fi | |
} | |
start_net() | |
{ | |
local mod | |
# load all kernel modules needed for containers networking | |
for mod in ${NET_MODULES}; do | |
modprobe ${mod} 2>/dev/null | |
done | |
if ip addr list | grep -q "venet0:.*UP" 2>/dev/null; then | |
return 0 | |
fi | |
get_veinfo | |
if [ -z "$VEINFO" ]; then | |
return 0 | |
fi | |
if [ -n "$VZDEV" ]; then | |
__echo "Bringing up interface $VZDEV: " | |
ip link set $VZDEV up | |
print_result | |
ip addr add 0.0.0.0/0 dev $VZDEV | |
if [ "${IPV6}" = "yes" ]; then | |
ip -6 addr add fe80::1/128 dev $VZDEV | |
fi | |
sysctl -q -w net.ipv4.conf.$VZDEV.send_redirects=0 | |
if [ "$(sysctl -n -e net.ipv4.ip_forward)" != "1" ]; then | |
print_warning "IP forwarding is not enabled" | |
fi | |
fi | |
} | |
stop_net() | |
{ | |
local mod | |
if [ -n "$VZDEV" ]; then | |
if ip addr list | grep -q "venet0:.*UP" 2>/dev/null; then | |
__echo "Bringing down interface $VZDEV: " | |
ip link set $VZDEV down | |
print_result | |
fi | |
fi | |
for mod in ${NET_MODULES}; do | |
/sbin/modprobe -r ${mod} > /dev/null 2>&1 | |
done | |
} | |
setup_ve0() | |
{ | |
if test -z "${VE0CPUUNITS}"; then | |
echo "Warning: VE0CPUUNITS is not set in ${VZCONF}; using value of 1000" | |
VE0CPUUNITS=1000 | |
fi | |
msg=`${VZCTL} set 0 --cpuunits ${VE0CPUUNITS} 2>&1` | |
if [ $? -ne 0 ]; then | |
print_failure "vzctl set 0 --cpuunits ${VE0CPUUNITS} failed: $msg" | |
fi | |
if ! test -f "${CONFIG_DIR}/0.conf"; then | |
return | |
fi | |
if ! grep -q '^ONBOOT=yes\|^ONBOOT=\"yes\"' ${CONFIG_DIR}/0.conf; | |
then | |
return | |
fi | |
__echo "Configure node UB resources: " | |
msg=`$VZCTL set 0 --reset_ub 2>&1` | |
print_result "$msg" | |
} | |
start_ves() | |
{ | |
local veid | |
local velist | |
local msg | |
local need_restart | |
need_restart="" | |
velist=$(vzlist -aH -octid,onboot -s-bootorder | | |
awk '$2 == "yes" {print $1}') | |
sysctl -q -w net.ipv4.route.src_check=0 | |
for veid in $velist; do | |
[ "${veid}" = "0" ] && continue | |
__echo "Starting CT ${veid}: " | |
if [ "x${VZFASTBOOT}" = "xyes" -a "x${DISK_QUOTA}" = "xyes" ]; | |
then | |
$VZQUOTA stat ${veid} >/dev/null 2>&1 | |
if [ $? -eq 6 ]; then | |
if $VZQUOTA show ${veid} 2>&1 | grep "vzquota : (warning) Quota is running" >/dev/null 2>&1; then | |
$VZQUOTA on ${veid} --nocheck >/dev/null 2>&1 | |
need_restart="${need_restart} ${veid}" | |
fi | |
fi | |
fi | |
msg=`$VZCTL start ${veid} 2>&1` | |
print_result "$msg" | |
done | |
for veid in ${need_restart}; do | |
__echo "Stopping CT ${veid}: " | |
$VZCTL stop ${veid} 2>&1 >/dev/null 2>&1 | |
print_result "$msg" | |
__echo "Starting CT ${veid}: " | |
msg=`$VZCTL start ${veid} 2>&1` | |
print_result "$msg" | |
done | |
} | |
stop_ves() | |
{ | |
local veid | |
local velist | |
local msg | |
local m | |
local mounts | |
local fail | |
local iter | |
local quota | |
local pids | |
if get_veinfo; then | |
get_parallel | |
for i in 0 1 2; do | |
iter=0; | |
pids= | |
velist=`awk '$1 != "VEID" && $1 != "Version:" {print $1}' ${VESTAT}` | |
for veid in $velist; do | |
echo "Shutting down CT $veid" | |
# Set fairsched parameters to maximum so | |
# CT will stop fast | |
$VZCTL set $veid --cpuunits 2000 --cpulimit 0 >/dev/null 2>&1 | |
$VZCTL --skiplock stop $veid >/dev/null 2>&1 & | |
pids="$pids $!" | |
iter=$(($iter+1)) | |
if [ ${iter} -gt ${PARALLEL} ]; then | |
for pid in ${pids}; do | |
wait ${pid} | |
done | |
pids= | |
iter=0 | |
fi | |
done | |
for pid in $pids; do | |
wait $pid | |
done | |
done | |
fi | |
iter=0 | |
fail=1 | |
while test $iter -lt 5 -a $fail -ne 0; do | |
fail=0 | |
mounts=`awk '{if ($3=="simfs") print $2}' /proc/mounts` | |
for m in $mounts; do | |
__echo "Unmounting CT area " | |
echo -n $m | |
msg=`umount $m 2>&1` | |
if [ $? -eq 0 ]; then | |
print_success | |
else | |
print_failure "$msg" | |
fail=$((fail+1)) | |
fuser -k -m ${m} > /dev/null 2>&1 | |
fi | |
done | |
iter=$(($iter+1)) | |
done | |
# turn quota off | |
quota=`awk -F: '/^[0-9]+:/{print $1}' /proc/vz/vzquota 2>/dev/null` | |
for m in ${quota}; do | |
__echo "Turn quota off for CT " | |
echo -n $m | |
msg=`vzquota off ${m} 2>&1` | |
print_result "$msg" | |
done | |
} | |
lockfile() | |
{ | |
local TEMPFILE="${1}.$$" | |
local LOCKFILE="${1}" | |
trap -- "rm -f ${LOCKFILE} ${TEMPFILE}" EXIT | |
echo $$ > ${TEMPFILE} 2> /dev/null || { | |
echo "Can't write to ${TEMPFILE}" | |
} | |
ln ${TEMPFILE} ${LOCKFILE} >/dev/null 2>&1 && { | |
rm -f ${TEMPFILE}; | |
return 0; | |
} | |
kill -0 `cat $LOCKFILE` >/dev/null 2>&1 && { | |
return 1; | |
} | |
ln ${TEMPFILE} ${LOCKFILE} >/dev/null 2>&1 && { | |
rm -f ${TEMPFILE}; | |
return 0; | |
} | |
rm -f ${LOCKFILE} | |
echo $$ > ${LOCKFILE} | |
return 0 | |
} | |
start() | |
{ | |
local veid | |
local velist | |
local msg | |
local mod | |
check_kernel | |
check_kernel_config | |
if ! lockfile $LOCKFILE; then | |
__echo "OpenVZ is locked" | |
print_failure | |
return 1 | |
fi | |
if [ -f ${SUBSYS_VZ} ]; then | |
__echo "OpenVZ already running" | |
print_failure | |
return 1 | |
fi | |
__echo "Starting OpenVZ: " | |
load_modules "${IPT_MODULES}" | |
for mod in $PRELOAD_MODULES; do | |
/sbin/modprobe -r $mod >/dev/null 2>&1 | |
/sbin/modprobe $mod >/dev/null 2>&1 | |
done | |
for mod in $MODULES; do | |
/sbin/modprobe $mod >/dev/null 2>&1 | |
RETVAL=$? | |
if [ $RETVAL -ne 0 ]; then | |
print_failure "failed to load module ${mod}" | |
return $RETVAL | |
fi | |
done | |
load_modules "${MODULES_OTHER} ${VZFS_MODULES}" | |
print_success "loading OpenVZ modules" | |
if [ ! -e /dev/vzctl ]; then | |
# On most modern distros udev will create a device for you, | |
# while on the old distros /dev/vzctl comes with vzctl rpm. | |
# So the below mknod call is probably not needed at all. | |
/bin/mknod -m 600 /dev/vzctl c 126 0 > /dev/null 2>&1 | |
RETVAL=$? | |
if [ $RETVAL -ne 0 ]; then | |
print_failure "creating /dev/vzctl" | |
return $RETVAL | |
fi | |
fi | |
start_net | |
setup_ve0 | |
start_ves | |
rm -f $LOCKFILE | |
touch $SUBSYS_VZ | |
} | |
stop() | |
{ | |
local mod | |
if ! lockfile $LOCKFILE; then | |
__echo "OpenVZ is locked" | |
print_failure | |
RETVAL=1 | |
return 1 | |
fi | |
stop_ves | |
stop_net | |
__echo "Stopping OpenVZ: " | |
for mod in ${MODULES_OTHER} ${MODULES} ${PRELOAD_MODULES} ${IPT_MODULES} ${VZFS_MODULES}; do | |
/sbin/modprobe -r ${mod} > /dev/null 2>&1 | |
done | |
rm -f $LOCKFILE | |
rm -f $SUBSYS_VZ | |
print_success | |
} | |
load_modules() | |
{ | |
local modules=$1 | |
local mod | |
for mod in ${modules}; do | |
if /sbin/lsmod | grep -qw ${mod}; then | |
continue | |
fi | |
/sbin/modprobe ${mod} >/dev/null 2>&1 | |
done | |
} | |
# See how we were called. | |
case "$1" in | |
start) | |
start | |
;; | |
stop) | |
stop | |
;; | |
restart|force-reload) | |
stop | |
start | |
;; | |
status) | |
status | |
RETVAL=$? | |
;; | |
*) | |
echo "Usage: $0 {start|stop|status|restart|force-reload}" | |
exit 1 | |
esac | |
exit $RETVAL |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment