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