| #!/bin/sh |
| # Copyright (C) 2000-2007 SWsoft. 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 |
| |
| ### |
| # chkconfig: 2345 96 88 |
| # description: OpenVZ startup script. |
| ### |
| |
| ### BEGIN INIT INFO |
| # Provides: vz |
| # required-start: $network $remote_fs $local_fs sshd |
| # required-stop: |
| # Default-Start: 2 3 5 |
| # Default-Stop: |
| # Description: OpenVZ startup script. |
| ### END INIT INFO |
| |
| |
| # This line is needed to cheat /etc/init.d/rc who expects action word |
| |
| VZCONF=@PKGCONFDIR@/vz.conf |
| |
| [ -f ${VZCONF} ] || exit 0 |
| . ${VZCONF} |
| [ "${VIRTUOZZO}" = "no" ] && exit 0 |
| |
| VZCTL=@SBINDIR@/vzctl |
| VZQUOTA=@SBINDIR@/vzquota |
| LOCKFILE=/var/lock/subsys/vz_lock |
| SUBSYS_VZ=/var/lock/subsys/vz |
| VESTAT=/proc/vz/vestat |
| PRELOAD_MODULES= |
| MODULES= |
| MODULES_OTHER= |
| NET_MODULES= |
| IPT_MODULES= |
| |
| [ -x ${VZCTL} ] || exit 0 |
| |
| VZDEV=venet0 |
| if [ "${MODULES_DISABLED}" != "yes" ]; then |
| PRELOAD_MODULES="af_packet" |
| MODULES="vzmon vzdquota vzdev" |
| CPT_MODULES="vzcpt vzrst" |
| VETH_MODULES="vzethdev" |
| MODULES_OTHER="vzcompat ${CPT_MODULES} ${VETH_MODULES}" |
| NET_MODULES="vznetdev vznet" |
| if [ "${VZWDOG}" = "yes" ]; then |
| MODULES="${MODULES} vzwdog" |
| fi |
| IPT_MODULES="ip_tables ${IPTABLES} xt_tcpudp" |
| fi |
| |
| CONFIG_DIR=@PKGCONFDIR@/conf |
| |
| rc_done='..done' |
| rc_failed='..failed' |
| # Source function library. |
| if [ -r /etc/init.d/functions ]; then |
| source /etc/init.d/functions |
| if [ -r /etc/redhat-release ] || [ -r /etc/centos-release ]; then |
| DISTR=redhat |
| fi |
| elif [ -r /etc/rc.status ]; then |
| source /etc/rc.status |
| if [ -r /etc/SuSE-release ]; then |
| DISTR=suse |
| fi |
| fi |
| |
| VEINFO="" |
| RETVAL=0 |
| # Number of the parallel VEs on stop. |
| # In case empty value the number of parallel VEs calculated as 'num_cpu * 4' |
| PARALLEL= |
| cd / |
| |
| # We used to install OpenVZ cron job when the vzctl package was |
| # installed, irrespective of whether OpenVZ was actually being |
| # run. Although the cron jobs didn't create any problems if someone |
| # wasn't running OpenVZ some users complained about the cron log file |
| # filling up, resource usage, and power consumption since systems |
| # wouldn't really idle. It really only makes sense to run the OpenVZ |
| # cron job if the vz service is turned on and not just merely |
| # having the package installed. This init.d script is an obvious place |
| # to install or remove the cron jobs based on the service |
| # being enabled or not. |
| SRC_CRONSCRIPT_DIR=@CRONDDIR@ |
| DST_CRONSCRIPT_DIR=@DST_CRONDDIR@ |
| |
| setup_cron() |
| { |
| [ -z "$SRC_CRONSCRIPT_DIR" ] && return |
| [ -d "$SRC_CRONSCRIPT_DIR" ] || return |
| install -m644 -o root -g root $SRC_CRONSCRIPT_DIR/vz \ |
| $DST_CRONSCRIPT_DIR |
| } |
| |
| remove_cron() |
| { |
| [ -z "$SRC_CRONSCRIPT_DIR" ] && return |
| [ -d "$SRC_CRONSCRIPT_DIR" ] || return |
| cat > $DST_CRONSCRIPT_DIR/vz <<EOF |
| # DO NOT EDIT THIS FILE! |
| # |
| # Contents of this file managed by /etc/init.d/vz script |
| # Master copy is $SRC_CRONSCRIPT_DIR/vz. |
| # Consult that file for documentation. |
| EOF |
| } |
| |
| get_kern_ver() |
| { |
| local ver=$1 |
| |
| set -- $(IFS='.-'; echo ${ver}) |
| echo $(((($1 * 256) + $2) * 256 + $3)) |
| } |
| |
| 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 |
| } |
| |
| print_success() |
| { |
| if [ "$DISTR" = "redhat" ]; then |
| echo_success |
| else |
| echo -n "$rc_done" |
| fi |
| echo |
| } |
| |
| print_failure() |
| { |
| echo -n "$1" |
| if [ "$DISTR" = "redhat" ]; then |
| failure $"$1" |
| else |
| echo -n "$rc_failed" |
| fi |
| echo |
| } |
| |
| __echo() |
| { |
| if [ "$DISTR" = "redhat" ]; then |
| echo -n $"$1" |
| else |
| echo -n "$1" |
| fi |
| } |
| |
| status() |
| { |
| local base=${0##*/} |
| if get_veinfo; then |
| echo "OpenVZ is running..." |
| return 0 |
| else |
| echo "OpenVZ is stopped." |
| return 3 |
| fi |
| } |
| |
| setup_net() |
| { |
| local mod |
| |
| if ip a l | grep -q "venet0:.*UP" 2>/dev/null; then |
| return 0 |
| fi |
| for mod in ${NET_MODULES}; do |
| modprobe ${mod} 2>/dev/null |
| done |
| get_veinfo |
| if [ -z "$VEINFO" ]; then |
| return 0 |
| fi |
| __echo "Bringing up interface $VZDEV: " |
| ip link set $VZDEV up |
| if [ $? -eq 0 ] ; then |
| print_success |
| else |
| print_failure |
| fi |
| ip addr add 0.0.0.0/0 dev $VZDEV |
| __echo "Configuring interface $VZDEV: " |
| sysctl -w net.ipv4.conf.$VZDEV.send_redirects=0 >/dev/null |
| if [ $? -eq 0 ] ; then |
| print_success |
| else |
| print_failure |
| fi |
| if [ "${IPV6}" = "yes" ]; then |
| __echo "Configuring ipv6 $VZDEV: " |
| # Fix me: ip addres should be generated |
| ip -6 addr add fe80::1/128 dev $VZDEV |
| if [ $? -eq 0 ] ; then |
| print_success |
| else |
| print_failure |
| fi |
| fi |
| } |
| |
| hn_setup() |
| { |
| 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` |
| if [ $? -eq 0 ]; then |
| print_success |
| else |
| print_failure "$msg" |
| fi |
| } |
| |
| ve_start() |
| { |
| local veid |
| local velist |
| local msg |
| local need_restart |
| |
| need_restart="" |
| cd ${CONFIG_DIR} || return |
| velist=`grep -l '^ONBOOT=yes\|^ONBOOT=\"yes\"' [0-9]*.conf 2>/dev/null | \ |
| sed -e 's/.conf//g' | sort -n` |
| cd - >/dev/null |
| echo "0" > /proc/sys/net/ipv4/route/src_check |
| for veid in $velist; do |
| [ "${veid}" = "0" ] && continue |
| __echo "Starting VE ${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` |
| if [ $? -eq 0 ]; then |
| print_success |
| else |
| print_failure "$msg" |
| fi |
| done |
| for veid in ${need_restart}; do |
| __echo "Stopping VE ${veid}: " |
| $VZCTL stop ${veid} 2>&1 >/dev/null 2>&1 |
| if [ $? -eq 0 ]; then |
| print_success |
| else |
| print_failure "$msg" |
| fi |
| __echo "Starting VE ${veid}: " |
| msg=`$VZCTL start ${veid} 2>&1` |
| if [ $? -eq 0 ]; then |
| print_success |
| else |
| print_failure "$msg" |
| fi |
| done |
| } |
| |
| ve_stop() |
| { |
| 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 = 0; i <= 2; i++)); do |
| iter=0; |
| pids= |
| velist=`awk '$1 != "VEID" && $1 != "Version:" {print $1}' ${VESTAT}` |
| for veid in $velist; do |
| echo "Shutting down VE $veid" |
| # Set fairsched parameters to maximum so |
| # VE will stop fast |
| $VZCTL set $veid --cpuunits 2000 --cpulimit 0 >/dev/null 2>&1 |
| $VZCTL --skiplock stop $veid >/dev/null 2>&1 & |
| pids="$pids $!" |
| let iter++ |
| 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 VE 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 VE " |
| echo -n $m |
| msg=`vzquota off ${m} 2>&1` |
| if [ $? -eq 0 ]; then |
| print_success |
| else |
| print_failure "$msg" |
| fi |
| done |
| } |
| |
| lockfile() |
| { |
| local TEMPFILE="${1}.$$" |
| local LOCKFILE="${1}" |
| |
| 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 |
| |
| 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}" |
| 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 |
| __echo "creating vzctl device" |
| print_failure |
| return $RETVAL |
| fi |
| fi |
| |
| setup_net |
| hn_setup |
| setup_cron |
| ve_start |
| |
| rm -f $LOCKFILE |
| touch $SUBSYS_VZ |
| } |
| |
| stop() |
| { |
| if ! lockfile $LOCKFILE; then |
| __echo "OpenVZ is locked" |
| print_failure |
| RETVAL=1 |
| return 1 |
| fi |
| |
| ve_stop |
| remove_cron |
| __echo "Stopping OpenVZ: " |
| ip link set ${VZDEV} down 2>/dev/null |
| for MOD in $MODULES; do |
| /sbin/modprobe -r $MOD > /dev/null 2>&1 |
| done |
| for MOD in $PRELOAD_MODULES ${IPT_MODULES2} ${NET_MODULES}; do |
| /sbin/modprobe -r $MOD > /dev/null 2>&1 |
| done |
| print_success |
| rm -f $LOCKFILE |
| rm -f $SUBSYS_VZ |
| } |
| |
| 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) |
| stop |
| start |
| ;; |
| status) |
| status |
| RETVAL=$? |
| ;; |
| *) |
| echo "Usage: $0 {start|stop|status|restart}" |
| exit 1 |
| esac |
| |
| exit $RETVAL |
| |