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 test -n "$INITSTYLE" || \
251 getFileValue INITSTYLE "$cfgdir"/style
252 getFileValue RUNLEVEL_START "$cfgdir"/runlevel
253 getFileValue RUNLEVEL_START "$cfgdir"/runlevel.start
254 getFileValue RUNLEVEL_STOP "$cfgdir"/runlevel.stop
255 getFileArray INITKILL_SEQ "$cfgdir"/killseq || :
257 findFile _gio_env "$cfgdir"/environment \
258 "$__CONFDIR"/.defaults/apps/init/environment \
259 "$__PKGLIBDEFAULTDIR"/environment
260 getFileArray OPTS_ENV "$_gio_env" || :
262 case x"$INITSTYLE" in
264 INITCMD_START=( "${INITCMD_RESCUE[@]}" )
265 INITCMD_STOP=( /sbin/killall5 )
271 test -n "$RUNLEVEL_START" || RUNLEVEL_START=3
272 test -n "$RUNLEVEL_STOP" || RUNLEVEL_STOP=6
274 for i in /etc/init.d/rc /etc/rc.d/rc; do
275 test -x "$vdir/vdir/$i" || continue
276 INITCMD_START=( "$i" "$RUNLEVEL_START" )
277 INITCMD_STOP=( "$i" "$RUNLEVEL_STOP" )
279 INITCMD_PREPARE=( $_FAKE_RUNLEVEL "$RUNLEVEL_START" /var/run/utmp )
283 INITCMD_START=( /sbin/init )
284 INITCMD_STOP=( /sbin/init )
286 _NEED_VSHELPER_SYNC=1
287 test -z "$RUNLEVEL_START" || INITCMD_START=( "${INITCMD_START[@]}" "$RUNLEVEL_START" )
288 test -z "$RUNLEVEL_STOP" || INITCMD_STOP=( "${INITCMD_STOP[@]}" "$RUNLEVEL_STOP" )
292 INITCMD_START=( /sbin/minit-start )
293 INITCMD_STOP=( /sbin/minit-stop )
295 INITCMD_START_SYNC=( "$_INITSYNC_MINIT_START" "$vdir" )
296 _NEED_VSHELPER_SYNC=1
297 test -z "$RUNLEVEL_START" || INITCMD_START=( "${INITCMD_START[@]}" "$RUNLEVEL_START" )
298 test -z "$RUNLEVEL_STOP" || INITCMD_STOP=( "${INITCMD_STOP[@]}" "$RUNLEVEL_STOP" )
299 ! isNumber "${RUNLEVEL_START:-3}" || INITCMD_PREPARE=( $_FAKE_RUNLEVEL "${RUNLEVEL_START:-3}" /var/run/utmp )
303 test -n "$RUNLEVEL_START" || RUNLEVEL_START="default"
305 INITCMD_START=( /lib/rcscripts/sh/init-vserver.sh "$RUNLEVEL_START" )
306 INITCMD_STOP=( /sbin/rc shutdown )
307 INITCMD_PREPARE=( $_FAKE_RUNLEVEL 3 /var/run/utmp )
309 pushd "$vdir"/vdir &>/dev/null
310 basever=$($_CHROOT_SH cat /etc/gentoo-release | $_AWK '{print $5}')
313 basemaj=${basever/.*}
314 basemin=${basever#*.}
315 basemin=${basemin/.*}
317 test "$basemaj" -lt 1 -o "$basemin" -lt 13 && \
319 Using init-style 'gentoo' requires >=baselayout-1.13 inside the vserver!
321 Your vserver ($(basename "$vdir")) seems to have baselayout-$basever,
322 please use 'plain' init-style instead!"
326 (*) panic "Unknown init-style '$INITSTYLE'; aborting";;
329 if test x"$INITSTYLE" != xrescue; then
330 getFileArray INITCMD_START "$cfgdir"/cmd.start || :
331 getFileArray INITCMD_STOP "$cfgdir"/cmd.stop || :
332 getFileArray INITCMD_START_SYNC "$cfgdir"/cmd.start-sync || :
333 getFileArray INITCMD_STOP_SYNC "$cfgdir"/cmd.stop-sync || :
334 getFileArray INITCMD_PREPARE "$cfgdir"/cmd.prepare || :
337 test -n "$OPTION_FORCE_SYNC" -o -e "$cfgdir"/sync || {
338 INITCMD_START_SYNC=()
343 if vshelper.isEnabled; then
344 vshelper.getSyncTimeout "$vdir" VSHELPER_SYNC_TIMEOUT || :
350 function _generateFlagOptions
354 CHCONTEXT_FLAG_OPTS=()
356 test ! -e "$vdir"/flags || \
365 OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --flag "$flag" )
366 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}"
372 isAvoidNamespace "$vdir" || {
374 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}" --flag namespace )
378 function _generateChcontextOptions
381 local ctx hostname domainname
386 read ctx <"$vdir"/context || :
388 read hostname <"$vdir"/uts/nodename || read hostname <"$vdir"/hostname || :
389 read domainname <"$vdir"/uts/domainname || read domainname <"$vdir"/domainname || :
392 test -z "$S_CONTEXT" || ctx=$S_CONTEXT
394 _generateCapabilityOptions "$vdir"
395 _generateFlagOptions "$vdir"
397 CHCONTEXT_OPTS=( $SILENT_OPT \
398 "${CHCONTEXT_FLAG_OPTS[@]}" \
401 ${ctx:+--ctx "$ctx"} \
402 ${hostname:+--hostname "$hostname"} \
403 ${domainname:+--domainname "$domainname"} )
405 OPTS_VCONTEXT_CREATE=( $SILENT_OPT \
406 ${ctx:+--xid "$ctx"} )
407 ## put '--secure' at front so that it can be overridden
408 OPTS_VATTRIBUTE=( --secure --flag default "${OPTS_VATTRIBUTE[@]}" )
411 function _generateScheduleOptions
414 if test -d "$vdir"/sched; then
415 OPTS_VSCHED=( --dir "$vdir"/sched --missingok )
419 local f="$vdir"/schedule
420 test -e "$f" || return 0
422 local fill_rate interval tokens tokens_min tokens_max prio_bias
430 read prio_bias || prio_bias=
434 test -n "$prio_bias" || {
435 echo $"Bad content in '$f'; aborting..." >&2
439 OPTS_VSCHED=( --fill-rate "$fill_rate" --interval "$interval" \
440 --tokens "$tokens" --tokens_min "$tokens_min" \
441 --tokens_max "$tokens_max" --priority-bias "$prio_bias" )
444 function _getInterfaceValue
454 read _giv_tmp <"$_giv_i/$_giv_val" && break || :
457 : ${_giv_tmp:=$_giv_dflt}
458 eval $_giv_val=\$_giv_tmp
461 ## Usage: _transformMask2Prefix <result-varname> <prefix> <mask>
462 function _transformMask2Prefix
466 test -n "$_tm2p_tmp" || {
467 $_MASK2PREFIX "$3" || _tm2p_tmp=$?
474 function _addInterfaceCmd
476 eval INTERFACE_CMDS_${INTERFACE_CMDS_IDX}='( "$@" )'
477 let ++INTERFACE_CMDS_IDX
480 ## Usage: _generateMac <var> <iface> <ctx>
481 function _generateMac
484 echo $"Interface basename '$iface' must be either a number, or the mac must be configured explicitly" >&2
488 eval $1=$(printf "f0:ff:%02x:%02x:%02x:%02x" $[ (~($2>>8)) & 0xff ] $[ ($2 & 0xff) ] $[ ($3>>8) & 0xff ] $[ $3 & 0xff ])
491 function _getVLANInfo
496 creation of VLAN_PLUS_VID devices is not supported; please create them
497 before starting the vserver and use the 'nodev' flag then"
498 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID"
502 creation of VLAN_PLUS_VID_NO_PAD devices is not supported; please
503 create them before starting the vserver and use the 'nodev' flag then"
504 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID_N0_PAD"
506 (*.????) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID";;
507 (*.*) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID_NO_PAD";;
514 ## Usage: _processSingleInterface <interface-directory>
515 function _processSingleInterface
530 _getInterfaceValue ip '' "$iface"
531 _getInterfaceValue extip '' "$iface" "$iface/.."
532 _getInterfaceValue dev '' "$iface" "$iface/.."
533 _getInterfaceValue prefix '' "$iface" "$iface/.."
534 _getInterfaceValue mask '' "$iface" "$iface/.."
535 _getInterfaceValue bcast '' "$iface" "$iface/.."
536 _getInterfaceValue name '' "$iface"
537 _getInterfaceValue scope '' "$iface" "$iface/.."
538 _getInterfaceValue mac '' "$iface"
540 test -n "$ip" || { echo $"Can not read ip for '$iface'" >&2; return 1; }
541 test -n "$dev" -o -e "$iface"/nodev || {
542 echo $"No device specified for '$iface'" >&2
546 test ! -e "$iface"/down || up=
549 _transformMask2Prefix prefix "$prefix" "$mask"
550 INTERFACES=( "${INTERFACES[@]}" "$ip${prefix:+/$prefix}" )
552 test ! -e "$iface"/nodev || break
554 test ! -e "$iface"/only_ip || break
557 if vlan_info=$(_getVLANInfo "$dev"); then
558 test -d /proc/net/vlan || {
559 echo -e $"VLAN device-name used, but vlan subsystem not enabled.\nTry to execute 'modprobe 8021q' before starting the vservers" >&2
562 test -e "$iface/vlandev" \
563 -o \( -e "$iface/../vlandev" -a ! -e "$iface/novlandev" \) \
564 -o \( -e "$__CONFDIR/.defaults/interfaces/vlandev" \
565 -a ! -e "$iface/novlandev" \
566 -a ! -e "$iface/../novlandev" \) && {
567 _addInterfaceCmd VCONFIG $vlan_info
571 if ! test -e "$iface"/indirect; then
572 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" broadcast ${bcast:-+} ${name:+label "$dev:$name"} dev "$dev"
573 #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
574 _addInterfaceCmd IP_LINK "$dev" $up
575 elif ! test -n "$ctx"; then
576 echo $"Using 'dummy' (indirect) for interface '$dev' requires a fixed context number; dynamic ctx are not supported" >&2
579 test -z "$mac" || _generateMac mac "$(basename $iface)" "$ctx" || return 1
580 _addInterfaceCmd MODPROBE dummy "$dev"
581 _addInterfaceCmd IP_LINK dev dummy0 address "$mac"
582 _addInterfaceCmd NAMEIF "$dev" "$mac"
583 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" dev "$dev"
584 test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$ctx" "$extip"
591 ## Usage: _generateInterfaceOptions <vserver-directory>
592 function _generateInterfaceOptions
597 test ! -e "$1"/context || read ctx <"$1"/context
599 for iface in "$1/interfaces/"*; do
600 test -d "$iface" || continue
601 test ! -e "$iface"/disabled || continue
603 _processSingleInterface "$iface"
605 _HAVE_INTERFACE_OPTIONS=1
608 function enableInterfaces
613 lock "$__LOCKDIR"/vserver.interfaces
615 while test $i -lt $INTERFACE_CMDS_IDX; do
616 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
627 $_MODPROBE ${name:+-o "$name"} "$mod" "$@"
629 NAMEIF) $_NAMEIF "$@";;
630 VCONFIG) $_VCONFIG set_name_type "$4" >/dev/null
631 $_VCONFIG add "$2" "$3" >/dev/null;;
632 IP_ADDR) $_IP addr add "$@";;
633 IP_ADDR_FLUSH) $_IP addr flush "$@";;
634 IP_LINK) $_IP link set "$@";;
635 IP_ROUTE) $_IP route add "$@";;
636 *) echo "Unknown interface-command type '$type'" >&2; false;;
645 function disableInterfaces
647 test -n "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$1"
649 local i=$INTERFACE_CMDS_IDX
652 lock "$__LOCKDIR"/vserver.interfaces
654 while test $i -gt 0; do
657 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
664 MODPROBE) $_RMMOD "${2:-$1}";;
666 VCONFIG) $_VCONFIG rem "$2.$3" >/dev/null;;
667 IP_ADDR) $_IP addr del "$@";;
669 IP_LINK) ;; ## Ignore the link-down command for now
670 IP_ROUTE) $_IP route del "$@";;
671 *) echo "Unknown interface-command type '$type'" >&2; false;;
678 ## Usage: prepareInit <vserver-directory>
681 pushd "$1/vdir" >/dev/null
684 { find var/run ! -type d -print0; \
685 find var/lock ! -type d -print0; } | xargs -0r $_CHROOT_SH rm
688 $_CHROOT_SH rm .autofsck forcefsck 2>/dev/null || :
689 : | $_CHROOT_SH truncate fastboot 2>/dev/null || :
694 "${INITCMD_PREPARE[@]}"
698 ## Usage: prepareInit <vserver-directory>
701 pushd "$1/vdir" >/dev/null
704 export PREVLEVEL=$RUNLEVEL_START # required by Debian's initscripts
707 "${STOPCMD_PREPARE[@]}"
712 function generateOptions
714 _generateInterfaceOptions "$1"
715 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
716 _generateNiceCommand "$1"
717 _generateInitOptions "$1"
718 _generateChcontextOptions "$1"
719 _generateScheduleOptions "$1"
720 _generatePersonalityOptions "$1"
722 if test -n "$_IS_FAKEINIT"; then
723 CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
724 OPTS_VCONTEXT_MIGRATE=( "${OPTS_VCONTEXT_MIGRATE[@]}" --initpid --disconnect )
732 local f="$vdir"/cpuset
736 test -d "$f" || return 0
737 test -e "$f"/name || return 0
739 read cpuset < "$f"/name
740 test -e "$f"/nocreate || {
741 test -d /dev/cpuset/"$cpuset" || mkdir /dev/cpuset/"$cpuset" || configured=1
742 for i in cpus mems cpu_exclusive mem_exclusive virtualized; do
743 if test -e "$f"/"$i"; then
744 cat "$f"/"$i" >/dev/cpuset/"$cpuset"/"$i" || {
752 echo $$ >/dev/cpuset/"$cpuset"/tasks || configured=1
753 if [ "$configured" -ne 0 ]; then
755 WARNING: Failed to create or CPUSET \"$cpuset\" does not exist! Not using it!" >&2
756 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
761 function removeCPUSET
765 local f="$vdir"/cpuset
767 test -d "$f" || return 0
768 test -e "$f"/name || return 0
770 read cpuset < "$f"/name
771 test -e "$f"/nocreate || {
772 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
776 function _mountVserverInternal
781 test -e "$fstab" || return 0
784 pushd "$vdir" >/dev/null
785 # check whether / is mounted readonly or whether there is special
786 # magic regarding the mtab file; when etc/mtab can not be touched,
787 # add the '-n' flag to mount
788 test -w etc -o -w etc/mtab || xflag=-n
789 "$@" $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs no
797 local fstab="$cfgdir"/fstab
800 test -e "$fstab" || return 0
801 pushd "$vdir" >/dev/null
802 # check whether / is mounted readonly or whether there is special
803 # magic regarding the mtab file; when etc/mtab can not be touched,
804 # add the '-n' flag to mount
805 test -w etc -o -w etc/mtab || xflag=-n
806 $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs only -n
810 function mountVserver
817 test -e "$cfgdir"/fstab -o \
818 -e "$cfgdir"/fstab.local -o \
819 -e "$cfgdir"/fstab.remote || return 0
821 findObject -r mtab_src "$cfgdir"/apps/init/mtab "$__CONFDIR"/.defaults/init/mtab "$__PKGLIBDEFAULTDIR"/mtab /dev/null
823 pushd "$vdir" >/dev/null
824 $_CHROOT_SH truncate /etc/mtab <"$mtab_src"
827 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
829 _mountVserverInternal "$cfgdir"/fstab
830 _mountVserverInternal "$cfgdir"/fstab.local
831 _mountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}"
833 isNamespaceCleanup "$cfgdir" && \
834 _namespaceCleanup "$cfgdir"
836 isAvoidNamespace "$cfgdir" || \
837 $_SECURE_MOUNT --rbind -n "$vdir" "/"
840 function _umountVserverInternal
843 test -e "$fstab" || return 0
848 while read src dst tmp; do
849 test -n "$tmp" || continue
855 "$@" $_EXEC_CD "$dst" $_UMOUNT -lfn . || is_ok=
861 function umountVserver
867 isAvoidNamespace "$cfgdir" || return 0
868 test -e "$cfgdir"/fstab -o \
869 -e "$cfgdir"/fstab.local -o \
870 -e "$cfgdir"/fstab.remote || return 0
871 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
873 pushd "$vdir/" >/dev/null || return 1
874 _umountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}" || is_ok=
875 _umountVserverInternal "$cfgdir"/fstab.local || is_ok=
876 _umountVserverInternal "$cfgdir"/fstab || is_ok=
877 popd >/dev/null || return 1
882 ## Usage: waitForSync <vserver> <context> <vshelper-fifo-varname>
886 test -n "$_NEED_VSHELPER_SYNC" && \
887 ! $_VSERVER_INFO - FEATURE vwait || _is_meth=async
889 vshelper.initSync "$1" "$3" "$_is_meth"
892 ## Usage: initWait <vserver> <context> <vwait-tmpdir-varname>
895 if $_VSERVER_INFO - FEATURE vwait; then
897 _is_tmpdir=$($_MKTEMPDIR vwaitstat.XXXXXX)
900 $_VWAIT --timeout "$VSHELPER_SYNC_TIMEOUT" \
902 >>$_is_tmpdir/out 2>$_is_tmpdir/err 3>$_is_tmpdir/fifo
905 if test "$rc" -ne 0 -a "$rc" -ne 1; then
906 $_VPS axf | $_EGREP -e "^[^ \t]+[ \t]+$S_CONTEXT[ \t]+" >&4
907 killContext "$S_CONTEXT" 9
911 ) 4>$_is_tmpdir/procs &
913 echo "$!" >$_is_tmpdir/pid
914 eval "$3"=$_is_tmpdir
919 ## Usage: _waitForVWait <vserver> <fifo> <pid> <procs>
920 function _waitForVWait
925 declare -r procs=$(cat $4)
927 getFileArray status "$2"
932 'vwait' exited with error '$2' which indicates that vserver could not
937 A timeout occured while waiting for the vserver to finish and it was
938 killed by sending a SIGKILL signal. Please investigate the reasons
939 and/or increase the timeout in apps/vshelper/sync-timeout."
942 (TIMEOUT) warning $"\
943 A timeout occured while waiting for the vserver to finish and it will
944 be killed by sending a SIGKILL signal. The following process list
945 might be useful for finding out the reason of this behavior:
947 ----------------------------------------------------------------------
949 }----------------------------------------------------------------------"
952 (\?\?\?|*) warning $"\
953 internal error: 'vwait' exited with an unexpected status '$1'; I will
954 try to continue but be prepared for unexpected events."
961 ## Usage: waitForSync <vserver> [<vshelper-fifo>] [<vwait-statdir>]
966 local vwait_statdir=$3
969 if test -d "$vwait_statdir"; then
970 _waitForVWait "$cfgdir" "$vwait_statdir/fifo" "$( <$vwait_statdir/pid )" "$vwait_statdir/procs"
971 elif test -n "$_NEED_VSHELPER_SYNC"; then
972 $_VSHELPER_SYNC "$fifo" "$VSHELPER_SYNC_TIMEOUT" || \
974 A timeout or other error occured while waiting for the synchronization
975 signal from vserver '$VSERVER_NAME'.
976 The vserver will be killed nevertheless..."
977 elif test "${#INITCMD_STOP_SYNC[@]}" -ne 0; then
978 "${INITCMD_STOP_SYNC[@]}" || \
980 Stop-synchronization for vserver '$VSERVER_NAME' failed. The vserver
981 will be killed nevertheless..."
984 test -z "$OPTION_FORCE_SYNC" -a ! -e "$cfgdir"/sync ||
990 local vdir name flavor start i already_handled base
994 ## Usage: execScriptlets <vserver-cfgdir> <vserver-name> <script-flavor>
995 function execScriptlets
1002 for base in "$vdir"/scripts "$__CONFDIR"/.defaults/scripts; do
1003 local DONT_SKIP_DEFAULTS=
1004 local already_handled=
1006 for i in "$base/$flavor" "$base/$flavor.d"/*; do
1007 isRegularFile "$i" || continue
1008 test -r "$i" || continue
1012 test -x "$i" || start=_sourceWrap
1013 $start "$i" "$flavor" "$name"
1016 test -z "$already_handled" -o -n "$DONT_SKIP_DEFAULTS" || break
1021 function sanityCheck
1023 declare -r cfgdir=$1
1025 ! test -e "$cfgdir"/fstab.local ||
1027 WARNING: 'fstab' will *not* be executed in the network context of the
1028 vserver anymore. Therefore, 'fstab.local' has the same functionality
1029 and is obsoleted. When you need the old behaviour, put the mounts
1030 into 'fstab.remote'"
1032 ! test -e "$cfgdir"/hostname -a ! -L "$cfgdir"/hostname ||
1034 WARNING: The hostname is now configured in 'uts/nodename' but not in
1037 ! test -e "$cfgdir"/domainname -a ! -L "$cfgdir"/domainname ||
1039 WARNING: The domainname is now configured in 'uts/domainname' but not
1040 in 'domainname'." >&2
1044 for i in "$cfgdir"/interfaces/*/only_ip; do
1045 if test -e "$i"; then
1047 iface=${i##$cfgdir/interfaces/}
1048 iface=${iface%%/only_ip}
1050 WARNING: The 'only_ip' flag for interface '$iface' is deprecated; use
1055 test ! -d "$cfgdir"/dlimits -o -L "$cfgdir/cache" || \
1057 WARNING: There is no cachedirectory configured for this vserver;
1058 please create '$cfgdir/cache' e.g. by executing
1060 ln -s ../.defaults/cachebase/$VSERVER_NAME $cfgdir/cache
1063 find "$cfgdir" -type f -exec "$_CHECK_UNIXFILE" '{}' ';'
1065 vshelper.doSanityCheck
1067 $_VSERVER_INFO - VERIFYCAP ||
1068 panic $"capabilities are not enabled in kernel-setup"
1070 $_VSERVER_INFO - VERIFYPROC ||
1072 /proc/uptime can not be accessed. Usually, this is caused by
1073 procfs-security. Please read the FAQ for more details
1074 http://www.linux-vserver.org/index.php?page=Linux-Vserver+FAQ"
1078 function _setSingleDiskLimit
1090 getFileValue ctx "$vdir/context"
1091 getFileValue directory "$dlimit/directory" || return 0
1092 getFileValue space_total "$dlimit/space_total" || return 0
1093 getFileValue inodes_total "$dlimit/inodes_total" || return 0
1094 getFileValue reserved "$dlimit/reserved" || return 0
1096 local cachename=$ctx$directory
1097 cachename=dlimits/${cachename//\//_}
1099 test -e "$vdir/cache/$cachename" && . "$vdir/cache/$cachename"
1100 # Remove the cache so if the machine goes down unexpectedly, we won't have a stale cache
1101 $_RM -f "$vdir/cache/$cachename"
1103 if test -z "$inodes_used" -o -z "$space_used"; then
1105 tmpvdu=`$_VDU --xid $ctx --space --inodes --script "$directory"`
1106 inodes_used=${tmpvdu##* }
1107 space_used=${tmpvdu%% *}
1110 $_VDLIMIT --xid $ctx \
1111 --set space_used=$space_used \
1112 --set space_total=$space_total \
1113 --set inodes_used=$inodes_used \
1114 --set inodes_total=$inodes_total \
1115 --set reserved=$reserved \
1120 function setDiskLimits
1125 # Disk Limits without a static context are useless
1126 test -e "$vdir"/context || return 0
1128 for dlimit in "$vdir/dlimits/"*; do
1129 test -d "$dlimit" || continue
1130 test ! -e "$dlimit/disabled" || continue
1132 _setSingleDiskLimit "$vdir" "$dlimit"
1137 function _saveSingleDiskLimit
1144 getFileValue ctx "$vdir/context"
1145 getFileValue directory "$dlimit/directory" || return 0
1147 local cachename=$ctx$directory
1148 cachename=${cachename//\//_}
1150 # Things are getting ugly here... LFS says that /var/cache (where
1151 # cachename is usually pointing to) can vanish and applications
1152 # have to deal with it. So, we have to interprete the $vdir/cache
1153 # symlink and have to create the needed directories manually.
1154 if test -d "$vdir/cache"; then
1155 : # ok, exists already
1156 elif test -L "$vdir/cache"; then
1157 # it's a dangling symlink
1159 link=$($_READLINK "$vdir/cache")
1160 ( cd $vdir && $_MKDIR -p "$link" )
1165 test -d "$vdir/cache"
1166 $_MKDIR -p "$vdir"/cache/dlimits
1168 $_VDLIMIT --xid $ctx "$directory" | \
1169 $_GREP '_used=' > "$vdir/cache/dlimits/$cachename"
1173 function saveDiskLimits
1178 test -e "$vdir"/context || return 0
1180 for dlimit in "$vdir/dlimits/"*; do
1181 test -d "$dlimit" || continue
1182 test ! -e "$dlimit/disabled" || continue
1184 _saveSingleDiskLimit "$vdir" "$dlimit"
1188 function _namespaceCleanup
1191 local root=$($_VSERVER_INFO "$1" VDIR 1)
1196 getFileArray skip "$vdir"/namespace-cleanup-skip \
1197 "$__CONFDIR"/.defaults/namespace-cleanup-skip || :
1199 # these are things that have to be accessible post-cleanup
1200 for tmp in "$root" "$__SBINDIR" "$__PKGLIBDIR" "$vdir" \
1201 "$__PKGSTATEDIR" "${skip[@]}"; do
1202 while test -n "$tmp"; do
1203 list=( "${list[@]}" "$tmp" )
1208 local -a list_umount
1209 while read dev path opts; do
1210 test -n "$path" || continue
1211 for i in "$root" /dev /proc; do
1212 test "${path#$i}" != "$path" && continue 2
1214 for i in "${list[@]}" /; do
1215 test "$path" = "$i" && continue 2
1217 # unmount them in reverse order so mounts further down the tree get unmounted first
1218 list_umount=( "$path" "${list_umount[@]}" )
1220 # separate loop to avoid races while reading /proc/mounts
1221 for i in "${list_umount[@]}"; do