| #!/sbin/runscript |
| # Copyright 1999-2005 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| # $Header: /var/www/viewcvs.gentoo.org/raw_cvs/gentoo-x86/sys-cluster/vzctl/files/vz-3.0.10.initd,v 1.2 2006/07/09 10:29:24 phreak Exp $ |
| |
| depend() { |
| after net vzeventd |
| } |
| |
| check_config() { |
| # if we don't want openvz running, say so |
| [ "${VIRTUOZZO}" = "yes" ] || return 1 |
| |
| # set default values |
| : ${VZCTL:=@SBINDIR@/vzctl} |
| : ${VZQUOTA:=@SBINDIR@/vzquota} |
| : ${VZVEINFO:=/proc/vz/veinfo} |
| : ${VESTAT:=/proc/vz/vestat} |
| : ${VPSCONFDIR:=@VPSCONFDIR@} |
| : ${VZREBOOTDIR:=@VZREBOOTDIR@} |
| : ${VZDEV:=venet0} |
| : ${VZCONF:=@PKGCONFDIR@/vz.conf} |
| : ${VE_STOP_MODE:=suspend} |
| |
| if [ "${MODULES_DISABLED}" != "yes" ]; then |
| : ${IPTABLES_MODULES:="${IPTABLES}"} |
| IPTABLES_MODULES="ip_tables ${IPTABLES_MODULES} xt_tcpudp" |
| : ${PRELOAD_MODULES:="af_packet"} |
| : ${MODULES:="vzmon vzdquota vzdev"} |
| : ${MIGRATE_MODULES:="vzcpt vzrst"} |
| : ${NET_MODULES:="vznetdev vznet vzethdev"} |
| : ${PLOOP_MODULES:="ploop pfmt_ploop1 pfmt_raw pio_direct pio_nfs pio_kaio"} |
| : ${MISC_MODULES:="vziolimit"} |
| |
| # check if you should load vzwdog module |
| [ "${VZWDOG}" = "yes" ] && MODULES="${MODULES} vzwdog" |
| fi |
| |
| # we need a working vzctl |
| if [ ! -x "${VZCTL}" ]; then |
| eerror "vzctl missing (${VZCTL})" |
| return 1 |
| fi |
| |
| if [ -z "${VE0CPUUNITS}" ]; then |
| ewarn "VE0CPUUNITS is not set in /etc/conf.d/vz; using default value of 1000" |
| VE0CPUUNITS=1000 |
| fi |
| return 0 |
| } |
| |
| mount_cgroups() |
| { |
| local g |
| for g in beancounter container fairsched ; do |
| if [ -d /proc/vz/$g ]; then |
| mount -t cgroup $g /proc/vz/$g -o name=$g 2>/dev/null |
| fi |
| done |
| } |
| |
| unmount_cgroups() |
| { |
| local g |
| for g in beancounter container fairsched ; do |
| umount /proc/vz/$g 2>/dev/null |
| done |
| } |
| |
| setup_ve0() { |
| local msg ve0conf="${VPSCONFDIR}/0.conf" |
| |
| mount_cgroups |
| |
| if ! msg=$(${VZCTL} set 0 --cpuunits ${VE0CPUUNITS} 2>&1); then |
| ewarn "vzctl set 0 --cpuunits ${VE0CPUUNITS} failed: ${msg}" |
| fi |
| |
| test -f ${ve0conf} || return |
| grep -Eq '^ONBOOT=yes\|^ONBOOT=\"yes\"' ${ve0conf} || return |
| |
| ebegin "Configuring hardware node UB resources" |
| msg=$(${VZCTL} set 0 --reset_ub 2>&1) |
| eend $? ${msg} |
| } |
| |
| start_net() { |
| local mod |
| |
| # load necessary modules |
| for mod in ${NET_MODULES}; do |
| modprobe ${mod} 2>/dev/null |
| done |
| |
| if [ ! -f ${VZVEINFO} ]; then |
| return 0 |
| fi |
| |
| # we don't operate on a running interface |
| if ip addr list | grep -q "venet0:.*UP" 2>/dev/null; then |
| return 0 |
| fi |
| |
| # configure the device |
| ebegin "Bringing up interface ${VZDEV}" |
| ip link set ${VZDEV} up |
| eend $? |
| |
| ip addr add 0.0.0.0/0 dev ${VZDEV} |
| |
| ebegin "Configuring interface ${VZDEV}" |
| sysctl -q -w net.ipv4.conf.${VZDEV}.send_redirects=0 |
| eend $? |
| |
| if [ "x$(sysctl -n -e net.ipv4.ip_forward)" != "x1" ]; then |
| ewarn "It looks like you have ip forwarding disabled. To make networking" |
| ewarn "available for containers, please, run sysctl -w net.ipv4.ip_forward=1" |
| fi |
| } |
| |
| stop_net() { |
| local mod |
| |
| if ip addr list | grep -q "venet0:.*UP" 2>/dev/null; then |
| ebegin "Bringing down interface ${VZDEV}" |
| ip link set ${VZDEV} down 2>/dev/null |
| eend $? |
| fi |
| |
| # remove all modules we probably loaded on start_net |
| for mod in ${NET_MODULES}; do |
| modprobe -r ${mod} > /dev/null 2>&1 |
| done |
| } |
| |
| start_ve() { |
| local veid velist msg iter=0 pid pids need_restart="" |
| |
| # CTs that were running before a reboot |
| velist=$(ls $VZREBOOTDIR) |
| rm -f $VZREBOOTDIR/* |
| # ... and not have ONBOOT=no |
| test -n "$velist" && velist=$(vzlist -aH -octid,onboot $velist | |
| awk '$2 != "no" {print $1}') |
| # ... plus ones with ONBOOT=yes |
| velist=$(echo "$velist"; vzlist -aH -octid,onboot | |
| awk '$2 == "yes" {print $1}') |
| # Then sort by bootorder |
| test -n "$velist" && velist=$(vzlist -aH -octid -s-bootorder $velist) |
| |
| sysctl -q -w net.ipv4.route.src_check=0 |
| |
| for veid in ${velist}; do |
| if [ "${VZFASTBOOT}" = "yes" -a "${DISK_QUOTA}" = "yes" ]; 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 |
| ${VZCTL} start ${veid} --skip-fsck 2>&1 & |
| pid=$! |
| eval VE_${pid}=${veid} |
| pids="${pids} $pid" |
| let iter++ |
| if [ ${iter} -ge ${VE_PARALLEL} ]; then |
| for pid in ${pids}; do |
| veid=`eval echo \\$VE_${pid}` |
| unset VE_${pid} |
| ebegin "Starting CT $veid" |
| wait ${pid} |
| eend $? |
| done |
| pids= |
| iter=0 |
| fi |
| done |
| |
| for pid in ${pids}; do |
| veid=`eval echo \\$VE_${pid}` |
| unset VE_${pid} |
| ebegin "Starting CT $veid" |
| wait ${pid} |
| eend $? |
| done |
| |
| for veid in ${need_restart}; do |
| ebegin "Stopping CT ${veid}" |
| msg=$(${VZCTL} stop ${veid}) |
| eend $? "${msg}" |
| |
| ebegin "Starting CT ${veid}" |
| msg=$($VZCTL start ${veid} 2>&1) |
| eend $? "${msg}" |
| done |
| |
| # we're ok even if some CTs failed to start |
| return 0 |
| } |
| |
| get_parallel() |
| { |
| [ -n "${VE_PARALLEL}" -a "${VE_PARALLEL}" != "0" ] && return |
| VE_PARALLEL=`awk ' |
| BEGIN { num=0; } |
| $1 == "processor" { num++; } |
| END { print num * 4; }' /proc/cpuinfo` |
| } |
| |
| stop_ve() { |
| local veid velist i iter pid pids stage stages msg |
| |
| if [ ! -f ${VESTAT} ]; then |
| return |
| fi |
| |
| # Pre-stop stage |
| rm -f $VZREBOOTDIR/* |
| velist=$(vzlist -1 2>/dev/null) |
| for veid in $velist; do |
| # Equalize cpuunits for all CTs |
| $VZCTL set $veid --cpuunits 2000 >/dev/null 2>&1 |
| # Save to vzreboot list |
| touch $VZREBOOTDIR/$veid |
| done |
| get_parallel |
| stages="stop" |
| [ "$VE_STOP_MODE" = "suspend" ] && stages="suspend stop" |
| for stage in $stages; do |
| case $stage in |
| suspend) |
| msg='Suspending CT' |
| ;; |
| stop) |
| msg='Shutting down CT' |
| ;; |
| esac |
| for ((i = 0; i <= 2; i++)); do |
| iter=0 |
| pids= |
| velist=$(vzlist -H -o ctid -sbootorder 2>/dev/null) |
| for veid in ${velist}; do |
| if [ "$stage" = "stop" ]; then |
| # Unset limits for CT to stop fast |
| $VZCTL set $veid --cpulimit 0 --iolimit 0 --iopslimit 0 >/dev/null 2>&1 |
| fi |
| ${VZCTL} --skiplock $stage ${veid} >/dev/null 2>&1 & |
| pid=$! |
| eval VE_${pid}=${veid} |
| pids="${pids} $pid" |
| let iter++ |
| if [ ${iter} -ge ${VE_PARALLEL} ]; then |
| for pid in ${pids}; do |
| veid=`eval echo \\$VE_${pid}` |
| unset VE_${pid} |
| ebegin "$msg $veid" |
| wait ${pid} |
| eend $? |
| done |
| pids= |
| iter=0 |
| fi |
| done |
| |
| for pid in ${pids}; do |
| veid=`eval echo \\$VE_${pid}` |
| unset VE_${pid} |
| ebegin "$msg $veid" |
| wait ${pid} |
| eend $? |
| done |
| done |
| done |
| } |
| |
| unmount_ve() { |
| local iter=0 |
| local fail=1 |
| local m mounts msg quota |
| |
| while [ ${iter} -lt 5 -a ${fail} -ne 0 ]; do |
| fail=0 |
| mounts=$(awk '{if ($3=="simfs") print $2}' /proc/mounts) |
| |
| for m in ${mounts}; do |
| ebegin "Unmounting CT area ${m}" |
| msg=$(umount ${m} 2>&1) |
| r=$? |
| eend $r "${msg}" |
| if [ $r -ne 0 ]; then |
| let fail++ |
| fuser -k -m ${m} > /dev/null 2>&1 |
| fi |
| done |
| |
| let iter++ |
| done |
| |
| # turn quota off |
| quota=$(awk -F: '/^[0-9]+:/{print $1}' /proc/vz/vzquota 2>/dev/null) |
| |
| for m in ${quota}; do |
| ebegin "Turning quota off for CT ${m}" |
| msg=$(vzquota off ${m} 2>&1) |
| eend $? "${msg}" |
| done |
| } |
| |
| start() { |
| check_config || return |
| |
| local mod rc |
| |
| ebegin "Loading OpenVZ modules" |
| for mod in ${IPTABLES_MODULES}; do |
| modprobe ${mod} >/dev/null 2>&1 |
| done |
| |
| for mod in ${PRELOAD_MODULES}; do |
| modprobe -r ${mod} >/dev/null 2>&1 |
| modprobe ${mod} >/dev/null 2>&1 |
| done |
| |
| for mod in ${MODULES}; do |
| modprobe ${mod} >/dev/null 2>&1 |
| rc=$? |
| if [ ${rc} -ne 0 ]; then |
| eend ${rc} "failed to load module ${mod}" |
| return ${rc} |
| fi |
| done |
| |
| for mod in ${MIGRATE_MODULES} ${PLOOP_MODULES} ${MISC_MODULES}; do |
| modprobe ${mod} >/dev/null 2>&1 |
| done |
| eend |
| |
| if [ ! -e /dev/vzctl ]; then |
| eerror "Missing device node /dev/vzctl" |
| einfo |
| einfo "Please create the vzctl device node using the following command:" |
| einfo " /bin/mknod /dev/vzctl c 126 0" |
| einfo |
| return 1 |
| fi |
| |
| if [ -f /proc/vz/oom_score_adj ]; then |
| ebegin "Applying OOM adjustments" |
| cat /etc/vz/oom-groups.conf > /proc/vz/oom_score_adj |
| eend $? |
| fi |
| |
| start_net |
| setup_ve0 |
| start_ve |
| # Try to run vzstats to submit new kernel info |
| vzstats >/dev/null 2>&1 |
| } |
| |
| stop() { |
| check_config || return |
| |
| # Avoid stop action inside a CT, check we are in CT0 |
| if test -r /proc/user_beancounters; then |
| if ! grep -Fq '^[[:space:]]*0:[[:space:]]' \ |
| /proc/user_beancounters; then |
| eerror "Looks like we are inside a container!" |
| return 1 |
| fi |
| fi |
| |
| local mod |
| |
| stop_ve |
| unmount_ve |
| unmount_cgroups |
| stop_net |
| |
| for mod in ${MIGRATE_MODULES} ${PLOOP_MODULES} ${MISC_MODULES}; do |
| modprobe -r ${mod} > /dev/null 2>&1 |
| done |
| |
| for mod in ${MODULES}; do |
| modprobe -r ${mod} > /dev/null 2>&1 |
| done |
| |
| for mod in ${PRELOAD_MODULES}; do |
| modprobe -r ${mod} > /dev/null 2>&1 |
| done |
| |
| # Even if some modules failed to unload (say they were not loaded) |
| # we return 0 for the service to be marked as stopped. |
| return 0 |
| } |