# $VSERVER_NAME ... name of vserver
declare -a NICE_CMD=()
+declare -a IONICE_CMD=()
declare -a CHBIND_CMD=()
declare -a CAP_OPTS=()
declare -a CHCONTEXT_INIT_OPTS=()
declare -a OPTS_VTAG_CREATE=()
declare -a OPTS_VTAG_ENTER=()
declare -a OPTS_VMEMCTRL=()
+declare -a OPTS_VSPACE=()
declare -a STOPCMD_PREPARE=()
INITSTYLE=sysv
S_CONTEXT=
+N_CONTEXT=
SILENT_OPT=
f="$vdir"/interfaces/lback
getFileValue lback "$f"
- getFileValue nid "$vdir/ncontext" "$vdir/context"
-
- CHBIND_CMD=( $_CHBIND $SILENT_OPT --secure ${nid:+--nid "$nid"}
+ CHBIND_CMD=( $_CHBIND $SILENT_OPT --secure ${N_CONTEXT:+--nid "$N_CONTEXT"}
${bcast:+--bcast "$bcast"} ${lback:+--lback "$lback"}
)
NICE_CMD=( $_NICE -n $nice )
}
+function _generateIONiceCommand
+{
+ local vdir=$1
+ local ionice_class=2
+ local ionice_priority=0
+
+ test -r "$vdir/ionice/class" && read ionice_class <"$vdir"/ionice/class
+ test -r "$vdir/ionice/priority" && read ionice_priority <"$vdir"/ionice/priority
+
+ IONICE_CMD=( $_IONICE -c$ionice_class -n$ionice_priority )
+}
function _generatePersonalityOptions
{
(xgentoo)
test -n "$RUNLEVEL_START" || RUNLEVEL_START="default"
+ RC_PATH=/usr/sbin:/usr/bin:/sbin:/bin
+
+ if test -x "$vdir/vdir/lib/rcscripts/sh/init-vserver.sh"; then
+ RC_WRAP=/lib/rcscripts/sh/init-vserver.sh
+ elif test -x "$vdir/vdir/lib/rc/sh/init-vserver.sh"; then
+ RC_WRAP=/lib/rc/sh/init-vserver.sh
+ else
+ panic "init-vserver.sh not found; aborting"
+ fi
- INITCMD_START=( env TERM=$TERM /lib/rcscripts/sh/init-vserver.sh "$RUNLEVEL_START" )
- INITCMD_STOP=( env -i TERM=$TERM RUNLEVEL=0 /sbin/rc shutdown )
+ INITCMD_START=( env TERM=$TERM $RC_WRAP "$RUNLEVEL_START" )
+ INITCMD_STOP=( env -i PATH=$RC_PATH TERM=$TERM RUNLEVEL=0 /sbin/rc shutdown )
INITCMD_PREPARE=( $_FAKE_RUNLEVEL 3 /var/run/utmp )
;;
return 0
}
+function _getTunInfo
+{
+ local iface="$1"
+
+ test -e "$iface/tun" -o -e "$iface/tap" || return 1
+ test ! -e "$iface/tun" || echo --tun
+ test ! -e "$iface/tap" || echo --tap
+ test ! -e "$iface/nocsum" || echo --~checksum
+ test -e "$iface/shared" || echo --nid-failure-ok "$N_CONTEXT"
+ if test -e "$iface/uid"; then
+ local uid
+ getFileValue uid "$iface/uid"
+ echo --uid "$uid"
+ fi
+ if test -e "$iface/gid"; then
+ local gid
+ getFileValue gid "$iface/gid"
+ echo --gid "$gid"
+ fi
+ if test -e "$iface/linktype"; then
+ local linktype
+ getFileValue linktype "$iface/linktype"
+ echo --linktype "$linktype"
+ fi
+ return 0
+}
+
## Usage: _processSingleInterface <interface-directory>
function _processSingleInterface
{
local mac
local extip
local up="up"
+ local peer
_getInterfaceValue ip '' "$iface"
_getInterfaceValue extip '' "$iface" "$iface/.."
_getInterfaceValue name '' "$iface"
_getInterfaceValue scope '' "$iface" "$iface/.."
_getInterfaceValue mac '' "$iface"
+ _getInterfaceValue peer '' "$iface"
test -n "$ip" || { echo $"Can not read ip for '$iface'" >&2; return 1; }
test -n "$dev" -o -e "$iface"/nodev || {
if ! test -e "$iface"/indirect; then
# XXX: IPv6 hack
- use_bcast="broadcast ${bcast:-+}"
+ local use_bcast="broadcast ${bcast:-+}"
echo "$ip" | $_GREP -q : && use_bcast=
- _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" $use_bcast ${name:+label "$dev:$name"} dev "$dev"
+
+ local tun_info
+ if tun_info=$(_getTunInfo "$iface"); then
+ _addInterfaceCmd TUNCTL "$dev" $tun_info
+ fi
+
+ _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" $use_bcast ${name:+label "$dev:$name"} dev "$dev" ${peer:+peer "$peer"}
#_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
_addInterfaceCmd IP_LINK "$dev" $up
- elif ! test -n "$ctx"; then
+ elif ! test -n "$N_CONTEXT"; then
echo $"Using 'dummy' (indirect) for interface '$dev' requires a fixed context number; dynamic ctx are not supported" >&2
return 1
else
- test -z "$mac" || _generateMac mac "$(basename $iface)" "$ctx" || return 1
+ test -z "$mac" || _generateMac mac "$(basename $iface)" "$N_CONTEXT" || return 1
_addInterfaceCmd MODPROBE dummy "$dev"
_addInterfaceCmd IP_LINK dev dummy0 address "$mac"
_addInterfaceCmd NAMEIF "$dev" "$mac"
_addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" dev "$dev"
- test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$ctx" "$extip"
+ test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$N_CONTEXT" "$extip"
fi
break
function _generateInterfaceOptions
{
local iface
- local ctx
- test ! -e "$1"/context || read ctx <"$1"/context
+ # XXX: This is here instead of in _generateChbindOptions
+ # to avoid a circular dependency
+ getFileValue N_CONTEXT "$1/ncontext" "$1/context"
+ test -n "$N_CONTEXT" -o -z "$S_CONTEXT" || N_CONTEXT="$S_CONTEXT"
for iface in "$1/interfaces/"*; do
test -d "$iface" || continue
IP_ADDR_FLUSH) $_IP addr flush "$@";;
IP_LINK) $_IP link set "$@";;
IP_ROUTE) $_IP route add "$@";;
+ TUNCTL)
+ local dev="$1"
+ shift
+ $_TUNCTL --persist "$@" "$dev"
+ ;;
*) echo "Unknown interface-command type '$type'" >&2; false;;
esac
IP_ADDR_FLUSH) ;;
IP_LINK) ;; ## Ignore the link-down command for now
IP_ROUTE) $_IP route del "$@";;
+ TUNCTL) $_TUNCTL --~persist "$1";;
*) echo "Unknown interface-command type '$type'" >&2; false;;
esac
done
function _generateMemctrlOptions
{
- local vdir="$"
+ local vdir="$1"
local badness
getFileValue badness "$vdir/badness"
OPTS_VMEMCTRL=( --badness "$badness" )
}
+function _generateSpaceOptions
+{
+ local vdir="$1"
+ local d="$vdir"/spaces
+
+ ( test ! -e "$d"/pid &&
+ ! $_VSERVER_INFO PIDSPACE FEATURE ) || \
+ OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --pid )
+
+ test ! -e "$d"/net || {
+ OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --net )
+ # network context and namespace don't make much sense
+ _HAVE_CHBIND_OPTIONS=1
+ CHBIND_CMD=()
+ }
+
+ local mask
+ getFileValue mask "$d"/mask || \
+ OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --mask "$mask" )
+}
+
## Usage: prepareInit <vserver-directory>
function prepareInit
{
_generateInterfaceOptions "$1"
test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
_generateNiceCommand "$1"
+ _generateIONiceCommand "$1"
_generateInitOptions "$1"
_generateChcontextOptions "$1"
_generateScheduleOptions "$1"
_generatePersonalityOptions "$1"
_generateTagOptions "$1"
_generateMemctrlOptions "$1"
+ _generateSpaceOptions "$1"
if test -n "$_IS_FAKEINIT"; then
CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
# these are things that have to be accessible post-cleanup
for i in "$root" "$__SBINDIR" "$__PKGLIBDIR" "$vdir" \
"$__PKGSTATEDIR" "$__LOCKDIR" /usr/local /tmp "${skip[@]}"; do
- local real=`readlink -f "$i"`
+ local real=`getPhysicalDir "$i"`
test "$i" != "$real" || real=
for j in "$i" "$real"; do
while test -n "$j"; do
done
local -a list_umount
- while read dev path opts; do
+ while read -r dev path opts; do
test -n "$path" || continue
for i in "$root" /dev /proc; do
test "${path#$i}" != "$path" && continue 2
done < /proc/mounts
# separate loop to avoid races while reading /proc/mounts
for i in "${list_umount[@]}"; do
- $_UMOUNT -l -n "$i"
+ $_UMOUNT -l -n -i "$i"
done
}