[Debian] Re: Bug#417540: fixes

Kir Kolyshkin kir at openvz.org
Fri Apr 13 11:59:21 EDT 2007


Ola Lundqvist wrote:
> Hi Kir
>
> On Fri, Apr 13, 2007 at 06:16:25PM +0400, Kir Kolyshkin wrote:
>   
>> I see two distinct problems described in this bug report:
>> 1. simfs not loaded
>> 2. (enhancement) check running kernel config
>>
>> Both are fixed in vzctl git.
>>
>> Check for kernel config options:
>> http://git.openvz.org/?p=vzctl;a=commit;h=8adf5dcc9dda2f621d6df7cec88ad6ab16bb5041
>>
>> Loading simfs module:
>> http://git.openvz.org/?p=vzctl;a=commit;h=f09fd723bbe70d98b772bd9d13fdf844d14cad59
>>     
>
> Thanks a lot for this information.
>
>   
>> Will be available in vzctl-3.0.17. The only thing I'm not sure about if 
>> this initscript (etc/init.d/vz-redhat.in) is used by Debian.
>>     
>
> Yes it is, but with a patch. Maybe you can include that as well? About half
> of it is compatible with redhat, but something need to be done about this
> subsys thing that do not exist in debian. Is that directory really needed?
>   
By Red Hat standards -- yes. But we can determine the distro runtime and 
fix the appropriate variables, can't we?

Can I rely on Debian having /etc/debian.version and 
/lib/lsb/init-functions (and not having /etc/init.d/functions and 
/etc/rc.status)?
If yes -- patch is attached for your review (against the latest vzctl 
git). For convenience, I'm also attaching the actual script.

> At least short description and force-reload should be possible to include
> in the RedHat version. :)
>
> The patch is as follows:
>
> --- vzctl-3.0.16.orig/etc/init.d/vz-redhat.in
> +++ vzctl-3.0.16/etc/init.d/vz-redhat.in
> @@ -1,4 +1,4 @@
> -#!/bin/sh
> +#!/bin/bash
>   

Why you change it to bash? Is there something bash-specific in the 
script? If yes, I'd like to kill it out.

>  #  Copyright (C) 2000-2007 SWsoft. All rights reserved.
>  #
>  #  This program is free software; you can redistribute it and/or modify
> @@ -30,6 +30,7 @@
>  # Default-Start: 2 3 5
>  # Default-Stop:
>  # Description: OpenVZ startup script.
> +# Short-Description: OpenVZ startup script
>  ### END INIT INFO
>                                                                                                                
>                                                                                                                
> @@ -43,7 +44,7 @@
>                                                                                                                
>  VZCTL=@SBINDIR@/vzctl
>  VZQUOTA=@SBINDIR@/vzquota
> -LOCKFILE=/var/lock/subsys/vz_lock
> +LOCKFILE=/var/lock/vz_lock
>  VESTAT=/proc/vz/vestat
>  PRELOAD_MODULES=
>  MODULES=
> @@ -422,7 +423,7 @@
>                 print_failure
>                 return 1
>         fi
> -       if [ -f /var/lock/subsys/vz ]; then
> +       if [ -f /var/lock/vz ]; then
>                 __echo "OpenVZ already running"
>                 print_failure
>                 return 1
> @@ -463,7 +464,7 @@
>         ve_start
>                                                                                                                
>         rm -f $LOCKFILE
> -       touch /var/lock/subsys/vz
> +       touch /var/lock/vz
>  }
>                                                                                                                
>  function stop()
> @@ -487,7 +488,7 @@
>         done
>         print_success
>         rm -f $LOCKFILE
> -       rm -f /var/lock/subsys/vz
> +       rm -f /var/lock/vz
>  }
>                                                                                                                
>  function load_modules()
> @@ -511,6 +512,10 @@
>    stop)
>         stop
>         ;;
> +  force-reload)
> +        stop
> +       start
> +        ;;
>    restart)
>         stop
>         start
>
>
> Regards,
>
> // Ola
>
>   
>
>   

