1 # $Id: vserver.functions 2538 2007-04-27 09:08:43Z hollow $ --*- sh -*--
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 )
284 INITCMD_START=( /sbin/init )
285 INITCMD_STOP=( /sbin/init )
287 _NEED_VSHELPER_SYNC=1
288 test -z "$RUNLEVEL_START" || INITCMD_START=( "${INITCMD_START[@]}" "$RUNLEVEL_START" )
289 test -z "$RUNLEVEL_STOP" || INITCMD_STOP=( "${INITCMD_STOP[@]}" "$RUNLEVEL_STOP" )
293 INITCMD_START=( /sbin/minit-start )
294 INITCMD_STOP=( /sbin/minit-stop )
296 INITCMD_START_SYNC=( "$_INITSYNC_MINIT_START" "$vdir" )
297 _NEED_VSHELPER_SYNC=1
298 test -z "$RUNLEVEL_START" || INITCMD_START=( "${INITCMD_START[@]}" "$RUNLEVEL_START" )
299 test -z "$RUNLEVEL_STOP" || INITCMD_STOP=( "${INITCMD_STOP[@]}" "$RUNLEVEL_STOP" )
300 ! isNumber "${RUNLEVEL_START:-3}" || INITCMD_PREPARE=( $_FAKE_RUNLEVEL "${RUNLEVEL_START:-3}" /var/run/utmp )
304 test -n "$RUNLEVEL_START" || RUNLEVEL_START="default"
306 INITCMD_START=( /lib/rcscripts/sh/init-vserver.sh "$RUNLEVEL_START" )
307 INITCMD_STOP=( env -i RUNLEVEL=0 /sbin/rc shutdown )
308 INITCMD_PREPARE=( $_FAKE_RUNLEVEL 3 /var/run/utmp )
312 (*) panic "Unknown init-style '$INITSTYLE'; aborting";;
315 if test x"$INITSTYLE" != xrescue; then
316 getFileArray INITCMD_START "$cfgdir"/cmd.start || :
317 getFileArray INITCMD_STOP "$cfgdir"/cmd.stop || :
318 getFileArray INITCMD_START_SYNC "$cfgdir"/cmd.start-sync || :
319 getFileArray INITCMD_STOP_SYNC "$cfgdir"/cmd.stop-sync || :
320 getFileArray INITCMD_PREPARE "$cfgdir"/cmd.prepare || :
323 test -n "$OPTION_FORCE_SYNC" -o -e "$cfgdir"/sync || {
324 INITCMD_START_SYNC=()
329 if vshelper.isEnabled; then
330 vshelper.getSyncTimeout "$vdir" VSHELPER_SYNC_TIMEOUT || :
336 function _generateFlagOptions
340 CHCONTEXT_FLAG_OPTS=()
342 test ! -e "$vdir"/flags || \
351 OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --flag "$flag" )
352 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}"
358 isAvoidNamespace "$vdir" || {
360 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}" --flag namespace )
364 function _generateChcontextOptions
367 local ctx hostname domainname
372 read ctx <"$vdir"/context || :
374 read hostname <"$vdir"/uts/nodename || read hostname <"$vdir"/hostname || :
375 read domainname <"$vdir"/uts/domainname || read domainname <"$vdir"/domainname || :
378 test -z "$S_CONTEXT" || ctx=$S_CONTEXT
380 _generateCapabilityOptions "$vdir"
381 _generateFlagOptions "$vdir"
383 CHCONTEXT_OPTS=( $SILENT_OPT \
384 "${CHCONTEXT_FLAG_OPTS[@]}" \
387 ${ctx:+--ctx "$ctx"} \
388 ${hostname:+--hostname "$hostname"} \
389 ${domainname:+--domainname "$domainname"} )
391 OPTS_VCONTEXT_CREATE=( $SILENT_OPT \
392 ${ctx:+--xid "$ctx"} )
393 ## put '--secure' at front so that it can be overridden
394 OPTS_VATTRIBUTE=( --secure --flag default "${OPTS_VATTRIBUTE[@]}" )
397 function _generateScheduleOptions
400 if test -d "$vdir"/sched; then
401 OPTS_VSCHED=( --dir "$vdir"/sched --missingok )
405 local f="$vdir"/schedule
406 test -e "$f" || return 0
408 local fill_rate interval tokens tokens_min tokens_max prio_bias
416 read prio_bias || prio_bias=
420 test -n "$prio_bias" || {
421 echo $"Bad content in '$f'; aborting..." >&2
425 OPTS_VSCHED=( --fill-rate "$fill_rate" --interval "$interval" \
426 --tokens "$tokens" --tokens_min "$tokens_min" \
427 --tokens_max "$tokens_max" --priority-bias "$prio_bias" )
430 function _getInterfaceValue
440 read _giv_tmp <"$_giv_i/$_giv_val" && break || :
443 : ${_giv_tmp:=$_giv_dflt}
444 eval $_giv_val=\$_giv_tmp
447 ## Usage: _transformMask2Prefix <result-varname> <prefix> <mask>
448 function _transformMask2Prefix
452 test -n "$_tm2p_tmp" || {
453 $_MASK2PREFIX "$3" || _tm2p_tmp=$?
460 function _addInterfaceCmd
462 eval INTERFACE_CMDS_${INTERFACE_CMDS_IDX}='( "$@" )'
463 let ++INTERFACE_CMDS_IDX
466 ## Usage: _generateMac <var> <iface> <ctx>
467 function _generateMac
470 echo $"Interface basename '$iface' must be either a number, or the mac must be configured explicitly" >&2
474 eval $1=$(printf "f0:ff:%02x:%02x:%02x:%02x" $[ (~($2>>8)) & 0xff ] $[ ($2 & 0xff) ] $[ ($3>>8) & 0xff ] $[ $3 & 0xff ])
477 function _getVLANInfo
482 creation of VLAN_PLUS_VID devices is not supported; please create them
483 before starting the vserver and use the 'nodev' flag then"
484 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID"
488 creation of VLAN_PLUS_VID_NO_PAD devices is not supported; please
489 create them before starting the vserver and use the 'nodev' flag then"
490 echo "$1 vlan ${1##vlan} VLAN_PLUS_VID_N0_PAD"
492 (*.????) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID";;
493 (*.*) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID_NO_PAD";;
500 ## Usage: _processSingleInterface <interface-directory>
501 function _processSingleInterface
516 _getInterfaceValue ip '' "$iface"
517 _getInterfaceValue extip '' "$iface" "$iface/.."
518 _getInterfaceValue dev '' "$iface" "$iface/.."
519 _getInterfaceValue prefix '' "$iface" "$iface/.."
520 _getInterfaceValue mask '' "$iface" "$iface/.."
521 _getInterfaceValue bcast '' "$iface" "$iface/.."
522 _getInterfaceValue name '' "$iface"
523 _getInterfaceValue scope '' "$iface" "$iface/.."
524 _getInterfaceValue mac '' "$iface"
526 test -n "$ip" || { echo $"Can not read ip for '$iface'" >&2; return 1; }
527 test -n "$dev" -o -e "$iface"/nodev || {
528 echo $"No device specified for '$iface'" >&2
532 test ! -e "$iface"/down || up=
535 _transformMask2Prefix prefix "$prefix" "$mask"
536 INTERFACES=( "${INTERFACES[@]}" "$ip${prefix:+/$prefix}" )
538 test ! -e "$iface"/nodev || break
540 test ! -e "$iface"/only_ip || break
542 test -e "$iface/vlandev" \
543 -o \( -e "$iface/../vlandev" -a ! -e "$iface/novlandev" \) \
544 -o \( -e "$__CONFDIR/.defaults/interfaces/vlandev" \
545 -a ! -e "$iface/novlandev" \
546 -a ! -e "$iface/../novlandev" \) && {
548 if vlan_info=$(_getVLANInfo "$dev"); then
549 test -d /proc/net/vlan || {
550 echo -e $"VLAN device-name used, but vlan subsystem not enabled.\nTry to execute 'modprobe 8021q' before starting the vservers" >&2
553 _addInterfaceCmd VCONFIG $vlan_info
557 if ! test -e "$iface"/indirect; then
559 use_bcast="broadcast ${bcast:-+}"
560 echo "$ip" | $_GREP -q : && use_bcast=
561 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" $use_bcast ${name:+label "$dev:$name"} dev "$dev"
562 #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
563 _addInterfaceCmd IP_LINK "$dev" $up
564 elif ! test -n "$ctx"; then
565 echo $"Using 'dummy' (indirect) for interface '$dev' requires a fixed context number; dynamic ctx are not supported" >&2
568 test -z "$mac" || _generateMac mac "$(basename $iface)" "$ctx" || return 1
569 _addInterfaceCmd MODPROBE dummy "$dev"
570 _addInterfaceCmd IP_LINK dev dummy0 address "$mac"
571 _addInterfaceCmd NAMEIF "$dev" "$mac"
572 _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" dev "$dev"
573 test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$ctx" "$extip"
580 ## Usage: _generateInterfaceOptions <vserver-directory>
581 function _generateInterfaceOptions
586 test ! -e "$1"/context || read ctx <"$1"/context
588 for iface in "$1/interfaces/"*; do
589 test -d "$iface" || continue
590 test ! -e "$iface"/disabled || continue
592 _processSingleInterface "$iface"
594 _HAVE_INTERFACE_OPTIONS=1
597 function enableInterfaces
602 lock "$__LOCKDIR"/vserver.interfaces
604 while test $i -lt $INTERFACE_CMDS_IDX; do
605 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
616 $_MODPROBE ${name:+-o "$name"} "$mod" "$@"
618 NAMEIF) $_NAMEIF "$@";;
619 VCONFIG) $_VCONFIG set_name_type "$4" >/dev/null
620 $_VCONFIG add "$2" "$3" >/dev/null;;
621 IP_ADDR) $_IP addr add "$@";;
622 IP_ADDR_FLUSH) $_IP addr flush "$@";;
623 IP_LINK) $_IP link set "$@";;
624 IP_ROUTE) $_IP route add "$@";;
625 *) echo "Unknown interface-command type '$type'" >&2; false;;
634 function disableInterfaces
636 test -n "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$1"
638 local i=$INTERFACE_CMDS_IDX
641 lock "$__LOCKDIR"/vserver.interfaces
643 while test $i -gt 0; do
646 eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
653 MODPROBE) $_RMMOD "${2:-$1}";;
655 VCONFIG) $_VCONFIG rem "$2.$3" >/dev/null;;
656 IP_ADDR) $_IP addr del "$@";;
658 IP_LINK) ;; ## Ignore the link-down command for now
659 IP_ROUTE) $_IP route del "$@";;
660 *) echo "Unknown interface-command type '$type'" >&2; false;;
667 ## Usage: prepareInit <vserver-directory>
670 pushd "$1/vdir" >/dev/null
673 { find var/run ! -type d -print0; \
674 find var/lock ! -type d -print0; } | xargs -0r $_CHROOT_SH rm
677 $_CHROOT_SH rm .autofsck forcefsck 2>/dev/null || :
678 : | $_CHROOT_SH truncate fastboot 2>/dev/null || :
683 "${INITCMD_PREPARE[@]}"
687 ## Usage: prepareInit <vserver-directory>
690 pushd "$1/vdir" >/dev/null
693 export PREVLEVEL=$RUNLEVEL_START # required by Debian's initscripts
696 "${STOPCMD_PREPARE[@]}"
701 function generateOptions
703 _generateInterfaceOptions "$1"
704 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
705 _generateNiceCommand "$1"
706 _generateInitOptions "$1"
707 _generateChcontextOptions "$1"
708 _generateScheduleOptions "$1"
709 _generatePersonalityOptions "$1"
711 if test -n "$_IS_FAKEINIT"; then
712 CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
713 OPTS_VCONTEXT_MIGRATE=( "${OPTS_VCONTEXT_MIGRATE[@]}" --initpid --disconnect )
721 local f="$vdir"/cpuset
725 test -d "$f" || return 0
726 test -e "$f"/name || return 0
728 read cpuset < "$f"/name
729 test -e "$f"/nocreate || {
730 test -d /dev/cpuset/"$cpuset" || mkdir /dev/cpuset/"$cpuset" || configured=1
731 for i in cpus mems cpu_exclusive mem_exclusive virtualized; do
732 if test -e "$f"/"$i"; then
733 cat "$f"/"$i" >/dev/cpuset/"$cpuset"/"$i" || {
741 echo $$ >/dev/cpuset/"$cpuset"/tasks || configured=1
742 if [ "$configured" -ne 0 ]; then
744 WARNING: Failed to create or CPUSET \"$cpuset\" does not exist! Not using it!" >&2
745 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
750 function removeCPUSET
754 local f="$vdir"/cpuset
756 test -d "$f" || return 0
757 test -e "$f"/name || return 0
759 read cpuset < "$f"/name
760 test -e "$f"/nocreate || {
761 rmdir /dev/cpuset/"$cpuset" 2>/dev/null || :
765 function _mountVserverInternal
770 test -e "$fstab" || return 0
773 pushd "$vdir" >/dev/null
774 # check whether / is mounted readonly or whether there is special
775 # magic regarding the mtab file; when etc/mtab can not be touched,
776 # add the '-n' flag to mount
777 test -w etc -o -w etc/mtab || xflag=-n
778 "$@" $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs no
786 local fstab="$cfgdir"/fstab
789 test -e "$fstab" || return 0
790 pushd "$vdir" >/dev/null
791 # check whether / is mounted readonly or whether there is special
792 # magic regarding the mtab file; when etc/mtab can not be touched,
793 # add the '-n' flag to mount
794 test -w etc -o -w etc/mtab || xflag=-n
795 $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs only -n
799 function mountVserver
806 test -e "$cfgdir"/fstab -o \
807 -e "$cfgdir"/fstab.local -o \
808 -e "$cfgdir"/fstab.remote || return 0
810 findObject -r mtab_src "$cfgdir"/apps/init/mtab "$__CONFDIR"/.defaults/init/mtab "$__PKGLIBDEFAULTDIR"/mtab /dev/null
812 pushd "$vdir" >/dev/null
813 $_CHROOT_SH truncate /etc/mtab <"$mtab_src"
816 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
818 _mountVserverInternal "$cfgdir"/fstab
819 _mountVserverInternal "$cfgdir"/fstab.local
820 _mountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}"
822 isNamespaceCleanup "$cfgdir" && \
823 _namespaceCleanup "$cfgdir"
825 isAvoidNamespace "$cfgdir" || \
826 $_SECURE_MOUNT --rbind -n "$vdir" "/"
829 function _umountVserverInternal
832 test -e "$fstab" || return 0
837 while read src dst tmp; do
838 test -n "$tmp" || continue
844 "$@" $_EXEC_CD "$dst" $_UMOUNT -lfn . || is_ok=
850 function umountVserver
856 isAvoidNamespace "$cfgdir" || return 0
857 test -e "$cfgdir"/fstab -o \
858 -e "$cfgdir"/fstab.local -o \
859 -e "$cfgdir"/fstab.remote || return 0
860 test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
862 pushd "$vdir/" >/dev/null || return 1
863 _umountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}" || is_ok=
864 _umountVserverInternal "$cfgdir"/fstab.local || is_ok=
865 _umountVserverInternal "$cfgdir"/fstab || is_ok=
866 popd >/dev/null || return 1
871 ## Usage: waitForSync <vserver> <context> <vshelper-fifo-varname>
875 test -n "$_NEED_VSHELPER_SYNC" && \
876 ! $_VSERVER_INFO - FEATURE vwait || _is_meth=async
878 vshelper.initSync "$1" "$3" "$_is_meth"
881 ## Usage: initWait <vserver> <context> <vwait-tmpdir-varname>
884 if $_VSERVER_INFO - FEATURE vwait; then
886 _is_tmpdir=$($_MKTEMPDIR vwaitstat.XXXXXX)
889 $_VWAIT --timeout "$VSHELPER_SYNC_TIMEOUT" \
891 >>$_is_tmpdir/out 2>$_is_tmpdir/err 3>$_is_tmpdir/fifo
894 if test "$rc" -ne 0 -a "$rc" -ne 1; then
895 $_VPS axf | $_EGREP -e "^[^ \t]+[ \t]+$S_CONTEXT[ \t]+" >&4
896 killContext "$S_CONTEXT" 9
900 ) 4>$_is_tmpdir/procs &
902 echo "$!" >$_is_tmpdir/pid
903 eval "$3"=$_is_tmpdir
908 ## Usage: _waitForVWait <vserver> <fifo> <pid> <procs>
909 function _waitForVWait
914 declare -r procs=$(cat $4)
916 getFileArray status "$2"
921 'vwait' exited with error '$2' which indicates that vserver could not
926 A timeout occured while waiting for the vserver to finish and it was
927 killed by sending a SIGKILL signal. Please investigate the reasons
928 and/or increase the timeout in apps/vshelper/sync-timeout."
931 (TIMEOUT) warning $"\
932 A timeout occured while waiting for the vserver to finish and it will
933 be killed by sending a SIGKILL signal. The following process list
934 might be useful for finding out the reason of this behavior:
936 ----------------------------------------------------------------------
938 }----------------------------------------------------------------------"
941 (\?\?\?|*) warning $"\
942 internal error: 'vwait' exited with an unexpected status '$1'; I will
943 try to continue but be prepared for unexpected events."
950 ## Usage: waitForSync <vserver> [<vshelper-fifo>] [<vwait-statdir>]
955 local vwait_statdir=$3
958 if test -d "$vwait_statdir"; then
959 _waitForVWait "$cfgdir" "$vwait_statdir/fifo" "$( <$vwait_statdir/pid )" "$vwait_statdir/procs"
960 elif test -n "$_NEED_VSHELPER_SYNC"; then
961 $_VSHELPER_SYNC "$fifo" "$VSHELPER_SYNC_TIMEOUT" || \
963 A timeout or other error occured while waiting for the synchronization
964 signal from vserver '$VSERVER_NAME'.
965 The vserver will be killed nevertheless..."
966 elif test "${#INITCMD_STOP_SYNC[@]}" -ne 0; then
967 "${INITCMD_STOP_SYNC[@]}" || \
969 Stop-synchronization for vserver '$VSERVER_NAME' failed. The vserver
970 will be killed nevertheless..."
973 test -z "$OPTION_FORCE_SYNC" -a ! -e "$cfgdir"/sync ||
979 local vdir name flavor start i already_handled base
983 ## Usage: execScriptlets <vserver-cfgdir> <vserver-name> <script-flavor>
984 function execScriptlets
991 for base in "$vdir"/scripts "$__CONFDIR"/.defaults/scripts; do
992 local DONT_SKIP_DEFAULTS=
993 local already_handled=
995 for i in "$base/$flavor" "$base/$flavor.d"/*; do
996 isRegularFile "$i" || continue
997 test -r "$i" || continue
1001 test -x "$i" || start=_sourceWrap
1002 $start "$i" "$flavor" "$name"
1005 test -z "$already_handled" -o -n "$DONT_SKIP_DEFAULTS" || break
1010 function sanityCheck
1012 declare -r cfgdir=$1
1014 ! test -e "$cfgdir"/fstab.local ||
1016 WARNING: 'fstab' will *not* be executed in the network context of the
1017 vserver anymore. Therefore, 'fstab.local' has the same functionality
1018 and is obsoleted. When you need the old behaviour, put the mounts
1019 into 'fstab.remote'"
1021 ! test -e "$cfgdir"/hostname -a ! -L "$cfgdir"/hostname ||
1023 WARNING: The hostname is now configured in 'uts/nodename' but not in
1026 ! test -e "$cfgdir"/domainname -a ! -L "$cfgdir"/domainname ||
1028 WARNING: The domainname is now configured in 'uts/domainname' but not
1029 in 'domainname'." >&2
1033 for i in "$cfgdir"/interfaces/*/only_ip; do
1034 if test -e "$i"; then
1036 iface=${i##$cfgdir/interfaces/}
1037 iface=${iface%%/only_ip}
1039 WARNING: The 'only_ip' flag for interface '$iface' is deprecated; use
1044 test ! -d "$cfgdir"/dlimits -o -L "$cfgdir/cache" || \
1046 WARNING: There is no cachedirectory configured for this vserver;
1047 please create '$cfgdir/cache' e.g. by executing
1049 ln -s ../.defaults/cachebase/$VSERVER_NAME $cfgdir/cache
1052 find "$cfgdir" -type f -exec "$_CHECK_UNIXFILE" '{}' ';'
1054 vshelper.doSanityCheck
1056 $_VSERVER_INFO - VERIFYCAP ||
1057 panic $"capabilities are not enabled in kernel-setup"
1059 $_VSERVER_INFO - VERIFYPROC ||
1061 /proc/uptime can not be accessed. Usually, this is caused by
1062 procfs-security. Please read the FAQ for more details
1063 http://linux-vserver.org/Proc-Security"
1067 function _setSingleDiskLimit
1079 getFileValue ctx "$vdir/context"
1080 getFileValue directory "$dlimit/directory" || return 0
1081 getFileValue space_total "$dlimit/space_total" || return 0
1082 getFileValue inodes_total "$dlimit/inodes_total" || return 0
1083 getFileValue reserved "$dlimit/reserved" || return 0
1085 local cachename=$ctx$directory
1086 cachename=dlimits/${cachename//\//_}
1088 test -e "$vdir/cache/$cachename" && . "$vdir/cache/$cachename"
1089 # Remove the cache so if the machine goes down unexpectedly, we won't have a stale cache
1090 $_RM -f "$vdir/cache/$cachename"
1092 if test -z "$inodes_used" -o -z "$space_used"; then
1094 tmpvdu=`$_VDU --xid $ctx --space --inodes --script "$directory"`
1095 inodes_used=${tmpvdu##* }
1096 space_used=${tmpvdu%% *}
1099 $_VDLIMIT --xid $ctx \
1100 --set space_used=$space_used \
1101 --set space_total=$space_total \
1102 --set inodes_used=$inodes_used \
1103 --set inodes_total=$inodes_total \
1104 --set reserved=$reserved \
1109 function setDiskLimits
1114 # Disk Limits without a static context are useless
1115 test -e "$vdir"/context || return 0
1117 for dlimit in "$vdir/dlimits/"*; do
1118 test -d "$dlimit" || continue
1119 test ! -e "$dlimit/disabled" || continue
1121 _setSingleDiskLimit "$vdir" "$dlimit"
1126 function _saveSingleDiskLimit
1133 getFileValue ctx "$vdir/context"
1134 getFileValue directory "$dlimit/directory" || return 0
1136 local cachename=$ctx$directory
1137 cachename=${cachename//\//_}
1139 # Things are getting ugly here... LFS says that /var/cache (where
1140 # cachename is usually pointing to) can vanish and applications
1141 # have to deal with it. So, we have to interprete the $vdir/cache
1142 # symlink and have to create the needed directories manually.
1143 if test -d "$vdir/cache"; then
1144 : # ok, exists already
1145 elif test -L "$vdir/cache"; then
1146 # it's a dangling symlink
1148 link=$($_READLINK "$vdir/cache")
1149 ( cd $vdir && $_MKDIR -p "$link" )
1154 test -d "$vdir/cache"
1155 $_MKDIR -p "$vdir"/cache/dlimits
1157 $_VDLIMIT --xid $ctx "$directory" | \
1158 $_GREP '_used=' > "$vdir/cache/dlimits/$cachename"
1160 $_VDLIMIT --xid $ctx --remove "$directory"
1164 function saveDiskLimits
1169 test -e "$vdir"/context || return 0
1171 for dlimit in "$vdir/dlimits/"*; do
1172 test -d "$dlimit" || continue
1173 test ! -e "$dlimit/disabled" || continue
1175 _saveSingleDiskLimit "$vdir" "$dlimit"
1179 function _namespaceCleanup
1182 local root=$($_VSERVER_INFO "$1" VDIR 1)
1187 getFileArray skip "$vdir"/namespace-cleanup-skip \
1188 "$__CONFDIR"/.defaults/namespace-cleanup-skip || :
1190 # these are things that have to be accessible post-cleanup
1191 for tmp in "$root" "$__SBINDIR" "$__PKGLIBDIR" "$vdir" \
1192 "$__PKGSTATEDIR" "$__LOCKDIR" /usr/local /tmp "${skip[@]}"; do
1193 while test -n "$tmp"; do
1194 list=( "${list[@]}" "$tmp" )
1199 local -a list_umount
1200 while read dev path opts; do
1201 test -n "$path" || continue
1202 for i in "$root" /dev /proc; do
1203 test "${path#$i}" != "$path" && continue 2
1205 for i in "${list[@]}" /; do
1206 test "$path" = "$i" && continue 2
1208 # unmount them in reverse order so mounts further down the tree get unmounted first
1209 list_umount=( "$path" "${list_umount[@]}" )
1211 # separate loop to avoid races while reading /proc/mounts
1212 for i in "${list_umount[@]}"; do
1217 function loadDeviceMap
1221 local flags device target
1223 test -d "$dir" || return 0
1225 for i in "$dir"/*; do
1226 test -d "$i" || continue
1228 local -a vdevmap_opts=()
1229 test -e "$i/create" && vdevmap_opts=( "${vdevmap_opts[@]}" --create )
1230 test -e "$i/open" && vdevmap_opts=( "${vdevmap_opts[@]}" --open )
1231 test -e "$i/remap" && vdevmap_opts=( "${vdevmap_opts[@]}" --remap )
1233 getFileValue flags "$i/flags" || :
1234 getFileValue device "$i/device" || :
1235 getFileValue target "$i/target" || :
1236 vdevmap_opts=( "${vdevmap_opts[@]}" ${flags:+--flags "$flags"} \
1237 ${device:+--device "$device"} ${target:+--target "$target"} )
1239 $_VDEVMAP --xid "$xid" "${vdevmap_opts[@]}" || return $?