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 _readFileToArray
83 test -e "$_rfta_f" || return 0
84 while read _rfta_v; do
87 (*) eval "$_rfta_a=( \"\${$_rfta_a[@]}\" $_rfta_p \"$_rfta_v\" )";;
92 function _generateChbindOptions
99 test -n "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$vdir"
101 local f=$vdir/interfaces/bcast
102 getFileValue bcast "$f"
104 getFileValue nid "$vdir/ncontext" "$vdir/context"
106 CHBIND_OPTS=( $SILENT_OPT --secure ${nid:+--nid "$nid"} ${bcast:+--bcast "$bcast"} )
108 for i in "${INTERFACES[@]}"; do
109 CHBIND_OPTS=( "${CHBIND_OPTS[@]}" --ip "$i" )
112 _readFileToArray "$vdir"/nflags CHBIND_OPTS --flag
113 _readFileToArray "$vdir"/ncapabilities CHBIND_OPTS --ncap
115 _HAVE_CHBIND_OPTIONS=1
118 function _generateNiceCommand
122 local current_nice=`$_NICE`
124 test -r "$vdir/nice" && read nice <"$vdir"/nice
126 let nice=$nice-$current_nice || :
127 NICE_CMD=( $_NICE -n $nice )
131 function _generatePersonalityOptions
134 local f="$vdir"/personality
137 test -s "$f" || return 0
146 (*) flags=$flags$delim$tmp
153 OPTS_VCONTEXT_ENTER=( "${OPTS_VCONTEXT_ENTER[@]}"
154 --personality-type "$type"
155 ${flags:+--personality-flags "$flags"} )
158 function _generateCCapabilityOptions
162 _readFileToArray "$vdir"/ccapabilities OPTS_VATTRIBUTE --ccap
165 function _generateBCapabilityOptions
169 _readFileToArray "$vdir"/bcapabilities OPTS_VATTRIBUTE --bcap
172 function _generateCapabilityOptions
177 _generateBCapabilityOptions "$vdir"
178 _generateCCapabilityOptions "$vdir"
180 test -e "$vdir"/capabilities || return 0
189 CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" )
190 CAPCHROOT_OPTS=( "${CAPCHROOT_OPTS[@]}" --nochroot )
193 CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" )
196 done <"$vdir"/capabilities
199 function getEnterShell
206 getFileValue ENTER_SHELL "$vdir"/shell "$__CONFDIR"/.defaults/shell
208 test -n "$ENTER_SHELL" || {
210 for i in "/bin/bash -login" "/bin/sh -l" /bin/csh; do
212 test -x "$vdir/vdir/$1" || continue
219 ## Usage: sendKillSequence <ctx> <signal> [<wait> <signal>]*
220 function sendKillSequence
226 while isCtxRunning "$ctx"; do
227 test -z "$wait" || sleep "$wait"
229 killContext "$ctx" "$1"
230 test -n "$2" || break
236 function _generateInitOptions
239 local cfgdir=$vdir/apps/init
244 INITCMD_START_SYNC=()
249 INITKILL_SEQ=( 15 5 9 )
250 CHCONTEXT_INIT_OPTS=()
253 test x"$INITSTYLE" = xrescue || \
254 getFileValue INITSTYLE "$cfgdir"/style
255 getFileValue RUNLEVEL_START "$cfgdir"/runlevel
256 getFileValue RUNLEVEL_START "$cfgdir"/runlevel.start
257 getFileValue RUNLEVEL_STOP "$cfgdir"/runlevel.stop
258 getFileArray INITKILL_SEQ "$cfgdir"/killseq || :
260 findFile _gio_env "$cfgdir"/environment \
261 "$__CONFDIR"/.defaults/apps/init/environment \
262 "$__PKGLIBDEFAULTDIR"/environment
263 getFileArray OPTS_ENV "$_gio_env" || :
265 case x"$INITSTYLE" in
267 INITCMD_START=( "${INITCMD_RESCUE[@]}" )
268 INITCMD_STOP=( /sbin/killall5 )
272 test -n "$RUNLEVEL_START" || RUNLEVEL_START=3
273 test -n "$RUNLEVEL_STOP" || RUNLEVEL_STOP=6
275 for i in /etc/init.d/rc /etc/rc.d/rc; do
276 test -x "$vdir/vdir/$i" || continue
277 INITCMD_START=( "$i" "$RUNLEVEL_START" )
278 INITCMD_STOP=( "$i" "$RUNLEVEL_STOP" )
280 INITCMD_PREPARE=( $_FAKE_RUNLEVEL "$RUNLEVEL_START" /var/run/utmp )
281 OPTS_ENV=( "${OPTS_ENV[@]}" PREVLEVEL=N RUNLEVEL="$RUNLEVEL_START" )
285 INITCMD_START=( /sbin/init )
286 INITCMD_STOP=( /sbin/init )
288 _NEED_VSHELPER_SYNC=1
289 test -z "$RUNLEVEL_START" || INITCMD_START=( "${INITCMD_START[@]}" "$RUNLEVEL_START" )
290 test -z "$RUNLEVEL_STOP" || INITCMD_STOP=( "${INITCMD_STOP[@]}" "$RUNLEVEL_STOP" )
294 INITCMD_START=( /sbin/minit-start )
295 INITCMD_STOP=( /sbin/minit-stop )
297 INITCMD_START_SYNC=( "$_INITSYNC_MINIT_START" "$vdir" )
298 _NEED_VSHELPER_SYNC=1
299 test -z "$RUNLEVEL_START" || INITCMD_START=( "${INITCMD_START[@]}" "$RUNLEVEL_START" )
300 test -z "$RUNLEVEL_STOP" || INITCMD_STOP=( "${INITCMD_STOP[@]}" "$RUNLEVEL_STOP" )
301 ! isNumber "${RUNLEVEL_START:-3}" || INITCMD_PREPARE=( $_FAKE_RUNLEVEL "${RUNLEVEL_START:-3}" /var/run/utmp )
305 test -n "$RUNLEVEL_START" || RUNLEVEL_START="default"
307 INITCMD_START=( env TERM=$TERM /lib/rcscripts/sh/init-vserver.sh "$RUNLEVEL_START" )
308 INITCMD_STOP=( env -i TERM=$TERM RUNLEVEL=0 /sbin/rc shutdown )
309 INITCMD_PREPARE=( $_FAKE_RUNLEVEL 3 /var/run/utmp )
313 (*) panic "Unknown init-style '$INITSTYLE'; aborting";;
316 if test x"$INITSTYLE" != xrescue; then
317 getFileArray INITCMD_START "$cfgdir"/cmd.start || :
318 getFileArray INITCMD_STOP "$cfgdir"/cmd.stop || :
319 getFileArray INITCMD_START_SYNC "$cfgdir"/cmd.start-sync || :
320 getFileArray INITCMD_STOP_SYNC "$cfgdir"/cmd.stop-sync || :
321 getFileArray INITCMD_PREPARE "$cfgdir"/cmd.prepare || :
324 test -n "$OPTION_FORCE_SYNC" -o -e "$cfgdir"/sync || {
325 INITCMD_START_SYNC=()
330 if vshelper.isEnabled; then
331 vshelper.getSyncTimeout "$vdir" VSHELPER_SYNC_TIMEOUT || :
337 function _generateFlagOptions
341 CHCONTEXT_FLAG_OPTS=()
343 test ! -e "$vdir"/flags || \
352 OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --flag "$flag" )
353 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}"
359 isAvoidNamespace "$vdir" || {
361 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}" --flag namespace )
365 function _generateChcontextOptions
368 local ctx hostname domainname
373 read ctx <"$vdir"/context || :
375 read hostname <"$vdir"/uts/nodename || read hostname <"$vdir"/hostname || :
376 read domainname <"$vdir"/uts/domainname || read domainname <"$vdir"/domainname || :
379 test -z "$S_CONTEXT" || ctx=$S_CONTEXT
381 _generateCapabilityOptions "$vdir"
382 _generateFlagOptions "$vdir"
384 CHCONTEXT_OPTS=( $SILENT_OPT \
385 "${CHCONTEXT_FLAG_OPTS[@]}" \
388 ${ctx:+--ctx "$ctx"} \
389 ${hostname:+--hostname "$hostname"} \
390 ${domainname:+--domainname "$domainname"} )
392 OPTS_VCONTEXT_CREATE=( $SILENT_OPT \
393 ${ctx:+--xid "$ctx"} )
394 ## put '--secure' at front so that it can be overridden
395 OPTS_VATTRIBUTE=( --secure --flag default "${OPTS_VATTRIBUTE[@]}" )
398 function _generateScheduleOptions
401 if test -d "$vdir"/sched; then
402 OPTS_VSCHED=( --dir "$vdir"/sched --missingok )
406 local f="$vdir"/schedule
407 test -e "$f" || return 0
409 local fill_rate interval tokens tokens_min tokens_max prio_bias
417 read prio_bias || prio_bias=
421 test -n "$prio_bias" || {
422 echo $"Bad content in '$f'; aborting..." >&2
426 OPTS_VSCHED=( --fill-rate "$fill_rate" --interval "$interval" \
427 --tokens "$tokens" --tokens_min "$tokens_min" \
428 --tokens_max "$tokens_max" --priority-bias "$prio_bias" )
431 function _getInterfaceValue
441 read _giv_tmp <"$_giv_i/$_giv_val" && break || :
444 : ${_giv_tmp:=$_giv_dflt}
445 eval $_giv_val=\$_giv_tmp
448 ## Usage: _transformMask2Prefix <result-varname> <prefix> <mask>
449 function _transformMask2Prefix
453 test -n "$_tm2p_tmp" || {
454 $_MASK2PREFIX "$3" || _tm2p_tmp=$?
461 function _addInterfaceCmd
463 eval INTERFACE_CMDS_${INTERFACE_CMDS_IDX}='( "$@" )'
464 let ++INTERFACE_CMDS_IDX
467 ## Usage: _generateMac <var> <iface> <ctx>
468 function _generateMac
471 echo $"Interface basename '$iface' must be either a number, or the mac must be configured explicitly" >&2
475 eval $1=$(printf "f0:ff:%02x:%02x:%02x:%02x" $[ (~($2>>8)) & 0xff ] $[ ($2 & 0xff) ] $[ ($3>>8) & 0xff ] $[ $3 & 0xff ])
478 function _getVLANInfo
483 creation of VLAN_PLUS_VID devices is not supported; please create them
484 before starting the vserver and use the 'nodev' flag then"
485 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID"
489 creation of VLAN_PLUS_VID_NO_PAD devices is not supported; please
490 create them before starting the vserver and use the 'nodev' flag then"
491 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID_N0_PAD"
493 (*.????) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID";;
494 (*.*) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID_NO_PAD";;
501 ## Usage: _processSingleInterface <interface-directory>
502 function _processSingleInterface
517 _getInterfaceValue ip '' "$iface"
518 _getInterfaceValue extip '' "$iface" "$iface/.."
519 _getInterfaceValue dev '' "$iface" "$iface/.."
520 _getInterfaceValue prefix '' "$iface" "$iface/.."
521 _getInterfaceValue mask '' "$iface" "$iface/.."
522 _getInterfaceValue bcast '' "$iface" "$iface/.."
523 _getInterfaceValue name '' "$iface"
524 _getInterfaceValue scope '' "$iface" "$iface/.."
525 _getInterfaceValue mac '' "$iface"
527 test -n "$ip" || { echo $"Can not read ip for '$iface'" >&2; return 1; }
528 test -n "$dev" -o -e "$iface"/nodev || {
529 echo $"No device specified for '$iface'" >&2
533 test ! -e "$iface"/down || up=
536 _transformMask2Prefix prefix "$prefix" "$mask"
537 INTERFACES=( "${INTERFACES[@]}" "$ip${prefix:+/$prefix}" )
539 test ! -e "$iface"/nodev || break
541 test ! -e "$iface"/only_ip || break
543 test -e "$iface/vlandev" \
544 -o \( -e "$iface/../vlandev" -a ! -e "$iface/novlandev" \) \
545 -o \( -e "$__CONFDIR/.defaults/interfaces/vlandev" \
546 -a ! -e "$iface/novlandev" \
547 -a ! -e "$iface/../novlandev" \) && {
549 if vlan_info=$(_getVLANInfo "$dev"); then
550 test -d /proc/net/vlan || {
551 echo -e $"VLAN device-name used, but vlan subsystem not enabled.\nTry to execute 'modprobe 8021q' before starting the vservers" >&2
554 _addInterfaceCmd VCONFIG $vlan_info
558 if ! test -e "$iface"/indirect; then
560 use_bcast="broadcast ${bcast:-+}"
561 echo "$ip" | $_GREP -q : && use_bcast=
562 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" $use_bcast ${name:+label "$dev:$name"} dev "$dev"
563 #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
564 _addInterfaceCmd IP_LINK "$dev" $up
565 elif ! test -n "$ctx"; then
566 echo $"Using 'dummy' (indirect) for interface '$dev' requires a fixed context number; dynamic ctx are not supported" >&2
569 test -z "$mac" || _generateMac mac "$(basename $iface)" "$ctx" || return 1
570 _addInterfaceCmd MODPROBE dummy "$dev"
571 _addInterfaceCmd IP_LINK dev dummy0 address "$mac"
572 _addInterfaceCmd NAMEIF "$dev" "$mac"
573 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" dev "$dev"
574 test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$ctx" "$extip"
581 ## Usage: _generateInterfaceOptions <vserver-directory>
582 function _generateInterfaceOptions
587 test ! -e "$1"/context || read ctx <"$1"/context
589 for iface in "$1/interfaces/"*; do
590 test -d "$iface" || continue
591 test ! -e "$iface"/disabled || continue
593 _processSingleInterface "$iface"
595 _HAVE_INTERFACE_OPTIONS=1
598 function enableInterfaces
603 lock "$__LOCKDIR"/vserver.interfaces
605 while test $i -lt $INTERFACE_CMDS_IDX; do
606 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
617 $_MODPROBE ${name:+-o "$name"} "$mod" "$@"
619 NAMEIF) $_NAMEIF "$@";;
620 VCONFIG) $_VCONFIG set_name_type "$4" >/dev/null
621 $_VCONFIG add "$2" "$3" >/dev/null;;
622 IP_ADDR) $_IP addr add "$@";;
623 IP_ADDR_FLUSH) $_IP addr flush "$@";;
624 IP_LINK) $_IP link set "$@";;
625 IP_ROUTE) $_IP route add "$@";;
626 *) echo "Unknown interface-command type '$type'" >&2; false;;
635 function disableInterfaces
637 test -n "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$1"
639 local i=$INTERFACE_CMDS_IDX
642 lock "$__LOCKDIR"/vserver.interfaces
644 while test $i -gt 0; do
647 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
654 MODPROBE) $_RMMOD "${2:-$1}";;
656 VCONFIG) $_VCONFIG rem "$2.$3" >/dev/null;;
657 IP_ADDR) $_IP addr del "$@";;
659 IP_LINK) ;; ## Ignore the link-down command for now
660 IP_ROUTE) $_IP route del "$@";;
661 *) echo "Unknown interface-command type '$type'" >&2; false;;
668 ## Usage: prepareInit <vserver-directory>
671 pushd "$1/vdir" >/dev/null
674 { find var/run ! -type d -print0; \
675 find var/lock ! -type d -print0; } | xargs -0r $_CHROOT_SH rm
678 $_CHROOT_SH rm .autofsck forcefsck 2>/dev/null || :
679 : | $_CHROOT_SH truncate fastboot 2>/dev/null || :
684 "${INITCMD_PREPARE[@]}"
688 ## Usage: prepareInit <vserver-directory>
691 pushd "$1/vdir" >/dev/null
694 export PREVLEVEL=$RUNLEVEL_START RUNLEVEL=$RUNLEVEL_STOP # required by Debian's initscripts
697 "${STOPCMD_PREPARE[@]}"
702 function generateOptions
704 _generateInterfaceOptions "$1"
705 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
706 _generateNiceCommand "$1"
707 _generateInitOptions "$1"
708 _generateChcontextOptions "$1"
709 _generateScheduleOptions "$1"
710 _generatePersonalityOptions "$1"
712 if test -n "$_IS_FAKEINIT"; then
713 CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
714 OPTS_VCONTEXT_MIGRATE=( "${OPTS_VCONTEXT_MIGRATE[@]}" --initpid --disconnect )
722 local f="$vdir"/cpuset
726 test -d "$f" || return 0
727 test -e "$f"/name || return 0
729 read cpuset < "$f"/name
730 test -e "$f"/nocreate || {
731 test -d /dev/cpuset/"$cpuset" || mkdir /dev/cpuset/"$cpuset" || configured=1
732 for i in cpus mems cpu_exclusive mem_exclusive virtualized; do
733 if test -e "$f"/"$i"; then
734 cat "$f"/"$i" >/dev/cpuset/"$cpuset"/"$i" || {
742 echo $$ >/dev/cpuset/"$cpuset"/tasks || configured=1
743 if [ "$configured" -ne 0 ]; then
745 WARNING: Failed to create or CPUSET \"$cpuset\" does not exist! Not using it!" >&2
746 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
751 function removeCPUSET
755 local f="$vdir"/cpuset
757 test -d "$f" || return 0
758 test -e "$f"/name || return 0
760 read cpuset < "$f"/name
761 test -e "$f"/nocreate || {
762 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
766 function _mountVserverInternal
771 test -e "$fstab" || return 0
774 pushd "$vdir" >/dev/null
775 # check whether / is mounted readonly or whether there is special
776 # magic regarding the mtab file; when etc/mtab can not be touched,
777 # add the '-n' flag to mount
778 test -w etc -o -w etc/mtab || xflag=-n
779 "$@" $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs no
787 local fstab="$cfgdir"/fstab
790 test -e "$fstab" || return 0
791 pushd "$vdir" >/dev/null
792 # check whether / is mounted readonly or whether there is special
793 # magic regarding the mtab file; when etc/mtab can not be touched,
794 # add the '-n' flag to mount
795 test -w etc -o -w etc/mtab || xflag=-n
796 $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs only -n
800 function mountVserver
807 test -e "$cfgdir"/fstab -o \
808 -e "$cfgdir"/fstab.local -o \
809 -e "$cfgdir"/fstab.remote || return 0
811 findObject -r mtab_src "$cfgdir"/apps/init/mtab "$__CONFDIR"/.defaults/init/mtab "$__PKGLIBDEFAULTDIR"/mtab /dev/null
813 pushd "$vdir" >/dev/null
814 $_CHROOT_SH truncate /etc/mtab <"$mtab_src"
817 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
819 _mountVserverInternal "$cfgdir"/fstab
820 _mountVserverInternal "$cfgdir"/fstab.local
821 _mountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}"
823 isNamespaceCleanup "$cfgdir" && \
824 _namespaceCleanup "$cfgdir"
826 isAvoidNamespace "$cfgdir" || \
827 $_SECURE_MOUNT --rbind -n "$vdir" "/"
830 function _umountVserverInternal
833 test -e "$fstab" || return 0
838 while read src dst tmp; do
839 test -n "$tmp" || continue
845 "$@" $_EXEC_CD "$dst" $_UMOUNT -lfn . || is_ok=
851 function umountVserver
857 isAvoidNamespace "$cfgdir" || return 0
858 test -e "$cfgdir"/fstab -o \
859 -e "$cfgdir"/fstab.local -o \
860 -e "$cfgdir"/fstab.remote || return 0
861 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
863 pushd "$vdir/" >/dev/null || return 1
864 _umountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}" || is_ok=
865 _umountVserverInternal "$cfgdir"/fstab.local || is_ok=
866 _umountVserverInternal "$cfgdir"/fstab || is_ok=
867 popd >/dev/null || return 1
872 ## Usage: waitForSync <vserver> <context> <vshelper-fifo-varname>
876 test -n "$_NEED_VSHELPER_SYNC" && \
877 ! $_VSERVER_INFO - FEATURE vwait || _is_meth=async
879 vshelper.initSync "$1" "$3" "$_is_meth"
882 ## Usage: initWait <vserver> <context> <vwait-tmpdir-varname>
885 if $_VSERVER_INFO - FEATURE vwait; then
887 _is_tmpdir=$($_MKTEMPDIR vwaitstat.XXXXXX)
890 $_VWAIT --timeout "$VSHELPER_SYNC_TIMEOUT" \
892 >>$_is_tmpdir/out 2>$_is_tmpdir/err 3>$_is_tmpdir/fifo
895 if test "$rc" -ne 0 -a "$rc" -ne 1; then
896 $_VPS axf | $_EGREP -e "^[^ \t]+[ \t]+$S_CONTEXT[ \t]+" >&4
897 killContext "$S_CONTEXT" 9
901 ) 4>$_is_tmpdir/procs &
903 echo "$!" >$_is_tmpdir/pid
904 eval "$3"=$_is_tmpdir
909 ## Usage: _waitForVWait <vserver> <fifo> <pid> <procs>
910 function _waitForVWait
915 declare -r procs=$(cat $4)
917 getFileArray status "$2"
922 'vwait' exited with error '$2' which indicates that vserver could not
927 A timeout occured while waiting for the vserver to finish and it was
928 killed by sending a SIGKILL signal. Please investigate the reasons
929 and/or increase the timeout in apps/vshelper/sync-timeout."
932 (TIMEOUT) warning $"\
933 A timeout occured while waiting for the vserver to finish and it will
934 be killed by sending a SIGKILL signal. The following process list
935 might be useful for finding out the reason of this behavior:
937 ----------------------------------------------------------------------
939 }----------------------------------------------------------------------"
942 (\?\?\?|*) warning $"\
943 internal error: 'vwait' exited with an unexpected status '$1'; I will
944 try to continue but be prepared for unexpected events."
951 ## Usage: waitForSync <vserver> [<vshelper-fifo>] [<vwait-statdir>]
956 local vwait_statdir=$3
959 if test -d "$vwait_statdir"; then
960 _waitForVWait "$cfgdir" "$vwait_statdir/fifo" "$( <$vwait_statdir/pid )" "$vwait_statdir/procs"
961 elif test -n "$_NEED_VSHELPER_SYNC"; then
962 $_VSHELPER_SYNC "$fifo" "$VSHELPER_SYNC_TIMEOUT" || \
964 A timeout or other error occured while waiting for the synchronization
965 signal from vserver '$VSERVER_NAME'.
966 The vserver will be killed nevertheless..."
967 elif test "${#INITCMD_STOP_SYNC[@]}" -ne 0; then
968 "${INITCMD_STOP_SYNC[@]}" || \
970 Stop-synchronization for vserver '$VSERVER_NAME' failed. The vserver
971 will be killed nevertheless..."
974 test -z "$OPTION_FORCE_SYNC" -a ! -e "$cfgdir"/sync ||
980 local vdir name flavor start i already_handled base
984 ## Usage: execScriptlets <vserver-cfgdir> <vserver-name> <script-flavor>
985 function execScriptlets
992 for base in "$vdir"/scripts "$__CONFDIR"/.defaults/scripts; do
993 local DONT_SKIP_DEFAULTS=
994 local already_handled=
996 for i in "$base/$flavor" "$base/$flavor.d"/*; do
997 isRegularFile "$i" || continue
998 test -r "$i" || continue
1002 test -x "$i" || start=_sourceWrap
1003 $start "$i" "$flavor" "$name"
1006 test -z "$already_handled" -o -n "$DONT_SKIP_DEFAULTS" || break
1011 function sanityCheck
1013 declare -r cfgdir=$1
1015 ! test -e "$cfgdir"/fstab.local ||
1017 WARNING: 'fstab' will *not* be executed in the network context of the
1018 vserver anymore. Therefore, 'fstab.local' has the same functionality
1019 and is obsoleted. When you need the old behaviour, put the mounts
1020 into 'fstab.remote'"
1022 ! test -e "$cfgdir"/hostname -a ! -L "$cfgdir"/hostname ||
1024 WARNING: The hostname is now configured in 'uts/nodename' but not in
1027 ! test -e "$cfgdir"/domainname -a ! -L "$cfgdir"/domainname ||
1029 WARNING: The domainname is now configured in 'uts/domainname' but not
1030 in 'domainname'." >&2
1034 for i in "$cfgdir"/interfaces/*/only_ip; do
1035 if test -e "$i"; then
1037 iface=${i##$cfgdir/interfaces/}
1038 iface=${iface%%/only_ip}
1040 WARNING: The 'only_ip' flag for interface '$iface' is deprecated; use
1045 test ! -d "$cfgdir"/dlimits -o -L "$cfgdir/cache" || \
1047 WARNING: There is no cachedirectory configured for this vserver;
1048 please create '$cfgdir/cache' e.g. by executing
1050 ln -s ../.defaults/cachebase/$VSERVER_NAME $cfgdir/cache
1053 find "$cfgdir" -type f -exec "$_CHECK_UNIXFILE" '{}' ';'
1055 vshelper.doSanityCheck
1057 $_VSERVER_INFO - VERIFYCAP ||
1058 panic $"capabilities are not enabled in kernel-setup"
1060 $_VSERVER_INFO - VERIFYPROC ||
1062 /proc/uptime can not be accessed. Usually, this is caused by
1063 procfs-security. Please read the FAQ for more details
1064 http://linux-vserver.org/Proc-Security"
1068 function _setSingleDiskLimit
1080 getFileValue ctx "$vdir/context"
1081 getFileValue directory "$dlimit/directory" || return 0
1082 getFileValue space_total "$dlimit/space_total" || return 0
1083 getFileValue inodes_total "$dlimit/inodes_total" || return 0
1084 getFileValue reserved "$dlimit/reserved" || return 0
1086 local cachename=$ctx$directory
1087 cachename=dlimits/${cachename//\//_}
1089 test -e "$vdir/cache/$cachename" && . "$vdir/cache/$cachename"
1090 # Remove the cache so if the machine goes down unexpectedly, we won't have a stale cache
1091 $_RM -f "$vdir/cache/$cachename"
1093 if test -z "$inodes_used" -o -z "$space_used"; then
1095 tmpvdu=`$_VDU --xid $ctx --space --inodes --script "$directory"`
1096 inodes_used=${tmpvdu##* }
1097 space_used=${tmpvdu%% *}
1100 $_VDLIMIT --xid $ctx \
1101 --set space_used=$space_used \
1102 --set space_total=$space_total \
1103 --set inodes_used=$inodes_used \
1104 --set inodes_total=$inodes_total \
1105 --set reserved=$reserved \
1110 function setDiskLimits
1115 # Disk Limits without a static context are useless
1116 test -e "$vdir"/context || return 0
1118 for dlimit in "$vdir/dlimits/"*; do
1119 test -d "$dlimit" || continue
1120 test ! -e "$dlimit/disabled" || continue
1122 _setSingleDiskLimit "$vdir" "$dlimit"
1127 function _saveSingleDiskLimit
1134 getFileValue ctx "$vdir/context"
1135 getFileValue directory "$dlimit/directory" || return 0
1137 local cachename=$ctx$directory
1138 cachename=${cachename//\//_}
1140 # Things are getting ugly here... LFS says that /var/cache (where
1141 # cachename is usually pointing to) can vanish and applications
1142 # have to deal with it. So, we have to interprete the $vdir/cache
1143 # symlink and have to create the needed directories manually.
1144 if test -d "$vdir/cache"; then
1145 : # ok, exists already
1146 elif test -L "$vdir/cache"; then
1147 # it's a dangling symlink
1149 link=$($_READLINK "$vdir/cache")
1150 ( cd $vdir && $_MKDIR -p "$link" )
1155 test -d "$vdir/cache"
1156 $_MKDIR -p "$vdir"/cache/dlimits
1158 $_VDLIMIT --xid $ctx "$directory" | \
1159 $_GREP '_used=' > "$vdir/cache/dlimits/$cachename"
1161 $_VDLIMIT --xid $ctx --remove "$directory"
1165 function saveDiskLimits
1170 test -e "$vdir"/context || return 0
1172 for dlimit in "$vdir/dlimits/"*; do
1173 test -d "$dlimit" || continue
1174 test ! -e "$dlimit/disabled" || continue
1176 _saveSingleDiskLimit "$vdir" "$dlimit"
1180 function _namespaceCleanup
1183 local root=$($_VSERVER_INFO "$1" VDIR 1)
1188 getFileArray skip "$vdir"/namespace-cleanup-skip \
1189 "$__CONFDIR"/.defaults/namespace-cleanup-skip || :
1191 # these are things that have to be accessible post-cleanup
1192 for tmp in "$root" "$__SBINDIR" "$__PKGLIBDIR" "$vdir" \
1193 "$__PKGSTATEDIR" "$__LOCKDIR" /usr/local /tmp "${skip[@]}"; do
1194 while test -n "$tmp"; do
1195 list=( "${list[@]}" "$tmp" )
1200 local -a list_umount
1201 while read dev path opts; do
1202 test -n "$path" || continue
1203 for i in "$root" /dev /proc; do
1204 test "${path#$i}" != "$path" && continue 2
1206 for i in "${list[@]}" /; do
1207 test "$path" = "$i" && continue 2
1209 # unmount them in reverse order so mounts further down the tree get unmounted first
1210 list_umount=( "$path" "${list_umount[@]}" )
1212 # separate loop to avoid races while reading /proc/mounts
1213 for i in "${list_umount[@]}"; do
1218 function loadDeviceMap
1222 local flags device target
1224 test -d "$dir" || return 0
1226 for i in "$dir"/*; do
1227 test -d "$i" || continue
1229 local -a vdevmap_opts=()
1230 test -e "$i/create" && vdevmap_opts=( "${vdevmap_opts[@]}" --create )
1231 test -e "$i/open" && vdevmap_opts=( "${vdevmap_opts[@]}" --open )
1232 test -e "$i/remap" && vdevmap_opts=( "${vdevmap_opts[@]}" --remap )
1234 getFileValue flags "$i/flags" || :
1235 getFileValue device "$i/device" || :
1236 getFileValue target "$i/target" || :
1237 vdevmap_opts=( "${vdevmap_opts[@]}" ${flags:+--flags "$flags"} \
1238 ${device:+--device "$device"} ${target:+--target "$target"} )
1240 $_VDEVMAP --xid "$xid" "${vdevmap_opts[@]}" || return $?