-------------- next part --------------
A non-text attachment was scrubbed...
Name: debian-init-script.patch
Type: text/x-patch
Size: 1079 bytes
Desc: not available
Url : http://openvz.org/pipermail/debian/attachments/20070413/8890d3aa/debian-init-script-0001.bin
-------------- next part --------------
#!/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.
# Short-Description: OpenVZ startup script
### END INIT INFO


# This line is needed to cheat /etc/init.d/rc who expects action word

VZCONF=/home/kir/git-local/vzctl/inst/etc/vz/vz.conf

[ -f ${VZCONF}   ] || exit 0
. ${VZCONF}
[ "${VIRTUOZZO}" = "no" ] && exit 0

VZCTL=/home/kir/git-local/vzctl/inst/sbin/vzctl
[ -x ${VZCTL} ] || exit 0

VZQUOTA=/home/kir/git-local/vzctl/inst/sbin/vzquota
CONFIG_DIR=/home/kir/git-local/vzctl/inst/etc/vz/conf
LOCKFILE=/var/lock/subsys/vz_lock
SUBSYS_VZ=/var/lock/subsys/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"
	VZFS_MODULES="simfs"
fi


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
elif [ -r /lib/lsb/init-functions ]; then
	source /lib/lsb/init-functions
	if [ -f /etc/debian.version ]; then
		DISTR=debian
		LOCKFILE=/var/lock/vz_lock
		SUBSYS_VZ=/var/lock/vz
	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=/home/kir/git-local/vzctl/inst/etc/vz/cron
DST_CRONSCRIPT_DIR=/home/kir/git-local/vzctl/inst/etc/cron.d

check_old_cron_files()
{
	# avoid double OpenVZ cron settings
	local f
	for f in vpsreboot vpsnetclean; do
		[ -f $DST_CRONSCRIPT_DIR/$f ] && rm -f $DST_CRONSCRIPT_DIR/$f
	done
}

setup_cron()
{
	check_old_cron_files
	[ -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()
{
	check_old_cron_files
	[ -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
}

check_kernel()
{
	if ! [ test -d /proc/vz ]; then
		print_failure "Running kernel is not OpenVZ kernel."
		exit 1
	fi
}

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 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 '^#|^$') || return 0

	for opt in opt_must; do
		if ! echo "$conf" | grep -q "${opt}="; then
			__echo "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
}

print_success()
{
	if [ "$DISTR" = "redhat" ]; then
		echo_success
	elif [ "$DISTR" = "debian" ]; then
		: # do nothing
	else
		echo -n "$rc_done"
	fi
	echo
}

print_failure()
{
	if [ "$DISTR" = "debian" ]; then
		log_failure_msg $1
		return
	fi
	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()
{
	check_kernel

	if get_veinfo && [ -f $SUBSYS_VZ ]; then
		echo "OpenVZ is running..."
		return 0
	else
		echo "OpenVZ is stopped."
		return 3
	fi
}

start_net()
{
	local mod

	if ip a l | grep -q "venet0:.*UP" 2>/dev/null; then
		return 0
	fi
	# load all kernel modules needed for VE networking
	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 -q -w net.ipv4.conf.$VZDEV.send_redirects=0
	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
}

stop_net()
{
	local mod

	if ip a l | grep -q "venet0:.*UP" 2>/dev/null; then
		__echo "Bringing down interface $VZDEV: " 
		ip link set $VZDEV down 
		if [ $? -eq 0 ] ; then
			print_success
		else
			print_failure
		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`
	if [ $? -eq 0 ]; then
		print_success
	else
		print_failure "$msg"
	fi
}

start_ves()
{
	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
	sysctl -q -w net.ipv4.route.src_check=0
	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
}

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 = 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}"

	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
	setup_cron
	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
	remove_cron
	stop_net
	__echo "Stopping OpenVZ: "
	for mod in ${MODULES_OTHER} ${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
	;;
  force-reload)
	stop
	start
	;;
  restart)
	stop
	start
	;;
  status)
  	status
	RETVAL=$?
	;;
  *)
  	echo "Usage: $0 {start|stop|status|restart}"
	exit 1
esac

exit $RETVAL


More information about the Debian mailing list