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=()
45 declare -a OPTS_ENV=()
47 declare -a STOPCMD_PREPARE=()
49 declare -a VSERVER_EXTRA_CMDS=()
52 VSHELPER_SYNC_TIMEOUT=30
57 _HAVE_INTERFACE_OPTIONS=
68 : ${VSERVER_NAME:=$(basename "$VSERVER_DIR")}
70 if test -e "$VSERVER_DIR"/noisy -o -n "$OPTION_VERBOSE"; then
76 function _generateChbindOptions
83 test -n "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$vdir"
85 local f=$vdir/interfaces/bcast
86 getFileValue bcast "$f"
88 getFileValue nid "$vdir/ncontext" "$vdir/context"
90 CHBIND_OPTS=( $SILENT_OPT ${nid:+--nid "$nid"} ${bcast:+--bcast "$bcast"} )
92 for i in "${INTERFACES[@]}"; do
93 CHBIND_OPTS=( "${CHBIND_OPTS[@]}" --ip "$i" )
96 _HAVE_CHBIND_OPTIONS=1
99 function _generateNiceCommand
103 local current_nice=`$_NICE`
105 test -r "$vdir/nice" && read nice <"$vdir"/nice
107 let nice=$nice-$current_nice || :
108 NICE_CMD=( $_NICE -n $nice )
112 function _generatePersonalityOptions
115 local f="$vdir"/personality
118 test -s "$f" || return 0
127 (*) flags=$flags$delim$tmp
134 OPTS_VCONTEXT_ENTER=( "${OPTS_VCONTEXT_ENTER[@]}"
135 --personality-type "$type"
136 ${flags:+--personality-flags "$flags"} )
139 function _generateCCapabilityOptions
143 local f="$vdir"/ccapabilities
145 test -e "$f" || return 0
149 (*) OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --ccap "$cap" );;
154 function _generateBCapabilityOptions
158 local f="$vdir"/bcapabilities
160 test -e "$f" || return 0
164 (*) OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --bcap "$cap" );;
169 function _generateCapabilityOptions
174 _generateBCapabilityOptions "$vdir"
175 _generateCCapabilityOptions "$vdir"
177 test -e "$vdir"/capabilities || return 0
186 CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" )
187 CAPCHROOT_OPTS=( "${CAPCHROOT_OPTS[@]}" --nochroot )
190 CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" )
193 done <"$vdir"/capabilities
196 function getEnterShell
203 getFileValue ENTER_SHELL "$vdir"/shell "$__CONFDIR"/.defaults/shell
205 test -n "$ENTER_SHELL" || {
207 for i in "/bin/bash -login" "/bin/sh -l" /bin/csh; do
209 test -x "$vdir/vdir/$1" || continue
216 ## Usage: sendKillSequence <ctx> <signal> [<wait> <signal>]*
217 function sendKillSequence
223 while isCtxRunning "$ctx"; do
224 test -z "$wait" || sleep "$wait"
226 killContext "$ctx" "$1"
227 test -n "$2" || break
233 function _generateInitOptions
236 local cfgdir=$vdir/apps/init
241 INITCMD_START_SYNC=()
246 INITKILL_SEQ=( 15 5 9 )
247 CHCONTEXT_INIT_OPTS=()
250 getFileValue INITSTYLE "$cfgdir"/style
251 getFileValue RUNLEVEL_START "$cfgdir"/runlevel
252 getFileValue RUNLEVEL_START "$cfgdir"/runlevel.start
253 getFileValue RUNLEVEL_STOP "$cfgdir"/runlevel.stop
254 getFileArray INITKILL_SEQ "$cfgdir"/killseq || :
256 findFile _gio_env "$cfgdir"/environment \
257 "$__CONFDIR"/.defaults/apps/init/environment \
258 "$__PKGLIBDEFAULTDIR"/environment
259 getFileArray OPTS_ENV "$_gio_env" || :
261 case x"$INITSTYLE" in
263 INITCMD_START=( "${INITCMD_RESCUE[@]}" )
264 INITCMD_STOP=( /sbin/killall5 )
270 test -n "$RUNLEVEL_START" || RUNLEVEL_START=3
271 test -n "$RUNLEVEL_STOP" || RUNLEVEL_STOP=6
273 for i in /etc/init.d/rc /etc/rc.d/rc; do
274 test -x "$vdir/vdir/$i" || continue
275 INITCMD_START=( "$i" "$RUNLEVEL_START" )
276 INITCMD_STOP=( "$i" "$RUNLEVEL_STOP" )
278 INITCMD_PREPARE=( $_FAKE_RUNLEVEL "$RUNLEVEL_START" /var/run/utmp )
282 INITCMD_START=( /sbin/init )
283 INITCMD_STOP=( /sbin/init )
285 _NEED_VSHELPER_SYNC=1
286 test -z "$RUNLEVEL_START" || INITCMD_START=( "${INITCMD_START[@]}" "$RUNLEVEL_START" )
287 test -z "$RUNLEVEL_STOP" || INITCMD_STOP=( "${INITCMD_STOP[@]}" "$RUNLEVEL_STOP" )
291 INITCMD_START=( /sbin/minit-start )
292 INITCMD_STOP=( /sbin/minit-stop )
294 INITCMD_START_SYNC=( "$_INITSYNC_MINIT_START" "$vdir" )
295 _NEED_VSHELPER_SYNC=1
296 test -z "$RUNLEVEL_START" || INITCMD_START=( "${INITCMD_START[@]}" "$RUNLEVEL_START" )
297 test -z "$RUNLEVEL_STOP" || INITCMD_STOP=( "${INITCMD_STOP[@]}" "$RUNLEVEL_STOP" )
298 ! isNumber "${RUNLEVEL_START:-3}" || INITCMD_PREPARE=( $_FAKE_RUNLEVEL "${RUNLEVEL_START:-3}" /var/run/utmp )
302 test -n "$RUNLEVEL_START" || RUNLEVEL_START="default"
304 INITCMD_START=( /lib/rcscripts/sh/init-vserver.sh "$RUNLEVEL_START" )
305 INITCMD_STOP=( /sbin/rc shutdown )
306 INITCMD_PREPARE=( $_FAKE_RUNLEVEL 3 /var/run/utmp )
308 pushd "$vdir"/vdir &>/dev/null
309 basever=$($_CHROOT_SH cat /etc/gentoo-release | $_AWK '{print $5}')
312 basemaj=${basever/.*}
313 basemin=${basever#*.}
314 basemin=${basemin/.*}
316 test "$basemaj" -lt 1 -o "$basemin" -lt 13 && \
318 Using init-style 'gentoo' requires >=baselayout-1.13 inside the vserver!
320 Your vserver ($(basename "$vdir")) seems to have baselayout-$basever,
321 please use 'plain' init-style instead!"
325 (*) panic "Unknown init-style '$INITSTYLE'; aborting";;
328 if test x"$INITSTYLE" != xrescue; then
329 getFileArray INITCMD_START "$cfgdir"/cmd.start || :
330 getFileArray INITCMD_STOP "$cfgdir"/cmd.stop || :
331 getFileArray INITCMD_START_SYNC "$cfgdir"/cmd.start-sync || :
332 getFileArray INITCMD_STOP_SYNC "$cfgdir"/cmd.stop-sync || :
333 getFileArray INITCMD_PREPARE "$cfgdir"/cmd.prepare || :
336 test -n "$OPTION_FORCE_SYNC" -o -e "$cfgdir"/sync || {
337 INITCMD_START_SYNC=()
342 if vshelper.isEnabled; then
343 vshelper.getSyncTimeout "$vdir" VSHELPER_SYNC_TIMEOUT || :
349 function _generateFlagOptions
353 CHCONTEXT_FLAG_OPTS=()
355 test ! -e "$vdir"/flags || \
364 OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --flag "$flag" )
365 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}"
371 isAvoidNamespace "$vdir" || {
373 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}" --flag namespace )
377 function _generateChcontextOptions
380 local ctx hostname domainname
385 read ctx <"$vdir"/context || :
387 read hostname <"$vdir"/uts/nodename || read hostname <"$vdir"/hostname || :
388 read domainname <"$vdir"/uts/domainname || read domainname <"$vdir"/domainname || :
391 test -z "$S_CONTEXT" || ctx=$S_CONTEXT
393 _generateCapabilityOptions "$vdir"
394 _generateFlagOptions "$vdir"
396 CHCONTEXT_OPTS=( $SILENT_OPT \
397 "${CHCONTEXT_FLAG_OPTS[@]}" \
400 ${ctx:+--ctx "$ctx"} \
401 ${hostname:+--hostname "$hostname"} \
402 ${domainname:+--domainname "$domainname"} )
404 OPTS_VCONTEXT_CREATE=( $SILENT_OPT \
405 ${ctx:+--xid "$ctx"} )
406 ## put '--secure' at front so that it can be overridden
407 OPTS_VATTRIBUTE=( --secure --flag default "${OPTS_VATTRIBUTE[@]}" )
410 function _generateScheduleOptions
413 if test -d "$vdir"/sched; then
414 OPTS_VSCHED=( --dir "$vdir"/sched --missingok )
418 local f="$vdir"/schedule
419 test -e "$f" || return 0
421 local fill_rate interval tokens tokens_min tokens_max prio_bias
429 read prio_bias || prio_bias=
433 test -n "$prio_bias" || {
434 echo $"Bad content in '$f'; aborting..." >&2
438 OPTS_VSCHED=( --fill-rate "$fill_rate" --interval "$interval" \
439 --tokens "$tokens" --tokens_min "$tokens_min" \
440 --tokens_max "$tokens_max" --priority-bias "$prio_bias" )
443 function _getInterfaceValue
453 read _giv_tmp <"$_giv_i/$_giv_val" && break || :
456 : ${_giv_tmp:=$_giv_dflt}
457 eval $_giv_val=\$_giv_tmp
460 ## Usage: _transformMask2Prefix <result-varname> <prefix> <mask>
461 function _transformMask2Prefix
465 test -n "$_tm2p_tmp" || {
466 $_MASK2PREFIX "$3" || _tm2p_tmp=$?
473 function _addInterfaceCmd
475 eval INTERFACE_CMDS_${INTERFACE_CMDS_IDX}='( "$@" )'
476 let ++INTERFACE_CMDS_IDX
479 ## Usage: _generateMac <var> <iface> <ctx>
480 function _generateMac
483 echo $"Interface basename '$iface' must be either a number, or the mac must be configured explicitly" >&2
487 eval $1=$(printf "f0:ff:%02x:%02x:%02x:%02x" $[ (~($2>>8)) & 0xff ] $[ ($2 & 0xff) ] $[ ($3>>8) & 0xff ] $[ $3 & 0xff ])
490 function _getVLANInfo
495 creation of VLAN_PLUS_VID devices is not supported; please create them
496 before starting the vserver and use the 'nodev' flag then"
497 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID"
501 creation of VLAN_PLUS_VID_NO_PAD devices is not supported; please
502 create them before starting the vserver and use the 'nodev' flag then"
503 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID_N0_PAD"
505 (*.????) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID";;
506 (*.*) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID_NO_PAD";;
513 ## Usage: _processSingleInterface <interface-directory>
514 function _processSingleInterface
529 _getInterfaceValue ip '' "$iface"
530 _getInterfaceValue extip '' "$iface" "$iface/.."
531 _getInterfaceValue dev '' "$iface" "$iface/.."
532 _getInterfaceValue prefix '' "$iface" "$iface/.."
533 _getInterfaceValue mask '' "$iface" "$iface/.."
534 _getInterfaceValue bcast '' "$iface" "$iface/.."
535 _getInterfaceValue name '' "$iface"
536 _getInterfaceValue scope '' "$iface" "$iface/.."
537 _getInterfaceValue mac '' "$iface"
539 test -n "$ip" || { echo $"Can not read ip for '$iface'" >&2; return 1; }
540 test -n "$dev" -o -e "$iface"/nodev || {
541 echo $"No device specified for '$iface'" >&2
545 test ! -e "$iface"/down || up=
548 _transformMask2Prefix prefix "$prefix" "$mask"
549 INTERFACES=( "${INTERFACES[@]}" "$ip${prefix:+/$prefix}" )
551 test ! -e "$iface"/nodev || break
553 test ! -e "$iface"/only_ip || break
556 if vlan_info=$(_getVLANInfo "$dev"); then
557 test -d /proc/net/vlan || {
558 echo -e $"VLAN device-name used, but vlan subsystem not enabled.\nTry to execute 'modprobe 8021q' before starting the vservers" >&2
561 test -e "$iface/vlandev" \
562 -o \( -e "$iface/../vlandev" -a ! -e "$iface/novlandev" \) \
563 -o \( -e "$__CONFDIR/.defaults/interfaces/vlandev" \
564 -a ! -e "$iface/novlandev" \
565 -a ! -e "$iface/../novlandev" \) && {
566 _addInterfaceCmd VCONFIG $vlan_info
570 if ! test -e "$iface"/indirect; then
571 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" broadcast ${bcast:-+} ${name:+label "$dev:$name"} dev "$dev"
572 #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
573 _addInterfaceCmd IP_LINK "$dev" $up
574 elif ! test -n "$ctx"; then
575 echo $"Using 'dummy' (indirect) for interface '$dev' requires a fixed context number; dynamic ctx are not supported" >&2
578 test -z "$mac" || _generateMac mac "$(basename $iface)" "$ctx" || return 1
579 _addInterfaceCmd MODPROBE dummy "$dev"
580 _addInterfaceCmd IP_LINK dev dummy0 address "$mac"
581 _addInterfaceCmd NAMEIF "$dev" "$mac"
582 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" dev "$dev"
583 test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$ctx" "$extip"
590 ## Usage: _generateInterfaceOptions <vserver-directory>
591 function _generateInterfaceOptions
596 test ! -e "$1"/context || read ctx <"$1"/context
598 for iface in "$1/interfaces/"*; do
599 test -d "$iface" || continue
600 test ! -e "$iface"/disabled || continue
602 _processSingleInterface "$iface"
604 _HAVE_INTERFACE_OPTIONS=1
607 function enableInterfaces
612 lock "$__LOCKDIR"/vserver.interfaces
614 while test $i -lt $INTERFACE_CMDS_IDX; do
615 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
626 $_MODPROBE ${name:+-o "$name"} "$mod" "$@"
628 NAMEIF) $_NAMEIF "$@";;
629 VCONFIG) $_VCONFIG set_name_type "$4" >/dev/null
630 $_VCONFIG add "$2" "$3" >/dev/null;;
631 IP_ADDR) $_IP addr add "$@";;
632 IP_ADDR_FLUSH) $_IP addr flush "$@";;
633 IP_LINK) $_IP link set "$@";;
634 IP_ROUTE) $_IP route add "$@";;
635 *) echo "Unknown interface-command type '$type'" >&2; false;;
644 function disableInterfaces
646 test -n "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$1"
648 local i=$INTERFACE_CMDS_IDX
651 lock "$__LOCKDIR"/vserver.interfaces
653 while test $i -gt 0; do
656 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
663 MODPROBE) $_RMMOD "${2:-$1}";;
665 VCONFIG) $_VCONFIG rem "$2.$3" >/dev/null;;
666 IP_ADDR) $_IP addr del "$@";;
668 IP_LINK) ;; ## Ignore the link-down command for now
669 IP_ROUTE) $_IP route del "$@";;
670 *) echo "Unknown interface-command type '$type'" >&2; false;;
677 ## Usage: prepareInit <vserver-directory>
680 pushd "$1/vdir" >/dev/null
683 { find var/run ! -type d -print0; \
684 find var/lock ! -type d -print0; } | xargs -0r $_CHROOT_SH rm
687 $_CHROOT_SH rm .autofsck forcefsck 2>/dev/null || :
688 : | $_CHROOT_SH truncate fastboot 2>/dev/null || :
693 "${INITCMD_PREPARE[@]}"
697 ## Usage: prepareInit <vserver-directory>
700 pushd "$1/vdir" >/dev/null
703 export PREVLEVEL=$RUNLEVEL_START # required by Debian's initscripts
706 "${STOPCMD_PREPARE[@]}"
711 function generateOptions
713 _generateInterfaceOptions "$1"
714 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
715 _generateNiceCommand "$1"
716 _generateInitOptions "$1"
717 _generateChcontextOptions "$1"
718 _generateScheduleOptions "$1"
719 _generatePersonalityOptions "$1"
721 if test -n "$_IS_FAKEINIT"; then
722 CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
723 OPTS_VCONTEXT_MIGRATE=( "${OPTS_VCONTEXT_MIGRATE[@]}" --initpid --disconnect )
731 local f="$vdir"/cpuset
735 test -d "$f" || return 0
736 test -e "$f"/name || return 0
738 read cpuset < "$f"/name
739 test -e "$f"/nocreate || {
740 test -d /dev/cpuset/"$cpuset" || mkdir /dev/cpuset/"$cpuset" || configured=1
741 for i in cpus mems cpu_exclusive mem_exclusive virtualized; do
742 if test -e "$f"/"$i"; then
743 cat "$f"/"$i" >/dev/cpuset/"$cpuset"/"$i" || {
751 echo $$ >/dev/cpuset/"$cpuset"/tasks || configured=1
752 if [ "$configured" -ne 0 ]; then
754 WARNING: Failed to create or CPUSET \"$cpuset\" does not exist! Not using it!" >&2
755 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
760 function removeCPUSET
764 local f="$vdir"/cpuset
766 test -d "$f" || return 0
767 test -e "$f"/name || return 0
769 read cpuset < "$f"/name
770 test -e "$f"/nocreate || {
771 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
775 function _mountVserverInternal
780 test -e "$fstab" || return 0
783 pushd "$vdir" >/dev/null
784 # check whether / is mounted readonly or whether there is special
785 # magic regarding the mtab file; when etc/mtab can not be touched,
786 # add the '-n' flag to mount
787 test -w etc -o -w etc/mtab || xflag=-n
788 "$@" $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs no
796 local fstab="$cfgdir"/fstab
799 test -e "$fstab" || return 0
800 pushd "$vdir" >/dev/null
801 # check whether / is mounted readonly or whether there is special
802 # magic regarding the mtab file; when etc/mtab can not be touched,
803 # add the '-n' flag to mount
804 test -w etc -o -w etc/mtab || xflag=-n
805 $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs only -n
809 function mountVserver
816 test -e "$cfgdir"/fstab -o \
817 -e "$cfgdir"/fstab.local -o \
818 -e "$cfgdir"/fstab.remote || return 0
820 findObject -r mtab_src "$cfgdir"/apps/init/mtab "$__CONFDIR"/.defaults/init/mtab "$__PKGLIBDEFAULTDIR"/mtab /dev/null
822 pushd "$vdir" >/dev/null
823 $_CHROOT_SH truncate /etc/mtab <"$mtab_src"
826 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
828 _mountVserverInternal "$cfgdir"/fstab
829 _mountVserverInternal "$cfgdir"/fstab.local
830 _mountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}"
832 isNamespaceCleanup "$cfgdir" && \
833 _namespaceCleanup "$cfgdir"
835 isAvoidNamespace "$cfgdir" || \
836 $_SECURE_MOUNT --rbind -n "$vdir" "/"
839 function _umountVserverInternal
842 test -e "$fstab" || return 0
847 while read src dst tmp; do
848 test -n "$tmp" || continue
854 "$@" $_EXEC_CD "$dst" $_UMOUNT -lfn . || is_ok=
860 function umountVserver
866 isAvoidNamespace "$cfgdir" || return 0
867 test -e "$cfgdir"/fstab -o \
868 -e "$cfgdir"/fstab.local -o \
869 -e "$cfgdir"/fstab.remote || return 0
870 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
872 pushd "$vdir/" >/dev/null || return 1
873 _umountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}" || is_ok=
874 _umountVserverInternal "$cfgdir"/fstab.local || is_ok=
875 _umountVserverInternal "$cfgdir"/fstab || is_ok=
876 popd >/dev/null || return 1
881 ## Usage: waitForSync <vserver> <context> <vshelper-fifo-varname>
885 test -n "$_NEED_VSHELPER_SYNC" && \
886 ! $_VSERVER_INFO - FEATURE vwait || _is_meth=async
888 vshelper.initSync "$1" "$3" "$_is_meth"
891 ## Usage: initWait <vserver> <context> <vwait-tmpdir-varname>
894 if $_VSERVER_INFO - FEATURE vwait; then
896 _is_tmpdir=$($_MKTEMPDIR vwaitstat.XXXXXX)
899 $_VWAIT --timeout "$VSHELPER_SYNC_TIMEOUT" \
901 >>$_is_tmpdir/out 2>$_is_tmpdir/err 3>$_is_tmpdir/fifo
904 if test "$rc" -ne 0 -a "$rc" -ne 1; then
905 $_VPS axf | $_EGREP -e "^[^ \t]+[ \t]+$S_CONTEXT[ \t]+" >&4
906 killContext "$S_CONTEXT" 9
910 ) 4>$_is_tmpdir/procs &
912 echo "$!" >$_is_tmpdir/pid
913 eval "$3"=$_is_tmpdir
918 ## Usage: _waitForVWait <vserver> <fifo> <pid> <procs>
919 function _waitForVWait
924 declare -r procs=$(cat $4)
926 getFileArray status "$2"
931 'vwait' exited with error '$2' which indicates that vserver could not
936 A timeout occured while waiting for the vserver to finish and it was
937 killed by sending a SIGKILL signal. Please investigate the reasons
938 and/or increase the timeout in apps/vshelper/sync-timeout."
941 (TIMEOUT) warning $"\
942 A timeout occured while waiting for the vserver to finish and it will
943 be killed by sending a SIGKILL signal. The following process list
944 might be useful for finding out the reason of this behavior:
946 ----------------------------------------------------------------------
948 }----------------------------------------------------------------------"
951 (\?\?\?|*) warning $"\
952 internal error: 'vwait' exited with an unexpected status '$1'; I will
953 try to continue but be prepared for unexpected events."
960 ## Usage: waitForSync <vserver> [<vshelper-fifo>] [<vwait-statdir>]
965 local vwait_statdir=$3
968 if test -d "$vwait_statdir"; then
969 _waitForVWait "$cfgdir" "$vwait_statdir/fifo" "$( <$vwait_statdir/pid )" "$vwait_statdir/procs"
970 elif test -n "$_NEED_VSHELPER_SYNC"; then
971 $_VSHELPER_SYNC "$fifo" "$VSHELPER_SYNC_TIMEOUT" || \
973 A timeout or other error occured while waiting for the synchronization
974 signal from vserver '$VSERVER_NAME'.
975 The vserver will be killed nevertheless..."
976 elif test "${#INITCMD_STOP_SYNC[@]}" -ne 0; then
977 "${INITCMD_STOP_SYNC[@]}" || \
979 Stop-synchronization for vserver '$VSERVER_NAME' failed. The vserver
980 will be killed nevertheless..."
983 test -z "$OPTION_FORCE_SYNC" -a ! -e "$cfgdir"/sync ||
989 local vdir name flavor start i already_handled base
993 ## Usage: execScriptlets <vserver-cfgdir> <vserver-name> <script-flavor>
994 function execScriptlets
1001 for base in "$vdir"/scripts "$__CONFDIR"/.defaults/scripts; do
1002 local DONT_SKIP_DEFAULTS=
1003 local already_handled=
1005 for i in "$base/$flavor" "$base/$flavor.d"/*; do
1006 isRegularFile "$i" || continue
1007 test -r "$i" || continue
1011 test -x "$i" || start=_sourceWrap
1012 $start "$i" "$flavor" "$name"
1015 test -z "$already_handled" -o -n "$DONT_SKIP_DEFAULTS" || break
1020 function sanityCheck
1022 declare -r cfgdir=$1
1024 ! test -e "$cfgdir"/fstab.local ||
1026 WARNING: 'fstab' will *not* be executed in the network context of the
1027 vserver anymore. Therefore, 'fstab.local' has the same functionality
1028 and is obsoleted. When you need the old behaviour, put the mounts
1029 into 'fstab.remote'"
1031 ! test -e "$cfgdir"/hostname -a ! -L "$cfgdir"/hostname ||
1033 WARNING: The hostname is now configured in 'uts/nodename' but not in
1036 ! test -e "$cfgdir"/domainname -a ! -L "$cfgdir"/domainname ||
1038 WARNING: The domainname is now configured in 'uts/domainname' but not
1039 in 'domainname'." >&2
1043 for i in "$cfgdir"/interfaces/*/only_ip; do
1044 if test -e "$i"; then
1046 iface=${i##$cfgdir/interfaces/}
1047 iface=${iface%%/only_ip}
1049 WARNING: The 'only_ip' flag for interface '$iface' is deprecated; use
1054 test ! -d "$cfgdir"/dlimits -o -L "$cfgdir/cache" || \
1056 WARNING: There is no cachedirectory configured for this vserver;
1057 please create '$cfgdir/cache' e.g. by executing
1059 ln -s ../.defaults/cachebase/$VSERVER_NAME $cfgdir/cache
1062 find "$cfgdir" -type f -exec "$_CHECK_UNIXFILE" '{}' ';'
1064 vshelper.doSanityCheck
1066 $_VSERVER_INFO - VERIFYCAP ||
1067 panic $"capabilities are not enabled in kernel-setup"
1069 $_VSERVER_INFO - VERIFYPROC ||
1071 /proc/uptime can not be accessed. Usually, this is caused by
1072 procfs-security. Please read the FAQ for more details
1073 http://www.linux-vserver.org/index.php?page=Linux-Vserver+FAQ"
1077 function _setSingleDiskLimit
1089 getFileValue ctx "$vdir/context"
1090 getFileValue directory "$dlimit/directory" || return 0
1091 getFileValue space_total "$dlimit/space_total" || return 0
1092 getFileValue inodes_total "$dlimit/inodes_total" || return 0
1093 getFileValue reserved "$dlimit/reserved" || return 0
1095 local cachename=$ctx$directory
1096 cachename=dlimits/${cachename//\//_}
1098 test -e "$vdir/cache/$cachename" && . "$vdir/cache/$cachename"
1099 # Remove the cache so if the machine goes down unexpectedly, we won't have a stale cache
1100 $_RM -f "$vdir/cache/$cachename"
1102 if test -z "$inodes_used" -o -z "$space_used"; then
1104 tmpvdu=`$_VDU --xid $ctx --space --inodes --script "$directory"`
1105 inodes_used=${tmpvdu##* }
1106 space_used=${tmpvdu%% *}
1109 $_VDLIMIT --xid $ctx \
1110 --set space_used=$space_used \
1111 --set space_total=$space_total \
1112 --set inodes_used=$inodes_used \
1113 --set inodes_total=$inodes_total \
1114 --set reserved=$reserved \
1119 function setDiskLimits
1124 # Disk Limits without a static context are useless
1125 test -e "$vdir"/context || return 0
1127 for dlimit in "$vdir/dlimits/"*; do
1128 test -d "$dlimit" || continue
1129 test ! -e "$dlimit/disabled" || continue
1131 _setSingleDiskLimit "$vdir" "$dlimit"
1136 function _saveSingleDiskLimit
1143 getFileValue ctx "$vdir/context"
1144 getFileValue directory "$dlimit/directory" || return 0
1146 local cachename=$ctx$directory
1147 cachename=${cachename//\//_}
1149 # Things are getting ugly here... LFS says that /var/cache (where
1150 # cachename is usually pointing to) can vanish and applications
1151 # have to deal with it. So, we have to interprete the $vdir/cache
1152 # symlink and have to create the needed directories manually.
1153 if test -d "$vdir/cache"; then
1154 : # ok, exists already
1155 elif test -L "$vdir/cache"; then
1156 # it's a dangling symlink
1158 link=$($_READLINK "$vdir/cache")
1159 ( cd $vdir && $_MKDIR -p "$link" )
1164 test -d "$vdir/cache"
1165 $_MKDIR -p "$vdir"/cache/dlimits
1167 $_VDLIMIT --xid $ctx "$directory" | \
1168 $_GREP '_used=' > "$vdir/cache/dlimits/$cachename"
1172 function saveDiskLimits
1177 test -e "$vdir"/context || return 0
1179 for dlimit in "$vdir/dlimits/"*; do
1180 test -d "$dlimit" || continue
1181 test ! -e "$dlimit/disabled" || continue
1183 _saveSingleDiskLimit "$vdir" "$dlimit"
1187 function _namespaceCleanup
1190 local root=$($_VSERVER_INFO "$1" VDIR 1)
1195 getFileArray skip "$vdir"/namespace-cleanup-skip \
1196 "$__CONFDIR"/.defaults/namespace-cleanup-skip || :
1198 # these are things that have to be accessible post-cleanup
1199 for tmp in "$root" "$__SBINDIR" "$__PKGLIBDIR" "$vdir" \
1200 "$__PKGSTATEDIR" "${skip[@]}"; do
1201 while test -n "$tmp"; do
1202 list=( "${list[@]}" "$tmp" )
1207 local -a list_umount
1208 while read dev path opts; do
1209 test -n "$path" || continue
1210 for i in "$root" /dev /proc; do
1211 test "${path#$i}" != "$path" && continue 2
1213 for i in "${list[@]}" /; do
1214 test "$path" = "$i" && continue 2
1216 # unmount them in reverse order so mounts further down the tree get unmounted first
1217 list_umount=( "$path" "${list_umount[@]}" )
1219 # separate loop to avoid races while reading /proc/mounts
1220 for i in "${list_umount[@]}"; do