3 # Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; version 2 of the License.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 # $VSERVER_DIR ... path to vserver-cfg dir
20 # $VSERVER_NAME ... name of vserver
22 declare -a NICE_CMD=()
23 declare -a CHBIND_OPTS=()
24 declare -a CAP_OPTS=()
25 declare -a CHCONTEXT_INIT_OPTS=()
26 declare -a CHCONTEXT_FLAG_OPTS=()
27 declare -a CHCONTEXT_OPTS=()
28 declare -a CAPCHROOT_OPTS=()
29 declare -a INTERFACES=()
31 declare -a INITCMD_RESCUE=( /bin/sleep 900 )
32 declare -a INITCMD_START=()
33 declare -a INITCMD_START_SYNC=()
34 declare -a INITCMD_STOP=()
35 declare -a INITCMD_STOP_SYNC=()
36 declare -a INITCMD_PREPARE=()
37 declare -a INITKILL_SEQ=()
38 declare -a ENTER_SHELL=()
40 declare -a OPTS_VCONTEXT_CREATE=()
41 declare -a OPTS_VCONTEXT_MIGRATE=()
42 declare -a OPTS_VCONTEXT_ENTER=()
43 declare -a OPTS_VATTRIBUTE=( --flag fakeinit )
44 declare -a OPTS_VSCHED=()
46 declare -a STOPCMD_PREPARE=()
48 declare -a VSERVER_EXTRA_CMDS=()
51 VSHELPER_SYNC_TIMEOUT=30
56 _HAVE_INTERFACE_OPTIONS=
67 : ${VSERVER_NAME:=$(basename "$VSERVER_DIR")}
69 if test -e "$VSERVER_DIR"/noisy -o -n "$OPTION_VERBOSE"; then
75 function _generateChbindOptions
82 test -n "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$vdir"
84 local f=$vdir/interfaces/bcast
85 getFileValue bcast "$f"
87 getFileValue nid "$vdir/ncontext" "$vdir/context"
89 CHBIND_OPTS=( $SILENT_OPT ${nid:+--nid "$nid"} ${bcast:+--bcast "$bcast"} )
91 for i in "${INTERFACES[@]}"; do
92 CHBIND_OPTS=( "${CHBIND_OPTS[@]}" --ip "$i" )
95 _HAVE_CHBIND_OPTIONS=1
98 function _generateNiceCommand
102 local current_nice=`$_NICE`
104 test -r "$vdir/nice" && read nice <"$vdir"/nice
106 let nice=$nice-$current_nice || :
107 NICE_CMD=( $_NICE -n $nice )
111 function _generatePersonalityOptions
114 local f="$vdir"/personality
117 test -s "$f" || return 0
126 (*) flags=$flags$delim$tmp
133 OPTS_VCONTEXT_ENTER=( "${OPTS_VCONTEXT_ENTER[@]}"
134 --personality-type "$type"
135 ${flags:+--personality-flags "$flags"} )
138 function _generateCCapabilityOptions
142 local f="$vdir"/ccapabilities
144 test -e "$f" || return 0
148 (*) OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --ccap "$cap" );;
153 function _generateBCapabilityOptions
157 local f="$vdir"/bcapabilities
159 test -e "$f" || return 0
163 (*) OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --bcap "$cap" );;
168 function _generateCapabilityOptions
173 _generateBCapabilityOptions "$vdir"
174 _generateCCapabilityOptions "$vdir"
176 test -e "$vdir"/capabilities || return 0
185 CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" )
186 CAPCHROOT_OPTS=( "${CAPCHROOT_OPTS[@]}" --nochroot )
189 CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" )
192 done <"$vdir"/capabilities
195 function getEnterShell
202 getFileValue ENTER_SHELL "$vdir"/shell "$__CONFDIR"/.defaults/shell
204 test -n "$ENTER_SHELL" || {
206 for i in "/bin/bash -login" "/bin/sh -l" /bin/csh; do
208 test -x "$vdir/vdir/$1" || continue
215 ## Usage: sendKillSequence <ctx> <signal> [<wait> <signal>]*
216 function sendKillSequence
222 while isCtxRunning "$ctx"; do
223 test -z "$wait" || sleep "$wait"
225 killContext "$ctx" "$1"
226 test -n "$2" || break
232 function _generateInitOptions
235 local cfgdir=$vdir/apps/init
240 INITCMD_START_SYNC=()
245 INITKILL_SEQ=( 15 5 9 )
246 CHCONTEXT_INIT_OPTS=()
249 getFileValue INITSTYLE "$cfgdir"/style
250 getFileValue RUNLEVEL_START "$cfgdir"/runlevel
251 getFileValue RUNLEVEL_START "$cfgdir"/runlevel.start
252 getFileValue RUNLEVEL_STOP "$cfgdir"/runlevel.stop
253 getFileArray INITKILL_SEQ "$cfgdir"/killseq || :
255 case x"$INITSTYLE" in
257 INITCMD_START=( "${INITCMD_RESCUE[@]}" )
258 INITCMD_STOP=( /sbin/killall5 )
264 test -n "$RUNLEVEL_START" || RUNLEVEL_START=3
265 test -n "$RUNLEVEL_STOP" || RUNLEVEL_STOP=6
267 for i in /etc/init.d/rc /etc/rc.d/rc; do
268 test -x "$vdir/vdir/$i" || continue
269 INITCMD_START=( "$i" "$RUNLEVEL_START" )
270 INITCMD_STOP=( "$i" "$RUNLEVEL_STOP" )
272 INITCMD_PREPARE=( $_FAKE_RUNLEVEL "$RUNLEVEL_START" /var/run/utmp )
276 INITCMD_START=( /sbin/init )
277 INITCMD_STOP=( /sbin/init )
279 _NEED_VSHELPER_SYNC=1
280 test -z "$RUNLEVEL_START" || INITCMD_START=( "${INITCMD_START[@]}" "$RUNLEVEL_START" )
281 test -z "$RUNLEVEL_STOP" || INITCMD_STOP=( "${INITCMD_STOP[@]}" "$RUNLEVEL_STOP" )
285 INITCMD_START=( /sbin/minit-start )
286 INITCMD_STOP=( /sbin/minit-stop )
288 INITCMD_START_SYNC=( "$_INITSYNC_MINIT_START" "$vdir" )
289 _NEED_VSHELPER_SYNC=1
290 test -z "$RUNLEVEL_START" || INITCMD_START=( "${INITCMD_START[@]}" "$RUNLEVEL_START" )
291 test -z "$RUNLEVEL_STOP" || INITCMD_STOP=( "${INITCMD_STOP[@]}" "$RUNLEVEL_STOP" )
292 ! isNumber "${RUNLEVEL_START:-3}" || INITCMD_PREPARE=( $_FAKE_RUNLEVEL "${RUNLEVEL_START:-3}" /var/run/utmp )
296 panic "init-style '$INITSTYLE' is no longer supported; please use plain instead; aborting";;
299 (*) panic "Unknown init-style '$INITSTYLE'; aborting";;
302 if test x"$INITSTYLE" != xrescue; then
303 getFileArray INITCMD_START "$cfgdir"/cmd.start || :
304 getFileArray INITCMD_STOP "$cfgdir"/cmd.stop || :
305 getFileArray INITCMD_START_SYNC "$cfgdir"/cmd.start-sync || :
306 getFileArray INITCMD_STOP_SYNC "$cfgdir"/cmd.stop-sync || :
307 getFileArray INITCMD_PREPARE "$cfgdir"/cmd.prepare || :
310 test -n "$OPTION_FORCE_SYNC" -o -e "$cfgdir"/sync || {
311 INITCMD_START_SYNC=()
316 if vshelper.isEnabled; then
317 vshelper.getSyncTimeout "$vdir" VSHELPER_SYNC_TIMEOUT || :
323 function _generateFlagOptions
327 CHCONTEXT_FLAG_OPTS=()
329 test ! -e "$vdir"/flags || \
338 OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --flag "$flag" )
339 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}"
345 isAvoidNamespace "$vdir" || {
347 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}" --flag namespace )
351 function _generateChcontextOptions
354 local ctx hostname domainname
359 read ctx <"$vdir"/context || :
361 read hostname <"$vdir"/uts/nodename || read hostname <"$vdir"/hostname || :
362 read domainname <"$vdir"/uts/domainname || read domainname <"$vdir"/domainname || :
365 test -z "$S_CONTEXT" || ctx=$S_CONTEXT
367 _generateCapabilityOptions "$vdir"
368 _generateFlagOptions "$vdir"
370 CHCONTEXT_OPTS=( $SILENT_OPT \
371 "${CHCONTEXT_FLAG_OPTS[@]}" \
374 ${ctx:+--ctx "$ctx"} \
375 ${hostname:+--hostname "$hostname"} \
376 ${domainname:+--domainname "$domainname"} )
378 OPTS_VCONTEXT_CREATE=( $SILENT_OPT \
379 ${ctx:+--xid "$ctx"} )
380 ## put '--secure' at front so that it can be overridden
381 OPTS_VATTRIBUTE=( --secure --flag default "${OPTS_VATTRIBUTE[@]}" )
384 function _generateScheduleOptions
387 local f="$vdir"/schedule
388 test -e "$f" || return 0
390 local fill_rate interval tokens tokens_min tokens_max prio_bias
398 read prio_bias || prio_bias=
402 test -n "$prio_bias" || {
403 echo $"Bad content in '$f'; aborting..." >&2
407 OPTS_VSCHED=( --fill-rate "$fill_rate" --interval "$interval" \
408 --tokens "$tokens" --tokens_min "$tokens_min" \
409 --tokens_max "$tokens_max" --priority-bias "$prio_bias" )
412 function _getInterfaceValue
422 read _giv_tmp <"$_giv_i/$_giv_val" && break || :
425 : ${_giv_tmp:=$_giv_dflt}
426 eval $_giv_val=\$_giv_tmp
429 ## Usage: _transformMask2Prefix <result-varname> <prefix> <mask>
430 function _transformMask2Prefix
434 test -n "$_tm2p_tmp" || {
435 $_MASK2PREFIX "$3" || _tm2p_tmp=$?
442 function _addInterfaceCmd
444 eval INTERFACE_CMDS_${INTERFACE_CMDS_IDX}='( "$@" )'
445 let ++INTERFACE_CMDS_IDX
448 ## Usage: _generateMac <var> <iface> <ctx>
449 function _generateMac
452 echo $"Interface basename '$iface' must be either a number, or the mac must be configured explicitly" >&2
456 eval $1=$(printf "f0:ff:%02x:%02x:%02x:%02x" $[ (~($2>>8)) & 0xff ] $[ ($2 & 0xff) ] $[ ($3>>8) & 0xff ] $[ $3 & 0xff ])
459 function _getVLANInfo
464 creation of VLAN_PLUS_VID devices is not supported; please create them
465 before starting the vserver and use the 'nodev' flag then"
466 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID"
470 creation of VLAN_PLUS_VID_NO_PAD devices is not supported; please
471 create them before starting the vserver and use the 'nodev' flag then"
472 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID_N0_PAD"
474 (*.????) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID";;
475 (*.*) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID_NO_PAD";;
482 ## Usage: _processSingleInterface <interface-directory>
483 function _processSingleInterface
498 _getInterfaceValue ip '' "$iface"
499 _getInterfaceValue extip '' "$iface" "$iface/.."
500 _getInterfaceValue dev '' "$iface" "$iface/.."
501 _getInterfaceValue prefix '' "$iface" "$iface/.."
502 _getInterfaceValue mask '' "$iface" "$iface/.."
503 _getInterfaceValue bcast '' "$iface" "$iface/.."
504 _getInterfaceValue name '' "$iface"
505 _getInterfaceValue scope '' "$iface" "$iface/.."
506 _getInterfaceValue mac '' "$iface"
508 test -n "$ip" || { echo $"Can not read ip for '$iface'" >&2; return 1; }
509 test -n "$dev" -o -e "$iface"/nodev || {
510 echo $"No device specified for '$iface'" >&2
514 test ! -e "$iface"/down || up=
517 _transformMask2Prefix prefix "$prefix" "$mask"
518 INTERFACES=( "${INTERFACES[@]}" "$ip${prefix:+/$prefix}" )
520 test ! -e "$iface"/nodev || break
522 test ! -e "$iface"/only_ip || break
525 if vlan_info=$(_getVLANInfo "$dev"); then
526 test -d /proc/net/vlan || {
527 echo -e $"VLAN device-name used, but vlan subsystem not enabled.\nTry to execute 'modprobe 8021q' before starting the vservers" >&2
530 test -f /proc/net/vlan -o -e "$iface"/novlandev || {
531 _addInterfaceCmd VCONFIG $vlan_info
535 if ! test -e "$iface"/indirect; then
536 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" broadcast ${bcast:-+} ${name:+label "$dev:$name"} dev "$dev"
537 #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
538 _addInterfaceCmd IP_LINK "$dev" $up
539 elif ! test -n "$ctx"; then
540 echo $"Using 'dummy' (indirect) for interface '$dev' requires a fixed context number; dynamic ctx are not supported" >&2
543 test -z "$mac" || _generateMac mac "$(basename $iface)" "$ctx" || return 1
544 _addInterfaceCmd MODPROBE dummy "$dev"
545 _addInterfaceCmd IP_LINK dev dummy0 address "$mac"
546 _addInterfaceCmd NAMEIF "$dev" "$mac"
547 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" dev "$dev"
548 test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$ctx" "$extip"
555 ## Usage: _generateInterfaceOptions <vserver-directory>
556 function _generateInterfaceOptions
561 test ! -e "$1"/context || read ctx <"$1"/context
563 for iface in "$1/interfaces/"*; do
564 test -d "$iface" || continue
565 test ! -e "$iface"/disabled || continue
567 _processSingleInterface "$iface"
569 _HAVE_INTERFACE_OPTIONS=1
572 function enableInterfaces
577 lock "$__LOCKDIR"/vserver.interfaces
579 while test $i -lt $INTERFACE_CMDS_IDX; do
580 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
591 $_MODPROBE ${name:+-o "$name"} "$mod" "$@"
593 NAMEIF) $_NAMEIF "$@";;
594 VCONFIG) $_VCONFIG set_name_type "$4" >/dev/null
595 $_VCONFIG add "$2" "$3" >/dev/null;;
596 IP_ADDR) $_IP addr add "$@";;
597 IP_ADDR_FLUSH) $_IP addr flush "$@";;
598 IP_LINK) $_IP link set "$@";;
599 IP_ROUTE) $_IP route add "$@";;
600 *) echo "Unknown interface-command type '$type'" >&2; false;;
609 function disableInterfaces
611 test -n "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$1"
613 local i=$INTERFACE_CMDS_IDX
616 lock "$__LOCKDIR"/vserver.interfaces
618 while test $i -gt 0; do
621 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
628 MODPROBE) $_RMMOD "${2:-$1}";;
630 VCONFIG) $_VCONFIG rem "$2.$3" >/dev/null;;
631 IP_ADDR) $_IP addr del "$@";;
633 IP_LINK) ;; ## Ignore the link-down command for now
634 IP_ROUTE) $_IP route del "$@";;
635 *) echo "Unknown interface-command type '$type'" >&2; false;;
642 ## Usage: prepareInit <vserver-directory>
645 pushd "$1/vdir" >/dev/null
648 { find var/run ! -type d -print0; \
649 find var/lock ! -type d -print0; } | xargs -0r $_CHROOT_SH rm
652 $_CHROOT_SH rm .autofsck forcefsck 2>/dev/null || :
653 : | $_CHROOT_SH truncate fastboot 2>/dev/null || :
658 "${INITCMD_PREPARE[@]}"
662 ## Usage: prepareInit <vserver-directory>
665 pushd "$1/vdir" >/dev/null
668 export PREVLEVEL=$RUNLEVEL_START # required by Debian's initscripts
671 "${STOPCMD_PREPARE[@]}"
676 function generateOptions
678 _generateInterfaceOptions "$1"
679 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
680 _generateNiceCommand "$1"
681 _generateInitOptions "$1"
682 _generateChcontextOptions "$1"
683 _generateScheduleOptions "$1"
684 _generatePersonalityOptions "$1"
686 if test -n "$_IS_FAKEINIT"; then
687 CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
688 OPTS_VCONTEXT_MIGRATE=( "${OPTS_VCONTEXT_MIGRATE[@]}" --initpid --disconnect )
696 local f="$vdir"/cpuset
700 test -d "$f" || return 0
701 test -e "$f"/name || return 0
703 read cpuset < "$f"/name
704 test -e "$f"/nocreate || {
705 test -d /dev/cpuset/"$cpuset" || mkdir /dev/cpuset/"$cpuset" || configured=1
706 for i in cpus mems cpu_exclusive mem_exclusive virtualized; do
707 if test -e "$f"/"$i"; then
708 cat "$f"/"$i" >/dev/cpuset/"$cpuset"/"$i" 2>/dev/null || {
716 echo $$ >/dev/cpuset/"$cpuset"/tasks || configured=1
717 if [ "$configured" -ne 0 ]; then
719 WARNING: Failed to create or CPUSET \"$cpuset\" does not exist! Not using it!" >&2
720 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
725 function removeCPUSET
729 local f="$vdir"/cpuset
731 test -d "$f" || return 0
732 test -e "$f"/name || return 0
734 read cpuset < "$f"/name
735 test -e "$f"/nocreate || {
736 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
740 function _mountVserverInternal
745 test -e "$fstab" || return 0
748 pushd "$vdir" >/dev/null
749 # check whether / is mounted readonly or whether there is special
750 # magic regarding the mtab file; when etc/mtab can not be touched,
751 # add the '-n' flag to mount
752 test -w etc -o -w etc/mtab || xflag=-n
753 "$@" $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs no
761 local fstab="$cfgdir"/fstab
764 test -e "$fstab" || return 0
765 pushd "$vdir" >/dev/null
766 # check whether / is mounted readonly or whether there is special
767 # magic regarding the mtab file; when etc/mtab can not be touched,
768 # add the '-n' flag to mount
769 test -w etc -o -w etc/mtab || xflag=-n
770 $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs only -n
774 function mountVserver
781 test -e "$cfgdir"/fstab -o \
782 -e "$cfgdir"/fstab.local -o \
783 -e "$cfgdir"/fstab.remote || return 0
785 findObject -r mtab_src "$cfgdir"/apps/init/mtab "$__CONFDIR"/.defaults/init/mtab "$__PKGLIBDEFAULTDIR"/mtab /dev/null
787 pushd "$vdir" >/dev/null
788 $_CHROOT_SH truncate /etc/mtab <"$mtab_src"
791 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
793 _mountVserverInternal "$cfgdir"/fstab
794 _mountVserverInternal "$cfgdir"/fstab.local
795 _mountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}"
797 isNamespaceCleanup "$cfgdir" && \
800 isAvoidNamespace "$cfgdir" || \
801 $_SECURE_MOUNT --rbind -n "$vdir" "/"
804 function _umountVserverInternal
807 test -e "$fstab" || return 0
812 while read src dst tmp; do
813 test -n "$tmp" || continue
819 "$@" $_EXEC_CD "$dst" $_UMOUNT -lfn . || is_ok=
825 function umountVserver
831 isAvoidNamespace "$cfgdir" || return 0
832 test -e "$cfgdir"/fstab -o \
833 -e "$cfgdir"/fstab.local -o \
834 -e "$cfgdir"/fstab.remote || return 0
835 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
837 pushd "$vdir/" >/dev/null || return 1
838 _umountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}" || is_ok=
839 _umountVserverInternal "$cfgdir"/fstab.local || is_ok=
840 _umountVserverInternal "$cfgdir"/fstab || is_ok=
841 popd >/dev/null || return 1
846 ## Usage: waitForSync <vserver> <context> <vshelper-fifo-varname>
850 test -n "$_NEED_VSHELPER_SYNC" && \
851 ! $_VSERVER_INFO - FEATURE vwait || _is_meth=async
853 vshelper.initSync "$1" "$3" "$_is_meth"
856 ## Usage: initWait <vserver> <context> <vwait-tmpdir-varname>
859 if $_VSERVER_INFO - FEATURE vwait; then
861 _is_tmpdir=$($_MKTEMPDIR vwaitstat.XXXXXX)
864 $_VWAIT --timeout "$VSHELPER_SYNC_TIMEOUT" \
866 >>$_is_tmpdir/out 2>$_is_tmpdir/err 3>$_is_tmpdir/fifo
869 if test "$rc" -ne 0 -a "$rc" -ne 1; then
870 $_VPS axf | $_EGREP -e "^[^ \t]+[ \t]+$S_CONTEXT[ \t]+" >&4
871 killContext "$S_CONTEXT" 9
875 ) 4>$_is_tmpdir/procs &
877 echo "$!" >$_is_tmpdir/pid
878 eval "$3"=$_is_tmpdir
883 ## Usage: _waitForVWait <vserver> <fifo> <pid> <procs>
884 function _waitForVWait
889 declare -r procs=$(cat $4)
891 getFileArray status "$2"
896 'vwait' exited with error '$2' which indicates that vserver could not
901 A timeout occured while waiting for the vserver to finish and it was
902 killed by sending a SIGKILL signal. Please investigate the reasons
903 and/or increase the timeout in apps/vshelper/sync-timeout."
906 (TIMEOUT) warning $"\
907 A timeout occured while waiting for the vserver to finish and it will
908 be killed by sending a SIGKILL signal. The following process list
909 might be useful for finding out the reason of this behavior:
911 ----------------------------------------------------------------------
913 }----------------------------------------------------------------------"
916 (\?\?\?|*) warning $"\
917 internal error: 'vwait' exited with an unexpected status '$1'; I will
918 try to continue but be prepared for unexpected events."
925 ## Usage: waitForSync <vserver> [<vshelper-fifo>] [<vwait-statdir>]
930 local vwait_statdir=$3
933 if test -d "$vwait_statdir"; then
934 _waitForVWait "$cfgdir" "$vwait_statdir/fifo" "$( <$vwait_statdir/pid )" "$vwait_statdir/procs"
935 elif test -n "$_NEED_VSHELPER_SYNC"; then
936 $_VSHELPER_SYNC "$fifo" "$VSHELPER_SYNC_TIMEOUT" || \
938 A timeout or other error occured while waiting for the synchronization
939 signal from vserver '$VSERVER_NAME'.
940 The vserver will be killed nevertheless..."
941 elif test "${#INITCMD_STOP_SYNC[@]}" -ne 0; then
942 "${INITCMD_STOP_SYNC[@]}" || \
944 Stop-synchronization for vserver '$VSERVER_NAME' failed. The vserver
945 will be killed nevertheless..."
948 test -z "$OPTION_FORCE_SYNC" -a ! -e "$cfgdir"/sync ||
954 local vdir name flavor start i already_handled base
958 ## Usage: execScriptlets <vserver-cfgdir> <vserver-name> <script-flavor>
959 function execScriptlets
966 for base in "$vdir"/scripts "$__CONFDIR"/.defaults/scripts; do
967 local DONT_SKIP_DEFAULTS=
968 local already_handled=
970 for i in "$base/$flavor" "$base/$flavor.d"/*; do
971 isRegularFile "$i" || continue
972 test -r "$i" || continue
976 test -x "$i" || start=_sourceWrap
977 $start "$i" "$flavor" "$name"
980 test -z "$already_handled" -o -n "$DONT_SKIP_DEFAULTS" || break
989 ! test -e "$cfgdir"/fstab.local ||
991 WARNING: 'fstab' will *not* be executed in the network context of the
992 vserver anymore. Therefore, 'fstab.local' has the same functionality
993 and is obsoleted. When you need the old behaviour, put the mounts
996 ! test -e "$cfgdir"/hostname -a ! -L "$cfgdir"/hostname ||
998 WARNING: The hostname is now configured in 'uts/nodename' but not in
1001 ! test -e "$cfgdir"/domainname -a ! -L "$cfgdir"/domainname ||
1003 WARNING: The domainname is now configured in 'uts/domainname' but not
1004 in 'domainname'." >&2
1008 for i in "$cfgdir"/interfaces/*/only_ip; do
1009 if test -e "$i"; then
1011 iface=${i##$cfgdir/interfaces/}
1012 iface=${iface%%/only_ip}
1014 WARNING: The 'only_ip' flag for interface '$iface' is deprecated; use
1019 test ! -d "$cfgdir"/dlimits -o -L "$cfgdir/cache" || \
1021 WARNING: There is no cachedirectory configured for this vserver;
1022 please create '$cfgdir/cache' e.g. by executing
1024 ln -s ../.defaults/cachebase/$VSERVER_NAME $cfgdir/cache
1027 find "$cfgdir" -type f -exec "$_CHECK_UNIXFILE" '{}' ';'
1029 vshelper.doSanityCheck
1031 $_VSERVER_INFO - VERIFYCAP ||
1032 panic $"capabilities are not enabled in kernel-setup"
1034 $_VSERVER_INFO - VERIFYPROC ||
1036 /proc/uptime can not be accessed. Usually, this is caused by
1037 procfs-security. Please read the FAQ for more details
1038 http://www.linux-vserver.org/index.php?page=Linux-Vserver+FAQ"
1042 function _setSingleDiskLimit
1054 getFileValue ctx "$vdir/context"
1055 getFileValue directory "$dlimit/directory" || return 0
1056 getFileValue space_total "$dlimit/space_total" || return 0
1057 getFileValue inodes_total "$dlimit/inodes_total" || return 0
1058 getFileValue reserved "$dlimit/reserved" || return 0
1060 local cachename=$ctx$directory
1061 cachename=dlimits/${cachename//\//_}
1063 test -e "$vdir/cache/$cachename" && . "$vdir/cache/$cachename"
1064 # Remove the cache so if the machine goes down unexpectedly, we won't have a stale cache
1065 $_RM -f "$vdir/cache/$cachename"
1067 if test -z "$inodes_used" -o -z "$space_used"; then
1069 tmpvdu=`$_VDU --xid $ctx --space --inodes --script "$directory"`
1070 inodes_used=${tmpvdu##* }
1071 space_used=${tmpvdu%% *}
1074 $_VDLIMIT --xid $ctx \
1075 --set space_used=$space_used \
1076 --set space_total=$space_total \
1077 --set inodes_used=$inodes_used \
1078 --set inodes_total=$inodes_total \
1079 --set reserved=$reserved \
1084 function setDiskLimits
1089 # Disk Limits without a static context are useless
1090 test -e "$vdir"/context || return 0
1092 for dlimit in "$vdir/dlimits/"*; do
1093 test -d "$dlimit" || continue
1094 test ! -e "$dlimit/disabled" || continue
1096 _setSingleDiskLimit "$vdir" "$dlimit"
1101 function _saveSingleDiskLimit
1108 getFileValue ctx "$vdir/context"
1109 getFileValue directory "$dlimit/directory" || return 0
1111 local cachename=$ctx$directory
1112 cachename=${cachename//\//_}
1114 # Things are getting ugly here... LFS says that /var/cache (where
1115 # cachename is usually pointing to) can vanish and applications
1116 # have to deal with it. So, we have to interprete the $vdir/cache
1117 # symlink and have to create the needed directories manually.
1118 if test -d "$vdir/cache"; then
1119 : # ok, exists already
1120 elif test -L "$vdir/cache"; then
1121 # it's a dangling symlink
1123 link=$($_READLINK "$vdir/cache")
1124 ( cd $vdir && $_MKDIR -p "$link" )
1129 test -d "$vdir/cache"
1130 $_MKDIR -p "$vdir"/cache/dlimits
1132 $_VDLIMIT --xid $ctx "$directory" | \
1133 $_GREP '_used=' > "$vdir/cache/dlimits/$cachename"
1137 function saveDiskLimits
1142 test -e "$vdir"/context || return 0
1144 for dlimit in "$vdir/dlimits/"*; do
1145 test -d "$dlimit" || continue
1146 test ! -e "$dlimit/disabled" || continue
1148 _saveSingleDiskLimit "$vdir" "$dlimit"
1152 function _namespaceCleanup
1154 local root=$(readlink -f "$vdir")
1157 while [ "$tmp" ]; do
1158 list=( "${list[@]}" "$tmp" )
1161 local -a list_umount
1162 while read dev path opts; do
1163 [ "$path" ] || continue
1164 for i in "$root" /dev /proc; do
1165 [ "${path#$i}" != "$path" ] && continue 2
1167 for i in "${list[@]}" /; do
1168 [ "$path" = "$i" ] && continue 2
1170 list_umount=( "${list_umount[@]}" "$path" )
1172 for i in "${list_umount[@]}"; do