implemented parts of Liam Helmer's dummy-interface method
[util-vserver.git] / util-vserver / scripts / vserver.functions
1 # $Id$  --*- sh -*--
2
3 # Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 #  
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.
8 #  
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.
13 #  
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.
17
18 ## Expected env:
19 #  $VSERVER_DIR   ... path to vserver-cfg dir
20 #  $VSERVER_NAME  ... name of vserver
21
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=()
30
31 declare -a INITCMD_START=()
32 declare -a INITCMD_START_SYNC=()
33 declare -a INITCMD_STOP=()
34 declare -a INITCMD_STOP_SYNC=()
35 declare -a INITCMD_PREPARE=()
36 declare -a INITKILL_SEQ=()
37 declare -a ENTER_SHELL=()
38
39 declare -a OPTS_VCONTEXT_CREATE=()
40 declare -a OPTS_VCONTEXT_MIGRATE=()
41 declare -a OPTS_VATTRIBUTE=()
42 declare -a OPTS_VSCHED=()
43
44 declare -a VSERVER_EXTRA_CMDS=()
45
46 VSHELPER_SYNC_TIMEOUT=30
47 USE_VNAMESPACE=
48 INTERFACE_CMDS_IDX=0
49 _HAVE_INTERFACE_OPTIONS=
50 _HAVE_CHBIND_OPTIONS=
51 _NEED_VSHELPER_SYNC=
52 _IS_FAKEINIT=
53
54 INITSTYLE=sysv
55
56 S_CONTEXT=
57
58 SILENT_OPT=
59
60 : ${VSERVER_NAME:=$(basename "$VSERVER_DIR")}
61
62 if test -e "$VSERVER_DIR"/noisy -o "$OPTION_VERBOSE"; then
63     SILENT_OPT=
64 else
65     SILENT_OPT='--silent'
66 fi
67
68 function _generateChbindOptions
69 {
70     local vdir="$1"
71     local i
72     local bcast=
73
74     test "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$vdir"
75
76     local f=$vdir/interfaces/bcast
77     getFileValue bcast "$f"
78     
79     CHBIND_OPTS=( $SILENT_OPT ${bcast:+--bcast "$bcast"} )
80
81     for i in "${INTERFACES[@]}"; do
82         CHBIND_OPTS=( "${CHBIND_OPTS[@]}" --ip "$i" )
83     done
84
85     _HAVE_CHBIND_OPTIONS=1
86 }
87
88 function _generateNiceCommand
89 {
90     local vdir=$1
91     local nice
92
93     test -r "$vdir/nice" || return 0;
94     read nice <"$vdir"/nice
95
96     NICE_CMD=( $_NICE -$nice )
97 }
98
99 function _generateCCapabilityOptions
100 {
101     local vdir=$1
102     local cap
103     local f="$vdir"/ccapabilities
104     
105     test -e "$f" || return 0
106     while read cap; do
107         case x"$cap" in
108             (x|x\#)     ;;
109             (*)         OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --ccap "$cap" );;
110         esac
111     done <"$f"
112 }
113
114 function _generateBCapabilityOptions
115 {
116     local vdir=$1
117     local cap
118     local f="$vdir"/bcapabilities
119     
120     test -e "$f" || return 0
121     while read cap; do
122         case x"$cap" in
123             (x|x\#)     ;;
124             (*)         OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --bcap "$cap" );;
125         esac
126     done <"$f"
127 }
128
129 function _generateCapabilityOptions
130 {
131     local vdir=$1
132     local cap
133
134     _generateBCapabilityOptions "$vdir"
135     _generateCCapabilityOptions "$vdir"
136     
137     test -e "$vdir"/capabilities || return 0
138
139     CAP_OPTS=()
140     CAPCHROOT_OPTS=()
141
142     while read cap; do
143         case x"$cap" in
144             (x|x\#)     ;;
145             (!CAP_SYSCHROOT)
146                 CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" )
147                 CAPCHROOT_OPTS=( "${CAPCHROOT_OPTS[@]}" --nochroot )
148                 ;;
149             (*)
150                 CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" )
151                 ;;
152         esac
153     done <"$vdir"/capabilities
154 }
155
156 function getEnterShell
157 {
158     local vdir=$1
159
160     ENTER_SHELL=()
161     
162     getFileValue ENTER_SHELL     "$vdir"/shell
163     
164     test "$ENTER_SHELL" || {
165         local i
166         for i in "/bin/bash -login" "/bin/sh -l" /bin/csh; do
167             set -- $i
168             test -x "$vdir/vdir/$1" || continue
169             ENTER_SHELL=( "$@" )
170             break
171         done
172     }
173 }
174
175 ## Usage: sendKillSequence <ctx> <signal> [<wait> <signal>]*
176 function sendKillSequence
177 {
178     local ctx=$1
179     local wait=
180     shift
181
182     while isCtxRunning "$ctx"; do
183         test -z "$wait" || sleep "$wait"
184         
185         $_VKILL -c "$ctx" ${1:+-s "$1"}
186         test "$2" || break
187         wait="$2"
188         shift 2
189     done
190 }
191
192 function _generateInitOptions
193 {
194     local vdir=$1
195     local cfgdir=$vdir/apps/init
196     local runlevel_start
197     local runlevel_stop
198     local i f
199
200     INITCMD_START=()
201     INITCMD_STOP=()
202     INITCMD_START_SYNC=()
203     INITCMD_STOP_SYNC=()
204     INITCMD_PREPARE=()
205
206     INITKILL_SEQ=( 15 5 9 )
207     CHCONTEXT_INIT_OPTS=()
208
209
210     getFileValue INITSTYLE      "$cfgdir"/style
211     getFileValue runlevel_start "$cfgdir"/runlevel
212     getFileValue runlevel_start "$cfgdir"/runlevel.start
213     getFileValue runlevel_stop  "$cfgdir"/runlevel.stop
214     getFileArray INITKILL_SEQ   "$cfgdir"/killseq || :
215
216     case x"$INITSTYLE" in
217         (xsysv)
218             test "$runlevel_start" || runlevel_start=3
219             test "$runlevel_stop"  || runlevel_stop=6
220
221             for i in /etc/init.d/rc /etc/rc.d/rc; do
222                 test -x "$vdir/vdir/$i" || continue
223                 INITCMD_START=( "$i" "$runlevel_start" )
224                 INITCMD_STOP=(  "$i" "$runlevel_stop"  )
225             done
226             INITCMD_PREPARE=( $_FAKE_RUNLEVEL "$runlevel_start" /var/run/utmp )
227             ;;
228             
229         (xplain)
230             INITCMD_START=( /sbin/init )
231             INITCMD_STOP=(  /sbin/init )
232             _IS_FAKEINIT=1
233             _NEED_VSHELPER_SYNC=1
234             test -z "$runlevel_start" || INITCMD_START=( "${INITCMD_START[@]}" "$runlevel_start" )
235             test -z "$runlevel_stop"  || INITCMD_STOP=(  "${INITCMD_STOP[@]}"  "$runlevel_stop"  )
236             ;;
237             
238         (xminit)
239             INITCMD_START=( /sbin/minit-start )
240             INITCMD_STOP=(  /sbin/minit-stop  )
241             _IS_FAKEINIT=1
242             INITCMD_START_SYNC=( "$_INITSYNC_MINIT_START" "$vdir" )
243             _NEED_VSHELPER_SYNC=1
244             test -z "$runlevel_start" || INITCMD_START=( "${INITCMD_START[@]}" "$runlevel_start" )
245             test -z "$runlevel_stop"  || INITCMD_STOP=(  "${INITCMD_STOP[@]}"  "$runlevel_stop"  )
246             ;;
247
248         (xgentoo)
249             INITCMD_START=( /sbin/rc default  )
250             INITCMD_STOP=(  /sbin/rc shutdown )
251             ;;
252
253         (x) ;;
254         (*) echo "Unknown init-style '$INITSTYLE'; aborting" >&2;
255             exit 1;;
256     esac
257
258     getFileArray INITCMD_START      "$cfgdir"/cmd.start      || :
259     getFileArray INITCMD_STOP       "$cfgdir"/cmd.stop       || :
260     getFileArray INITCMD_START_SYNC "$cfgdir"/cmd.start-sync || :
261     getFileArray INITCMD_STOP_SYNC  "$cfgdir"/cmd.stop-sync  || :
262     getFileArray INITCMD_PREPARE    "$cfgdir"/cmd.prepare    || :
263
264     
265     test "$OPTION_FORCE_SYNC" -o -e "$cfgdir"/sync || {
266         INITCMD_START_SYNC=()
267         INITCMD_STOP_SYNC=()
268         _NEED_VSHELPER_SYNC=
269     }
270
271     if vshelper.isEnabled; then
272         vshelper.getSyncTimeout "$vdir" VSHELPER_SYNC_TIMEOUT || :
273     else
274         _NEED_VSHELPER_SYNC=
275     fi
276 }
277
278 function _generateFlagOptions
279 {
280     local vdir=$1
281
282     CHCONTEXT_FLAG_OPTS=()
283
284     test ! -e "$vdir"/flags || \
285     while read flag; do
286         case x"$flag" in
287             (x|x\#)             ;;
288             (xnamespace)        ;;
289             (xfakeinit)
290                 _IS_FAKEINIT=1
291                 ;;
292             (*)
293                 OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --flag "$flag" )
294                 CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}"
295                                       --flag "$flag" )
296                 ;;
297         esac
298     done <"$vdir"/flags
299
300     isAvoidNamespace "$vdir" || {
301         USE_VNAMESPACE=1
302         CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}" --flag namespace )
303     }
304 }
305
306 function _generateChcontextOptions
307 {
308     local vdir=$1
309     local ctx hostname domainname
310     local cap_opts
311     local flag
312
313     {
314         read ctx        <"$vdir"/context        || :
315         ## LEGACY ALERT
316         read hostname   <"$vdir"/uts/nodename   || read hostname   <"$vdir"/hostname   || :
317         read domainname <"$vdir"/uts/domainname || read domainname <"$vdir"/domainname || :
318     } 2>/dev/null
319
320     ## LEGACY ALERT
321     test \( ! -e "$vdir"/hostname   -o -e "$vdir"/uts/nodename   \) -a \
322          \( ! -e "$vdir"/domainname -o -e "$vdir"/uts/domainname \) || {
323         echo $"\
324 The hostname is now configured in 'uts/nodename' but not in 'hostname' anymore;
325 the old way is not supported when using 2.6 kernel patches so it is strongly
326 recommended to move these files.
327
328 The same applies to 'domainname' vs. 'uts/domainname'." >&2
329     }
330
331     test -z "$S_CONTEXT" || ctx=$S_CONTEXT
332
333     _generateCapabilityOptions "$vdir"
334     _generateFlagOptions       "$vdir"
335
336     CHCONTEXT_OPTS=( $SILENT_OPT \
337                      "${CHCONTEXT_FLAG_OPTS[@]}" \
338                      "${CAP_OPTS[@]}" \
339                      --secure
340                      ${ctx:+--ctx "$ctx"} \
341                      ${hostname:+--hostname "$hostname"} \
342                      ${domainname:+--domainname "$domainname"} )
343
344     OPTS_VCONTEXT_CREATE=( $SILENT_OPT \
345                            ${ctx:+--xid "$ctx"} )
346     ## put '--secure' at front so that it can be overridden
347     OPTS_VATTRIBUTE=( --secure "${OPTS_VATTRIBUTE[@]}" )
348 }
349
350 function _generateScheduleOptions
351 {
352     local vdir=$1
353     local f="$vdir"/schedule
354     test -e "$f" || return 0
355
356     local fill_rate interval tokens tokens_min tokens_max cpu_mask
357     {
358         {
359             read fill_rate   && \
360             read interval    && \
361             read tokens      && \
362             read tokens_min  && \
363             read tokens_max  && \
364             read cpu_mask    || cpu_mask=
365         } <"$f"
366     } 2>/dev/null
367
368     test "$cpu_mask" || {
369         echo $"Bad content in '$f'; aborting..." >&2
370         false
371     }
372
373     OPTS_VSCHED=( --fill-rate  "$fill_rate"  --interval "$interval" \
374                   --tokens     "$tokens"     --tokens_min "$tokens_min" \
375                   --tokens_max "$tokens_max" --cpu_mask "$cpu_mask" )
376 }
377
378 function _getInterfaceValue
379 {
380     local val=$1
381     local dflt=$2
382     shift 2
383     
384     local i
385     local tmp
386
387     for i; do
388         read tmp  <"$i/$val" && break || :
389     done 2>/dev/null
390
391     : ${tmp:=$dflt}
392     eval $val=\$tmp
393 }
394
395 ## Usage: _transformMask2Prefix <result-varname> <prefix> <mask>
396 function _transformMask2Prefix
397 {
398     local tmp=$2
399     
400     test "$tmp" || {
401         $_MASK2PREFIX "$3" || tmp=$?
402     }
403
404     eval $1=\$tmp
405     return 0
406 }
407
408 function _addInterfaceCmd
409 {
410     eval INTERFACE_CMDS_${INTERFACE_CMDS_IDX}='( "$@" )'
411     let ++INTERFACE_CMDS_IDX
412 }
413
414 ## Usage: _generateMac <var> <iface> <ctx>
415 function _generateMac
416 {
417     isNumber "$2" || {
418         echo $"Interface basename '$iface' must be either a number, or the mac must be configured explicitly" >&2
419         return 1
420     }
421
422     eval $1=$(printf "f0:ff:%02x:%02x:%02x:%02x" $[ (~($2>>8)) & 0xff ] $[ ($2 & 0xff) ] $[ ($3>>8) & 0xff ] $[ $3 & 0xff ])
423 }
424
425 ## Usage: _processSingleInterface <interface-directory>
426 function _processSingleInterface
427 {
428     local iface=$1
429
430     local ip
431     local dev
432     local prefix
433     local mask
434     local bcast
435     local name
436     local scope
437     local mac
438     local extip
439     local up="up"
440
441     _getInterfaceValue ip     '' "$iface"
442     _getInterfaceValue extip  '' "$iface" "$iface/.."
443     _getInterfaceValue dev    '' "$iface" "$iface/.."
444     _getInterfaceValue prefix '' "$iface" "$iface/.."
445     _getInterfaceValue mask   '' "$iface" "$iface/.."
446     _getInterfaceValue bcast  '' "$iface" "$iface/.."
447     _getInterfaceValue name   '' "$iface"
448     _getInterfaceValue scope  '' "$iface" "$iface/.."
449     _getInterfaceValue mac    '' "$iface"
450
451     test "$ip" || { echo $"Can not read ip for '$iface'"  >&2; return 1; }
452
453     test ! -e "$iface"/only_ip || {
454         ## LEGACY ALERT
455         echo $"The 'only_ip' flag for interface '$iface' is deprecated; use 'nodev' instead of" >&2
456         unset dev
457     }
458     test ! -e "$iface"/nodev   || unset dev
459     test ! -e "$iface"/down    || up=
460     
461     if test "$dev"; then
462         _transformMask2Prefix prefix "$prefix" "$mask"
463
464         case "$dev" in
465             (*.*)
466                 test -d /proc/net/vlan || {
467                     echo -e $"VLAN device-name used, but vlan subsystem not enabled.\nTry to execute 'modprobe 8021q' before starting the vservers"  >&2
468                     return 1
469                 }
470                 test -f /proc/net/vlan || {
471                     _addInterfaceCmd VCONFIG "${dev/./ }"
472                     _addInterfaceCmd IP_ADDR 127.0.0.1/8 broadcast 127.255.255.255 dev "$dev"
473                     _addInterfaceCmd IP_LINK "$dev" $up
474                 }
475                 ;;
476         esac
477
478         if ! test -e "$iface"/indirect; then
479             _addInterfaceCmd IP_ADDR  "$ip${prefix:+/$prefix}" broadcast ${bcast:-+} ${name:+label "$dev:$name"} dev "$dev"
480             #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
481             _addInterfaceCmd IP_LINK  "$dev" $up
482         elif ! test "$ctx"; then
483             echo $"Using 'dummy' (indirect) for interface '$dev' requires a fixed context number; dynamic ctx are not supported" >&2
484             return 1
485         else
486             test "$mac" || _generateMac mac "$(basename '$iface')" "$ctx" || return 1
487             _addInterfaceCmd MODPROBE -o "dummy${ctx}" dummy
488             _addInterfaceCmd IP_LINK  dev "dummy${ctx}" address "$mac"
489             _addInterfaceCmd NAMEIF   "$dev" "$mac"
490             _addInterfaceCmd IP_ADDR  "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} dev "$dev"
491             test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" "$ctx" "$extip"
492         fi
493         INTERFACES=( "${INTERFACES[@]}" "$ip${prefix:+/$prefix}" )
494     fi
495 }
496
497 ## Usage: _generateInterfaceOptions <vserver-directory>
498 function _generateInterfaceOptions
499 {
500     local iface
501     local ctx
502
503     test ! -e "$1"/context || read ctx <"$vdir"/context
504
505     for iface in "$1/interfaces/"*; do
506         test   -d "$iface"          || continue
507         test ! -e "$iface"/disabled || continue
508     
509         _processSingleInterface "$iface"
510     done
511     _HAVE_INTERFACE_OPTIONS=1
512 }
513
514 function enableInterfaces
515 {
516     local i=0
517     declare -a var
518
519     while test $i -lt $INTERFACE_CMDS_IDX; do
520         eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
521         local type=${var[0]}
522         unset var[0]
523         
524         case "$type" in
525             IPTABLES)   ;; ## TODO
526             MODPROBE)   $_MODPROBE "${var[@]}";;
527             NAMEIF)     $_NAMEIF   "${var[@]}";;
528             VCONFIG)    $_VCONFIG  add "${var[@]}";;
529             IP_ADDR)    $_IP addr  add "${var[@]}";;
530             IP_LINK)    $_IP link  set "${var[@]}";;
531             IP_ROUTE)   $_IP route add "${var[@]}";;
532             *)          echo "Unknown interface-command type '$type'" >&2; false;;
533         esac
534
535         let ++i
536     done
537 }
538
539 function disableInterfaces
540 {
541     test "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$1"
542
543     local i=$INTERFACE_CMDS_IDX
544     declare -a var
545
546     while test $i -gt 0; do
547         let --i || :
548
549         eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
550         local type=${var[0]}
551         unset var[0]
552         
553         case "$type" in
554             IPTABLES)   ;; ## TODO
555             MODPROBE)   $_RMMOD    "${var[@]}";;
556             NAMEIF)     ;;
557             VCONFIG)    $_VCONFIG  rem "${var[@]}";;
558             IP_ADDR)    $_IP addr  del "${var[@]}";;
559             IP_LINK)    ;; ## Ignore the link-down command for now
560             IP_ROUTE)   $_IP route del "${var[@]}";;
561             *)          echo "Unknown interface-command type '$type'" >&2; false;;
562         esac
563     done
564 }
565
566 ## Usage: prepareInit <vserver-directory>
567 function prepareInit
568 {
569     pushd "$1/vdir" >/dev/null
570     case "$INITSTYLE" in
571         sysv)
572             { find var/run  ! -type d -print0; \
573               find var/lock ! -type d -print0; } | xargs -0r $_CHROOT_RM
574             ;;
575         minit)
576             ;;
577     esac
578     "${INITCMD_PREPARE[@]}"
579     popd >/dev/null
580 }
581
582 function generateOptions
583 {
584     _generateInterfaceOptions  "$1"
585     test "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1" 
586     _generateNiceCommand       "$1"
587     _generateInitOptions       "$1"
588     _generateChcontextOptions  "$1"
589     _generateScheduleOptions   "$1"
590
591     if test "$_IS_FAKEINIT"; then
592         CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
593         OPTS_VCONTEXT_MIGRATE=( "${OPTS_VCONTEXT_MIGRATE[@]}" --fakeinit --disconnect )
594     fi
595 }
596
597 function _mountVserverInternal
598 {
599     local fstab="$1"
600     test -e "$fstab" || return 0
601     shift
602     
603     "$@" $_SECURE_MOUNT -a --chroot "$vdir" --fstab "$fstab"
604 }
605
606 function mountVserver
607 {
608     local cfgdir=$1
609     local ns_opt=$2
610     local vdir=$1/vdir
611     local mtab_src
612
613     test -e "$cfgdir"/fstab -o \
614          -e "$cfgdir"/fstab.local || return 0
615
616     findObject -r mtab_src "$vdir"/apps/init/mtab "$CONFDIR"/.defaults/init/mtab "$PKGLIBDEFAULTDIR"/mtab /dev/null
617     
618     pushd "$vdir" >/dev/null
619     $_CHROOT_CAT /etc/mtab <"$mtab_src"
620     popd >/dev/null
621
622     test "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
623
624     test -z "$NAMESPACE_CLEANUP" || isAvoidNamespace "$cfgdir" || \
625         $_VNAMESPACE --cleanup
626
627     _mountVserverInternal "$cfgdir"/fstab       $_CHBIND "${CHBIND_OPTS[@]}"
628     _mountVserverInternal "$cfgdir"/fstab.local
629
630     isAvoidNamespace "$cfgdir" || \
631         $_SECURE_MOUNT --rbind -n "$vdir" "/"
632 }
633
634 function _umountVserverInternal
635 {
636     local fstab="$1"
637     test -e "$fstab" || return 0
638     shift
639
640     tac "$fstab" | {
641         is_ok=1
642         while read src dst tmp; do
643             test "$tmp" || continue
644             case x"$src" in
645                 (x\#*)  continue;;
646             esac
647
648         
649             "$@" $_EXEC_CD "$dst" $_UMOUNT -lfn . || is_ok=
650         done
651         test "$is_ok"
652     }
653 }
654
655 function umountVserver
656 {
657     local cfgdir=$1
658     local vdir=$1/vdir
659     local is_ok=1
660
661     isAvoidNamespace "$cfgdir"    || return 0
662     test -e "$cfgdir"/fstab -o \
663          -e "$cfgdir"/fstab.local || return 0
664     test "$_HAVE_CHBIND_OPTIONS"  || _generateChbindOptions "$cfgdir"
665     
666     pushd "$vdir/" >/dev/null || return 1
667         _umountVserverInternal  "$cfgdir"/fstab.local                              || is_ok=
668         _umountVserverInternal  "$cfgdir"/fstab       $_CHBIND "${CHBIND_OPTS[@]}" || is_ok=
669     popd >/dev/null           || return 1
670
671     test "$is_ok"
672 }
673
674 ## Usage: waitForSync <vserver> <vshelper-fifo-varname>
675 function initSync
676 {
677     test -z "$_NEED_VSHELPER_SYNC" || vshelper.initSync "$1" "$2"
678 }
679
680 ## Usage: waitForSync <vserver> [<vshelper-fifo>]
681 function waitForSync
682 {
683     local cfgdir=$1
684     local fifo=$2
685     
686     if test "$_NEED_VSHELPER_SYNC"; then
687         $_VSHELPER_SYNC "$fifo" "$VSHELPER_SYNC_TIMEOUT" || \
688             warning $"\
689 A timeout or other error occured while waiting for the synchronization
690 signal from vserver '$VSERVER_NAME'.
691 The vserver will be killed nevertheless..."
692     elif test "${#INITCMD_STOP_SYNC[@]}" -ne 0; then
693         "${INITCMD_STOP_SYNC[@]}" || \
694             warning $"\
695 Stop-synchronization for vserver '$VSERVER_NAME' failed. The vserver
696 will be killed nevertheless..."
697     fi
698
699     test -z "$OPTION_FORCE_SYNC" -a ! -e "$cfgdir"/sync ||
700         sleep 1
701 }
702
703 function _sourceWrap
704 {
705     local vdir name flavor start i
706     . "$@"
707 }
708
709 ## Usage: execScriptlets <vserver-cfgdir> <vserver-name> <script-flavor>
710 function execScriptlets
711 {
712     local vdir=$1
713     local name=$2
714     local flavor=$3
715     local start=
716     local i
717
718     for i in "$vdir/scripts/$flavor" "$vdir/scripts/$flavor.d"/*; do
719         test -f "$i" -a -r "$i" || continue
720         test -x "$i" || start=_sourceWrap
721         $start "$i" "$flavor" "$name"
722     done
723 }