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 panic "init-style '$INITSTYLE' is no longer supported; please use plain instead; aborting";;
305 (*) panic "Unknown init-style '$INITSTYLE'; aborting";;
308 if test x"$INITSTYLE" != xrescue; then
309 getFileArray INITCMD_START "$cfgdir"/cmd.start || :
310 getFileArray INITCMD_STOP "$cfgdir"/cmd.stop || :
311 getFileArray INITCMD_START_SYNC "$cfgdir"/cmd.start-sync || :
312 getFileArray INITCMD_STOP_SYNC "$cfgdir"/cmd.stop-sync || :
313 getFileArray INITCMD_PREPARE "$cfgdir"/cmd.prepare || :
316 test -n "$OPTION_FORCE_SYNC" -o -e "$cfgdir"/sync || {
317 INITCMD_START_SYNC=()
322 if vshelper.isEnabled; then
323 vshelper.getSyncTimeout "$vdir" VSHELPER_SYNC_TIMEOUT || :
329 function _generateFlagOptions
333 CHCONTEXT_FLAG_OPTS=()
335 test ! -e "$vdir"/flags || \
344 OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --flag "$flag" )
345 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}"
351 isAvoidNamespace "$vdir" || {
353 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}" --flag namespace )
357 function _generateChcontextOptions
360 local ctx hostname domainname
365 read ctx <"$vdir"/context || :
367 read hostname <"$vdir"/uts/nodename || read hostname <"$vdir"/hostname || :
368 read domainname <"$vdir"/uts/domainname || read domainname <"$vdir"/domainname || :
371 test -z "$S_CONTEXT" || ctx=$S_CONTEXT
373 _generateCapabilityOptions "$vdir"
374 _generateFlagOptions "$vdir"
376 CHCONTEXT_OPTS=( $SILENT_OPT \
377 "${CHCONTEXT_FLAG_OPTS[@]}" \
380 ${ctx:+--ctx "$ctx"} \
381 ${hostname:+--hostname "$hostname"} \
382 ${domainname:+--domainname "$domainname"} )
384 OPTS_VCONTEXT_CREATE=( $SILENT_OPT \
385 ${ctx:+--xid "$ctx"} )
386 ## put '--secure' at front so that it can be overridden
387 OPTS_VATTRIBUTE=( --secure --flag default "${OPTS_VATTRIBUTE[@]}" )
390 function _generateScheduleOptions
393 local f="$vdir"/schedule
394 test -e "$f" || return 0
396 local fill_rate interval tokens tokens_min tokens_max prio_bias
404 read prio_bias || prio_bias=
408 test -n "$prio_bias" || {
409 echo $"Bad content in '$f'; aborting..." >&2
413 OPTS_VSCHED=( --fill-rate "$fill_rate" --interval "$interval" \
414 --tokens "$tokens" --tokens_min "$tokens_min" \
415 --tokens_max "$tokens_max" --priority-bias "$prio_bias" )
418 function _getInterfaceValue
428 read _giv_tmp <"$_giv_i/$_giv_val" && break || :
431 : ${_giv_tmp:=$_giv_dflt}
432 eval $_giv_val=\$_giv_tmp
435 ## Usage: _transformMask2Prefix <result-varname> <prefix> <mask>
436 function _transformMask2Prefix
440 test -n "$_tm2p_tmp" || {
441 $_MASK2PREFIX "$3" || _tm2p_tmp=$?
448 function _addInterfaceCmd
450 eval INTERFACE_CMDS_${INTERFACE_CMDS_IDX}='( "$@" )'
451 let ++INTERFACE_CMDS_IDX
454 ## Usage: _generateMac <var> <iface> <ctx>
455 function _generateMac
458 echo $"Interface basename '$iface' must be either a number, or the mac must be configured explicitly" >&2
462 eval $1=$(printf "f0:ff:%02x:%02x:%02x:%02x" $[ (~($2>>8)) & 0xff ] $[ ($2 & 0xff) ] $[ ($3>>8) & 0xff ] $[ $3 & 0xff ])
465 function _getVLANInfo
470 creation of VLAN_PLUS_VID devices is not supported; please create them
471 before starting the vserver and use the 'nodev' flag then"
472 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID"
476 creation of VLAN_PLUS_VID_NO_PAD devices is not supported; please
477 create them before starting the vserver and use the 'nodev' flag then"
478 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID_N0_PAD"
480 (*.????) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID";;
481 (*.*) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID_NO_PAD";;
488 ## Usage: _processSingleInterface <interface-directory>
489 function _processSingleInterface
504 _getInterfaceValue ip '' "$iface"
505 _getInterfaceValue extip '' "$iface" "$iface/.."
506 _getInterfaceValue dev '' "$iface" "$iface/.."
507 _getInterfaceValue prefix '' "$iface" "$iface/.."
508 _getInterfaceValue mask '' "$iface" "$iface/.."
509 _getInterfaceValue bcast '' "$iface" "$iface/.."
510 _getInterfaceValue name '' "$iface"
511 _getInterfaceValue scope '' "$iface" "$iface/.."
512 _getInterfaceValue mac '' "$iface"
514 test -n "$ip" || { echo $"Can not read ip for '$iface'" >&2; return 1; }
515 test -n "$dev" -o -e "$iface"/nodev || {
516 echo $"No device specified for '$iface'" >&2
520 test ! -e "$iface"/down || up=
523 _transformMask2Prefix prefix "$prefix" "$mask"
524 INTERFACES=( "${INTERFACES[@]}" "$ip${prefix:+/$prefix}" )
526 test ! -e "$iface"/nodev || break
528 test ! -e "$iface"/only_ip || break
531 if vlan_info=$(_getVLANInfo "$dev"); then
532 test -d /proc/net/vlan || {
533 echo -e $"VLAN device-name used, but vlan subsystem not enabled.\nTry to execute 'modprobe 8021q' before starting the vservers" >&2
536 test -f /proc/net/vlan -o -e "$iface"/novlandev || {
537 _addInterfaceCmd VCONFIG $vlan_info
541 if ! test -e "$iface"/indirect; then
542 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" broadcast ${bcast:-+} ${name:+label "$dev:$name"} dev "$dev"
543 #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
544 _addInterfaceCmd IP_LINK "$dev" $up
545 elif ! test -n "$ctx"; then
546 echo $"Using 'dummy' (indirect) for interface '$dev' requires a fixed context number; dynamic ctx are not supported" >&2
549 test -z "$mac" || _generateMac mac "$(basename $iface)" "$ctx" || return 1
550 _addInterfaceCmd MODPROBE dummy "$dev"
551 _addInterfaceCmd IP_LINK dev dummy0 address "$mac"
552 _addInterfaceCmd NAMEIF "$dev" "$mac"
553 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" dev "$dev"
554 test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$ctx" "$extip"
561 ## Usage: _generateInterfaceOptions <vserver-directory>
562 function _generateInterfaceOptions
567 test ! -e "$1"/context || read ctx <"$1"/context
569 for iface in "$1/interfaces/"*; do
570 test -d "$iface" || continue
571 test ! -e "$iface"/disabled || continue
573 _processSingleInterface "$iface"
575 _HAVE_INTERFACE_OPTIONS=1
578 function enableInterfaces
583 lock "$__LOCKDIR"/vserver.interfaces
585 while test $i -lt $INTERFACE_CMDS_IDX; do
586 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
597 $_MODPROBE ${name:+-o "$name"} "$mod" "$@"
599 NAMEIF) $_NAMEIF "$@";;
600 VCONFIG) $_VCONFIG set_name_type "$4" >/dev/null
601 $_VCONFIG add "$2" "$3" >/dev/null;;
602 IP_ADDR) $_IP addr add "$@";;
603 IP_ADDR_FLUSH) $_IP addr flush "$@";;
604 IP_LINK) $_IP link set "$@";;
605 IP_ROUTE) $_IP route add "$@";;
606 *) echo "Unknown interface-command type '$type'" >&2; false;;
615 function disableInterfaces
617 test -n "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$1"
619 local i=$INTERFACE_CMDS_IDX
622 lock "$__LOCKDIR"/vserver.interfaces
624 while test $i -gt 0; do
627 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
634 MODPROBE) $_RMMOD "${2:-$1}";;
636 VCONFIG) $_VCONFIG rem "$2.$3" >/dev/null;;
637 IP_ADDR) $_IP addr del "$@";;
639 IP_LINK) ;; ## Ignore the link-down command for now
640 IP_ROUTE) $_IP route del "$@";;
641 *) echo "Unknown interface-command type '$type'" >&2; false;;
648 ## Usage: prepareInit <vserver-directory>
651 pushd "$1/vdir" >/dev/null
654 { find var/run ! -type d -print0; \
655 find var/lock ! -type d -print0; } | xargs -0r $_CHROOT_SH rm
658 $_CHROOT_SH rm .autofsck forcefsck 2>/dev/null || :
659 : | $_CHROOT_SH truncate fastboot 2>/dev/null || :
664 "${INITCMD_PREPARE[@]}"
668 ## Usage: prepareInit <vserver-directory>
671 pushd "$1/vdir" >/dev/null
674 export PREVLEVEL=$RUNLEVEL_START # required by Debian's initscripts
677 "${STOPCMD_PREPARE[@]}"
682 function generateOptions
684 _generateInterfaceOptions "$1"
685 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
686 _generateNiceCommand "$1"
687 _generateInitOptions "$1"
688 _generateChcontextOptions "$1"
689 _generateScheduleOptions "$1"
690 _generatePersonalityOptions "$1"
692 if test -n "$_IS_FAKEINIT"; then
693 CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
694 OPTS_VCONTEXT_MIGRATE=( "${OPTS_VCONTEXT_MIGRATE[@]}" --initpid --disconnect )
702 local f="$vdir"/cpuset
706 test -d "$f" || return 0
707 test -e "$f"/name || return 0
709 read cpuset < "$f"/name
710 test -e "$f"/nocreate || {
711 test -d /dev/cpuset/"$cpuset" || mkdir /dev/cpuset/"$cpuset" || configured=1
712 for i in cpus mems cpu_exclusive mem_exclusive virtualized; do
713 if test -e "$f"/"$i"; then
714 cat "$f"/"$i" >/dev/cpuset/"$cpuset"/"$i" 2>/dev/null || {
722 echo $$ >/dev/cpuset/"$cpuset"/tasks || configured=1
723 if [ "$configured" -ne 0 ]; then
725 WARNING: Failed to create or CPUSET \"$cpuset\" does not exist! Not using it!" >&2
726 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
731 function removeCPUSET
735 local f="$vdir"/cpuset
737 test -d "$f" || return 0
738 test -e "$f"/name || return 0
740 read cpuset < "$f"/name
741 test -e "$f"/nocreate || {
742 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
746 function _mountVserverInternal
751 test -e "$fstab" || return 0
754 pushd "$vdir" >/dev/null
755 # check whether / is mounted readonly or whether there is special
756 # magic regarding the mtab file; when etc/mtab can not be touched,
757 # add the '-n' flag to mount
758 test -w etc -o -w etc/mtab || xflag=-n
759 "$@" $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs no
767 local fstab="$cfgdir"/fstab
770 test -e "$fstab" || return 0
771 pushd "$vdir" >/dev/null
772 # check whether / is mounted readonly or whether there is special
773 # magic regarding the mtab file; when etc/mtab can not be touched,
774 # add the '-n' flag to mount
775 test -w etc -o -w etc/mtab || xflag=-n
776 $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs only -n
780 function mountVserver
787 test -e "$cfgdir"/fstab -o \
788 -e "$cfgdir"/fstab.local -o \
789 -e "$cfgdir"/fstab.remote || return 0
791 findObject -r mtab_src "$cfgdir"/apps/init/mtab "$__CONFDIR"/.defaults/init/mtab "$__PKGLIBDEFAULTDIR"/mtab /dev/null
793 pushd "$vdir" >/dev/null
794 $_CHROOT_SH truncate /etc/mtab <"$mtab_src"
797 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
799 _mountVserverInternal "$cfgdir"/fstab
800 _mountVserverInternal "$cfgdir"/fstab.local
801 _mountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}"
803 isNamespaceCleanup "$cfgdir" && \
806 isAvoidNamespace "$cfgdir" || \
807 $_SECURE_MOUNT --rbind -n "$vdir" "/"
810 function _umountVserverInternal
813 test -e "$fstab" || return 0
818 while read src dst tmp; do
819 test -n "$tmp" || continue
825 "$@" $_EXEC_CD "$dst" $_UMOUNT -lfn . || is_ok=
831 function umountVserver
837 isAvoidNamespace "$cfgdir" || return 0
838 test -e "$cfgdir"/fstab -o \
839 -e "$cfgdir"/fstab.local -o \
840 -e "$cfgdir"/fstab.remote || return 0
841 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
843 pushd "$vdir/" >/dev/null || return 1
844 _umountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}" || is_ok=
845 _umountVserverInternal "$cfgdir"/fstab.local || is_ok=
846 _umountVserverInternal "$cfgdir"/fstab || is_ok=
847 popd >/dev/null || return 1
852 ## Usage: waitForSync <vserver> <context> <vshelper-fifo-varname>
856 test -n "$_NEED_VSHELPER_SYNC" && \
857 ! $_VSERVER_INFO - FEATURE vwait || _is_meth=async
859 vshelper.initSync "$1" "$3" "$_is_meth"
862 ## Usage: initWait <vserver> <context> <vwait-tmpdir-varname>
865 if $_VSERVER_INFO - FEATURE vwait; then
867 _is_tmpdir=$($_MKTEMPDIR vwaitstat.XXXXXX)
870 $_VWAIT --timeout "$VSHELPER_SYNC_TIMEOUT" \
872 >>$_is_tmpdir/out 2>$_is_tmpdir/err 3>$_is_tmpdir/fifo
875 if test "$rc" -ne 0 -a "$rc" -ne 1; then
876 $_VPS axf | $_EGREP -e "^[^ \t]+[ \t]+$S_CONTEXT[ \t]+" >&4
877 killContext "$S_CONTEXT" 9
881 ) 4>$_is_tmpdir/procs &
883 echo "$!" >$_is_tmpdir/pid
884 eval "$3"=$_is_tmpdir
889 ## Usage: _waitForVWait <vserver> <fifo> <pid> <procs>
890 function _waitForVWait
895 declare -r procs=$(cat $4)
897 getFileArray status "$2"
902 'vwait' exited with error '$2' which indicates that vserver could not
907 A timeout occured while waiting for the vserver to finish and it was
908 killed by sending a SIGKILL signal. Please investigate the reasons
909 and/or increase the timeout in apps/vshelper/sync-timeout."
912 (TIMEOUT) warning $"\
913 A timeout occured while waiting for the vserver to finish and it will
914 be killed by sending a SIGKILL signal. The following process list
915 might be useful for finding out the reason of this behavior:
917 ----------------------------------------------------------------------
919 }----------------------------------------------------------------------"
922 (\?\?\?|*) warning $"\
923 internal error: 'vwait' exited with an unexpected status '$1'; I will
924 try to continue but be prepared for unexpected events."
931 ## Usage: waitForSync <vserver> [<vshelper-fifo>] [<vwait-statdir>]
936 local vwait_statdir=$3
939 if test -d "$vwait_statdir"; then
940 _waitForVWait "$cfgdir" "$vwait_statdir/fifo" "$( <$vwait_statdir/pid )" "$vwait_statdir/procs"
941 elif test -n "$_NEED_VSHELPER_SYNC"; then
942 $_VSHELPER_SYNC "$fifo" "$VSHELPER_SYNC_TIMEOUT" || \
944 A timeout or other error occured while waiting for the synchronization
945 signal from vserver '$VSERVER_NAME'.
946 The vserver will be killed nevertheless..."
947 elif test "${#INITCMD_STOP_SYNC[@]}" -ne 0; then
948 "${INITCMD_STOP_SYNC[@]}" || \
950 Stop-synchronization for vserver '$VSERVER_NAME' failed. The vserver
951 will be killed nevertheless..."
954 test -z "$OPTION_FORCE_SYNC" -a ! -e "$cfgdir"/sync ||
960 local vdir name flavor start i already_handled base
964 ## Usage: execScriptlets <vserver-cfgdir> <vserver-name> <script-flavor>
965 function execScriptlets
972 for base in "$vdir"/scripts "$__CONFDIR"/.defaults/scripts; do
973 local DONT_SKIP_DEFAULTS=
974 local already_handled=
976 for i in "$base/$flavor" "$base/$flavor.d"/*; do
977 isRegularFile "$i" || continue
978 test -r "$i" || continue
982 test -x "$i" || start=_sourceWrap
983 $start "$i" "$flavor" "$name"
986 test -z "$already_handled" -o -n "$DONT_SKIP_DEFAULTS" || break
995 ! test -e "$cfgdir"/fstab.local ||
997 WARNING: 'fstab' will *not* be executed in the network context of the
998 vserver anymore. Therefore, 'fstab.local' has the same functionality
999 and is obsoleted. When you need the old behaviour, put the mounts
1000 into 'fstab.remote'"
1002 ! test -e "$cfgdir"/hostname -a ! -L "$cfgdir"/hostname ||
1004 WARNING: The hostname is now configured in 'uts/nodename' but not in
1007 ! test -e "$cfgdir"/domainname -a ! -L "$cfgdir"/domainname ||
1009 WARNING: The domainname is now configured in 'uts/domainname' but not
1010 in 'domainname'." >&2
1014 for i in "$cfgdir"/interfaces/*/only_ip; do
1015 if test -e "$i"; then
1017 iface=${i##$cfgdir/interfaces/}
1018 iface=${iface%%/only_ip}
1020 WARNING: The 'only_ip' flag for interface '$iface' is deprecated; use
1025 test ! -d "$cfgdir"/dlimits -o -L "$cfgdir/cache" || \
1027 WARNING: There is no cachedirectory configured for this vserver;
1028 please create '$cfgdir/cache' e.g. by executing
1030 ln -s ../.defaults/cachebase/$VSERVER_NAME $cfgdir/cache
1033 find "$cfgdir" -type f -exec "$_CHECK_UNIXFILE" '{}' ';'
1035 vshelper.doSanityCheck
1037 $_VSERVER_INFO - VERIFYCAP ||
1038 panic $"capabilities are not enabled in kernel-setup"
1040 $_VSERVER_INFO - VERIFYPROC ||
1042 /proc/uptime can not be accessed. Usually, this is caused by
1043 procfs-security. Please read the FAQ for more details
1044 http://www.linux-vserver.org/index.php?page=Linux-Vserver+FAQ"
1048 function _setSingleDiskLimit
1060 getFileValue ctx "$vdir/context"
1061 getFileValue directory "$dlimit/directory" || return 0
1062 getFileValue space_total "$dlimit/space_total" || return 0
1063 getFileValue inodes_total "$dlimit/inodes_total" || return 0
1064 getFileValue reserved "$dlimit/reserved" || return 0
1066 local cachename=$ctx$directory
1067 cachename=dlimits/${cachename//\//_}
1069 test -e "$vdir/cache/$cachename" && . "$vdir/cache/$cachename"
1070 # Remove the cache so if the machine goes down unexpectedly, we won't have a stale cache
1071 $_RM -f "$vdir/cache/$cachename"
1073 if test -z "$inodes_used" -o -z "$space_used"; then
1075 tmpvdu=`$_VDU --xid $ctx --space --inodes --script "$directory"`
1076 inodes_used=${tmpvdu##* }
1077 space_used=${tmpvdu%% *}
1080 $_VDLIMIT --xid $ctx \
1081 --set space_used=$space_used \
1082 --set space_total=$space_total \
1083 --set inodes_used=$inodes_used \
1084 --set inodes_total=$inodes_total \
1085 --set reserved=$reserved \
1090 function setDiskLimits
1095 # Disk Limits without a static context are useless
1096 test -e "$vdir"/context || return 0
1098 for dlimit in "$vdir/dlimits/"*; do
1099 test -d "$dlimit" || continue
1100 test ! -e "$dlimit/disabled" || continue
1102 _setSingleDiskLimit "$vdir" "$dlimit"
1107 function _saveSingleDiskLimit
1114 getFileValue ctx "$vdir/context"
1115 getFileValue directory "$dlimit/directory" || return 0
1117 local cachename=$ctx$directory
1118 cachename=${cachename//\//_}
1120 # Things are getting ugly here... LFS says that /var/cache (where
1121 # cachename is usually pointing to) can vanish and applications
1122 # have to deal with it. So, we have to interprete the $vdir/cache
1123 # symlink and have to create the needed directories manually.
1124 if test -d "$vdir/cache"; then
1125 : # ok, exists already
1126 elif test -L "$vdir/cache"; then
1127 # it's a dangling symlink
1129 link=$($_READLINK "$vdir/cache")
1130 ( cd $vdir && $_MKDIR -p "$link" )
1135 test -d "$vdir/cache"
1136 $_MKDIR -p "$vdir"/cache/dlimits
1138 $_VDLIMIT --xid $ctx "$directory" | \
1139 $_GREP '_used=' > "$vdir/cache/dlimits/$cachename"
1143 function saveDiskLimits
1148 test -e "$vdir"/context || return 0
1150 for dlimit in "$vdir/dlimits/"*; do
1151 test -d "$dlimit" || continue
1152 test ! -e "$dlimit/disabled" || continue
1154 _saveSingleDiskLimit "$vdir" "$dlimit"
1158 function _namespaceCleanup
1160 local root=$(readlink -f "$vdir")
1163 while [ "$tmp" ]; do
1164 list=( "${list[@]}" "$tmp" )
1167 local -a list_umount
1168 while read dev path opts; do
1169 [ "$path" ] || continue
1170 for i in "$root" /dev /proc; do
1171 [ "${path#$i}" != "$path" ] && continue 2
1173 for i in "${list[@]}" /; do
1174 [ "$path" = "$i" ] && continue 2
1176 list_umount=( "${list_umount[@]}" "$path" )
1178 for i in "${list_umount[@]}"; do