2e1b8cbd8dc2791b32600fdd7831554d55e6d0ac
[util-vserver.git] / scripts / legacy / vserver
1 #!/bin/sh
2
3 # Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 # based on vserver by Jacques Gelinas
5 #  
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2, or (at your option)
9 # any later version.
10 #  
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #  
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 # This is a script to control a virtual server
21
22 : ${UTIL_VSERVER_VARS:=/usr/lib/util-vserver/util-vserver-vars}
23 test -e "$UTIL_VSERVER_VARS" || {
24     echo $"Can not find util-vserver installation (the file '$UTIL_VSERVER_VARS' would be expected); aborting..." >&2
25     exit 1
26 }
27 . "$UTIL_VSERVER_VARS"
28
29 USR_SBIN=$__SBINDIR
30 USR_LIB_VSERVER=$__PKGLIBDIR
31 DEFAULTPATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
32 VINIT_CMD=/etc/rc.vinit
33
34 vserver_mknod(){
35         mknod $1 $2 $3 $4
36         chmod $5 $1
37 }
38
39 mountproc()
40 {
41         mkdir -p $1/proc $1/dev/pts
42         if [ ! -d $1/proc/1 ] ; then
43                 mount -t proc none $1/proc
44                 mount -t devpts -o gid=5,mode=0620 none $1/dev/pts
45         fi
46 }
47 umountproc()
48 {
49         umount $1/proc 2>/dev/null
50         umount $1/dev/pts 2>/dev/null
51 }
52
53 # Check that the vservers parent directory has permission 000
54 # This is the key to avoid chroot escape
55 testperm()
56 {
57         return
58         PERM=`$_SHOWPERM $__DEFAULT_VSERVERDIR/$1/..`
59         if [ "$PERM" != 000 ] ; then
60                 echo
61                 echo "**********************************************************"
62                 echo $__DEFAULT_VSERVERDIR/$1/.. has insecure permissions.
63                 echo A vserver administrator may be able to visit the root server.
64                 echo To fix this, do
65                 echo "  " chmod 000 $__DEFAULT_VSERVERDIR/$1/..
66                 echo do it anytime you want, even if vservers are running.
67                 echo "**********************************************************"
68                 echo
69         fi
70 }
71
72 # Extract the initial runlevel from the vserver inittab
73 get_initdefault()
74 {
75         INITDEFAULT=`grep :initdefault $__DEFAULT_VSERVERDIR/$1/etc/inittab | sed 's/:/ /g' | ( read a level b; echo $level)`
76 }
77
78 # Read the vserver configuration file, reusing the PROFILE value
79 # found in /var/run/vservers
80 readlastconf()
81 {
82         if [ -f $__PKGSTATEDIR/$1.ctx ] ; then
83                 . $__PKGSTATEDIR/$1.ctx
84                 if [ "$S_PROFILE" != "" ] ; then
85                         export PROFILE=$S_PROFILE
86                 fi
87         fi
88         export PROFILE
89         . $__CONFDIR/$1.conf
90 }
91
92 usage()
93 {
94         echo vserver [ options ] server-name command ...
95         echo
96         echo server-name is a directory in $__DEFAULT_VSERVERDIR
97         echo
98         echo The commands are:
99         echo " build   : Create a virtual server by copying the packages"
100         echo "           of the root server"
101         echo " enter   : Enter in the virtual server context and starts a shell"
102         echo "           Same as \"vserver name exec /bin/sh\""
103         echo " exec    : Exec a command in the virtual server context"
104         echo " suexec  : Exec a command in the virtual server context uid"
105         echo " service : Control a service inside a vserver"
106         echo "           vserver name service service-name start/stop/restart/status"
107         echo " start   : Starts the various services in the vserver, runlevel 3"
108         echo " stop    : Ends all services and kills the remaining processes"
109         echo " running : Tells if a virtual server is running"
110         echo "           It returns proper exit code, so you can use it as a test"
111         echo " status  : Tells some information about a vserver"
112         echo " chkconfig : It turns a server on or off in a vserver"
113         echo
114         echo "--silent : No informative messages about vserver context and IP numbers"
115         echo "           Useful when you want to redirect the output"
116 }
117
118 calculateCaps()
119 {
120     local f
121     for f in "$@"; do
122         case $f in
123             !CAP_SYS_CHROOT)
124                 CHROOTOPT=--nochroot
125                 ;;
126             *)
127                 CAPS="$CAPS --cap $f"
128                 ;;
129         esac
130     done
131 }
132
133 SILENT=
134 while true
135 do
136         if [ "$1" = "--silent" ] ; then
137                 SILENT=--silent
138                 shift
139         else
140                 break
141         fi
142 done
143 # Setup the default ulimit for a vserver
144 setdefulimit(){
145         # File handle are limited to half of the current system limit
146         # Virtual memory is limited to the ram size
147         NFILE=`cat /proc/sys/fs/file-max`
148         NFILE=`expr $NFILE / 2`
149         VMEM=`cat /proc/meminfo  | grep MemTotal | (read a b c; echo $b)`
150         # Disabled for now, we need a different to set the security
151         # context limit than fiddling with ulimit
152         #ulimit -H -n $NFILE -v $VMEM
153 }
154 if [ $# -lt 2 ] ; then
155         usage
156 elif [ "$2" = "build" ] ; then
157         # Either the directory does not exist or is empty
158         NBSUB=`ls $__DEFAULT_VSERVERDIR/$1 2>/dev/null | grep -v lost+found | wc -l` 
159         NBSUB=`expr $NBSUB`
160         if [ "$NBSUB" != 0 ] ; then
161                 echo Virtual server $__DEFAULT_VSERVERDIR/$1 already exist
162         else
163                 if [ ! -d $__DEFAULT_VSERVERDIR ] ; then
164                         mkdir $__DEFAULT_VSERVERDIR || exit 1
165                         chmod 000 $__DEFAULT_VSERVERDIR
166                         echo Directory $__DEFAULT_VSERVERDIR was created with permissions 000
167                 fi
168                 mkdir -p $__DEFAULT_VSERVERDIR/$1 || exit 1
169                 chmod 755 $__DEFAULT_VSERVERDIR/$1
170                 if test "$UTIL_VSERVER_AVOID_COPY"; then
171                     mkdir -p $__DEFAULT_VSERVERDIR/$1/{etc/rc.d/init.d,sbin,var/run,var/log}
172                 else
173                     cp -ax /sbin /bin /etc /usr /var /lib $__DEFAULT_VSERVERDIR/$1/. || exit 1
174                 fi
175                 cd $__DEFAULT_VSERVERDIR/$1 || exit 1
176                 rm -fr lib/modules/*
177                 rm -f var/spool/mail/*
178                 rm -f `find var/run -type f`
179                 rm -f `find var/log -type f`
180                 touch var/log/wtmp
181                 rm -f var/lock/subsys/*
182                 rm -f etc/cron.d/kmod
183                 mkdir proc tmp home root boot
184                 test -f /root/.bashrc && cp -a /root/.bashrc root/.
185                 test -f /root/.bash_profile && cp -a /root/.bash_profile root/.
186                 chmod 1777 tmp
187                 chmod 750 root
188                 # Create a minimal dev so the virtual server can't grab
189                 # more privileges
190                 mkdir dev dev/pts
191                 vserver_mknod dev/null c 1 3 666
192                 vserver_mknod dev/zero c 1 5 666
193                 vserver_mknod dev/full c 1 7 666
194                 vserver_mknod dev/random c 1 8 644
195                 vserver_mknod dev/urandom c 1 9 644
196                 vserver_mknod dev/tty c 5 0 666
197                 vserver_mknod dev/ptmx c 5 2 666
198                 touch dev/hdv1
199                 # Turn off some service useless on a vserver
200                 #               vserver_turnoff apmd network autofs dhcpd gpm ipchains iptables \
201                 #                       irda isdn keytable kudzu linuxconf-setup netfs nfs nfslock \
202                 #                       pcmcia portmap pppoe random rawdevices rhnsd rstatd ruserd \
203                 #                       rwalld rwhod sendmail smb snmpd v_httpd h_xinetd v_sshd vservers \
204                 #                       xfs ypbind xinetd
205                 (
206                         cd etc/init.d 2>/dev/null || cd etc/rc.d/init.d
207                         for serv in *
208                         do
209                                 case $serv in
210                                 *.bak|*~|functions|killall|halt|single)
211                                         ;;
212                                 *)
213                                         #$USR_LIB_VSERVER/capchroot $__DEFAULT_VSERVERDIR/$1 /sbin/chkconfig --level 2345 $serv off
214                                         $0 --silent $1 chkconfig --level 2345 $serv off
215                                         ;;
216                                 esac
217                         done
218                 )
219                 rm -f etc/rc.d/rc6.d/S*reboot
220                 # Create a dummy /etc/fstab and /etc/mtab to please
221                 # df and linuxconf. We use hdv1, which does not exist
222                 # to remind the admin that it is not the real drive
223                 echo /dev/hdv1 / ext2 defaults 1 1 >etc/fstab
224                 echo /dev/hdv1 / ext2 rw 0 0 >etc/mtab
225                 # Install the vreboot utility
226                 cp -a "$_VREBOOT" sbin/.
227                 ln -sf vreboot sbin/vhalt
228
229                 echo Directory $__DEFAULT_VSERVERDIR/$1 has been populated
230                 if [ ! -d $__CONFDIR ] ; then
231                         mkdir $__CONFDIR
232                         chmod 600 $__CONFDIR
233                         echo Directory $__CONFDIR has been created
234                 fi
235                 if [ ! -f $__CONFDIR/$1.conf ] ; then
236                         CONF=$__CONFDIR/$1.conf
237                         cat >$CONF <<-EOF
238 if [ "$PROFILE" = "" ] ; then
239         PROFILE=prod
240 fi
241 # Select the IP number assigned to the virtual server
242 # This IP must be one IP of the server, either an interface
243 # or an IP alias
244 # A vserver may have more than one IP. Separate them with spaces.
245 # do not forget double quotes.
246 # Some examples:
247 # IPROOT="1.2.3.4 2.3.4.5"
248 # IPROOT="eth0:1.2.3.4 eth1:2.3.4.5"
249 # If the device is not specified, IPROOTDEV is used
250 case \$PROFILE in
251 prod)
252         IPROOT=1.2.3.4
253         # The netmask and broadcast are computed by default from IPROOTDEV
254         #IPROOTMASK=
255         #IPROOTBCAST=
256         # You can define on which device the IP alias will be done
257         # The IP alias will be set when the server is started and unset
258         # when the server is stopped
259         #IPROOTDEV=eth0
260         # You can set a different host name for the vserver
261         # If empty, the host name of the main server is used
262         S_HOSTNAME=
263         ;;
264 backup)
265         IPROOT=1.2.3.4
266         #IPROOTMASK=
267         #IPROOTBCAST=
268         #IPROOTDEV=eth0
269         S_HOSTNAME=
270         ;;
271 esac
272 # Uncomment the onboot line if you want to enable this
273 # virtual server at boot time
274 #ONBOOT=yes
275 # You can set a different NIS domain for the vserver
276 # If empty, the current on is kept
277 # Set it to "none" to have no NIS domain set
278 S_DOMAINNAME=
279 # You can set the priority level (nice) of all process in the vserver
280 # Even root won't be able to raise it
281 S_NICE=
282 # You can set various flags for the new security context
283 # lock: Prevent the vserver from setting new security context
284 # sched: Merge scheduler priority of all processes in the vserver
285 #        so that it acts a like a single one.
286 # nproc: Limit the number of processes in the vserver according to ulimit
287 #        (instead of a per user limit, this becomes a per vserver limit)
288 # private: No other process can join this security context. Even root
289 # Do not forget the quotes around the flags
290 S_FLAGS="lock nproc"
291 # You can set various ulimit flags and they will be inherited by the
292 # vserver. You enter here various command line argument of ulimit
293 # ULIMIT="-HS -u 200"
294 # The example above, combined with the nproc S_FLAGS will limit the
295 # vserver to a maximum of 200 processes
296 #ULIMIT="-HS -u 1000"
297 ULIMIT=""
298 # You can set various capabilities. By default, the vserver are run
299 # with a limited set, so you can let root run in a vserver and not
300 # worry about it. He can't take over the machine. In some cases
301 # you can to give a little more capabilities (such as CAP_NET_RAW)
302 # S_CAPS="CAP_NET_RAW"
303 S_CAPS=""
304 # Select an unused context (this is optional)
305 # The default is to allocate a free context on the fly
306 # In general you don't need to force a context
307 #S_CONTEXT=
308                         EOF
309                         echo $CONF has been created. Look at it\!
310                 fi
311         fi
312 elif [ ! -f $__CONFDIR/$1.conf ] ; then
313         echo No configuration for this vserver: $__CONFDIR/$1.conf
314         exit 1
315 elif [ ! -d $__DEFAULT_VSERVERDIR/$1/. ] ; then
316         echo No directory for this vserver: $__DEFAULT_VSERVERDIR/$1
317         exit 1
318 elif [ "$2" = "start" ] ; then
319         echo Starting the virtual server $1
320         testperm $1
321         if ! $0 $1 running
322         then
323                 test -x $__CONFDIR/$1.sh && $__CONFDIR/$1.sh pre-start $1
324                 S_NICE=
325                 S_FLAGS=
326                 . $__CONFDIR/$1.conf
327                 export PROFILE
328                 cd $__DEFAULT_VSERVERDIR/$1 || exit 1
329
330                 if [ "$PROFILE" != "" ] ; then
331                         echo export PROFILE=$PROFILE >etc/PROFILE
332                 fi
333
334                 rm -f `find var/run -type f`
335                 touch var/run/utmp
336                 chgrp ${UTMP_GROUP:-utmp} var/run/utmp
337                 chmod 0664 var/run/utmp
338                 rm -f  var/lock/subsys/*
339                 mountproc $__DEFAULT_VSERVERDIR/$1
340                 CTXOPT=
341                 HOSTOPT=
342                 DOMAINOPT=
343                 NICECMD=
344                 FLAGS=
345                 CAPS=
346                 get_initdefault $1
347                 STARTCMD="/etc/rc.d/rc $INITDEFAULT"
348                 if [ -x $__DEFAULT_VSERVERDIR/$1/etc/init.d/rc ] ; then
349                         STARTCMD="/etc/init.d/rc $INITDEFAULT"
350                 elif [ -x $__DEFAULT_VSERVERDIR/$1/usr/bin/emerge ] ; then
351                         STARTCMD="/sbin/rc default"
352                 elif [ -x $__DEFAULT_VSERVERDIR/$1/etc/rc.d/rc.M ] ; then
353                         STARTCMD="/etc/rc.d/rc.M"                       
354                 fi
355
356                 DISCONNECT=
357                 FAKEINIT=
358                 for f in $S_FLAGS dummy
359                 do
360                         case $f in
361                         dummy)
362                                 ;;
363
364                         minit)
365                                 FAKEINIT=true
366                                 FLAGS="$FLAGS --flag fakeinit"
367                                 STARTCMD=/sbin/minit-start
368                                 DISCONNECT=--disconnect
369                                 ;;
370
371                         fakeinit)
372                                 FAKEINIT=true
373                                 FLAGS="$FLAGS --flag $f"
374                                 STARTCMD=/sbin/init
375                                 DISCONNECT=--disconnect
376                                 ;;
377                         *)
378                                 FLAGS="$FLAGS --flag $f"
379                                 ;;
380                         esac
381                 done
382                 if [ "$FAKEINIT" = "" ] ; then
383                         $USR_LIB_VSERVER/fakerunlevel $INITDEFAULT var/run/utmp
384                 fi
385
386                 calculateCaps $S_CAPS
387
388                 if [ "$S_CONTEXT" != "" ] ; then
389                         CTXOPT="--ctx $S_CONTEXT"
390                 fi
391                 if [ "$S_HOSTNAME" != "" ] ; then
392                         HOSTOPT="--hostname $S_HOSTNAME"
393                         export HOSTNAME=$S_HOSTNAME
394                 fi
395                 if [ "$S_DOMAINNAME" != "" ] ; then
396                         DOMAINOPT="--domainname $S_DOMAINNAME"
397                 fi
398                 if [ "$S_NICE" != "" ] ; then
399                         NICECMD="nice -n $S_NICE"
400                 fi
401                 mkdir -p $__PKGSTATEDIR
402                 chmod 700 $__PKGSTATEDIR
403                 setdefulimit
404                 if [ "$ULIMIT" != "" ] ; then
405                         ulimit $ULIMIT
406                 fi
407                 #echo FLAGS=$FLAGS
408                 #echo CAPS=$CAPS
409                 # We switch to /vservers/$1 now, because after the
410                 # security context switch /vservers directory becomes a dead zone.
411                 cd $__DEFAULT_VSERVERDIR/$1
412                 export PATH=$DEFAULTPATH
413                 # PLANETLAB execute /etc/rc.vinit first for backward compatibility
414                 for CMD in "$VINIT_CMD $2" "$STARTCMD" ; do
415                     $NICECMD $_CHBIND_COMPAT $SILENT $IPOPT --bcast $IPROOTBCAST \
416                         $_CHCONTEXT_COMPAT $SILENT $DISCONNECT $CAPS $FLAGS $CTXOPT $HOSTOPT $DOMAINOPT --secure \
417                         $_SAVE_S_CONTEXT $__PKGSTATEDIR/$1.ctx \
418                         $_CAPCHROOT $CHROOTOPT . $CMD
419                 done
420
421                 sleep 2
422                 test ! -x $__CONFDIR/$1.sh || $__CONFDIR/$1.sh post-start $1
423         fi
424 elif [ "$2" = "running" ] ; then
425         if [ ! -f $__PKGSTATEDIR/$1.ctx ] ; then
426                 echo Server $1 is not running
427                 exit 1
428         else
429                 . $__PKGSTATEDIR/$1.ctx
430                 NB=$($USR_SBIN/vps ax | awk '{print $2}' | grep \^$S_CONTEXT\$ | wc -l)
431                 #NB=`$_CHCONTEXT_COMPAT --silent --ctx $S_CONTEXT ps ax | wc -l`
432                 #NB=`eval expr $NB + 0`
433                 if [ "$NB" -gt 0 ] ; then
434                         echo Server $1 is running
435                         exit 0
436                 else
437                         echo Server $1 is not running
438                         exit 1
439                 fi
440         fi
441 elif [ "$2" = "status" ] ; then
442         if $0 $1 running
443         then
444                 . $__PKGSTATEDIR/$1.ctx
445                 NB=$($USR_SBIN/vps ax | awk '{print $2}' | grep \^$S_CONTEXT\$ | wc -l)
446                 echo $NB processes running
447                 echo Vserver uptime: `$USR_LIB_VSERVER/filetime $__PKGSTATEDIR/$1.ctx`
448         fi
449 elif [ "$2" = "stop" ] ; then
450         echo Stopping the virtual server $1
451         CAPS=
452         IS_MINIT=
453         readlastconf $1
454         if $0 $1 running
455         then
456                 test -x $__CONFDIR/$1.sh && $__CONFDIR/$1.sh pre-stop $1
457                 cd $__DEFAULT_VSERVERDIR/$1
458                 mountproc $__DEFAULT_VSERVERDIR/$1
459                 # The fakeinit flag tell us how to turn off the server
460                 get_initdefault $1
461                 export PREVLEVEL=$INITDEFAULT
462                 STOPCMD="/etc/rc.d/rc 6"
463                 if [ -x $__DEFAULT_VSERVERDIR/$1/etc/init.d/rc ] ; then
464                         STOPCMD="/etc/init.d/rc 6"
465                 elif [ -x $__DEFAULT_VSERVERDIR/$1/usr/bin/emerge ] ; then
466                         STOPCMD="/sbin/rc shutdown"
467                 elif [ -x $__DEFAULT_VSERVERDIR/$1/etc/rc.d/rc.6 ] ; then
468                         STOPCMD="/etc/rc.d/rc.6"
469                 fi
470
471                 for f in $S_FLAGS dummy
472                 do
473                         case $f in
474                         minit)
475                                 IS_MINIT=1
476                                 FLAGS="$FLAGS --flag fakeinit"
477                                 STOPCMD="/sbin/minit-stop"
478                                 ;;
479
480                         fakeinit)
481                                 FLAGS="$FLAGS --flag $f"
482                                 STOPCMD="/sbin/init 6"
483                                 ;;
484                         *)
485                                 ;;
486                         esac
487                 done
488
489                 calculateCaps $S_CAPS
490
491                 cd $__DEFAULT_VSERVERDIR/$1
492                 export PATH=$DEFAULTPATH
493                 # PLANETLAB execute /etc/rc.vinit first for backward compatibility
494                 for CMD in "$VINIT_CMD $2" "$STOPCMD" ; do
495                     $_CHBIND_COMPAT $SILENT $IPOPT --bcast $IPROOTBCAST \
496                         $_CHCONTEXT_COMPAT $SILENT $CAPS --secure --ctx $S_CONTEXT \
497                         $_CAPCHROOT . $CMD
498                 done
499
500                 if test "$IS_MINIT"; then
501                     echo "Waiting for minit finish-signal"
502                     dd if=var/run/minit-stop of=/dev/zero bs=1 count=1 &>/dev/null
503                     sleep 1
504                 else
505                     echo sleeping 5 seconds
506                     sleep 5
507                 fi
508
509                 echo Killing all processes
510                 $_CHBIND_COMPAT --silent $IPOPT --bcast $IPROOTBCAST \
511                         $_CHCONTEXT_COMPAT $CAPS --secure --silent --ctx $S_CONTEXT \
512                         $_VSERVERKILLALL
513         fi
514         # We umount anyway, because "enter" establish the mount
515         # but when you exit, the server is considered not running
516         umountproc $__DEFAULT_VSERVERDIR/$1
517         cd /
518         test -x $__CONFDIR/$1.sh && $__CONFDIR/$1.sh post-stop $1
519 elif [ "$2" = "restart" ] ; then
520         if $0 $1 running
521         then
522                 $0 $1 stop
523                 $0 $1 start
524         fi
525 elif [ "$2" = "suexec" ] ; then
526         if [ -z "$3" ] ; then
527                 echo "Missing user!" >&2
528                 echo "vserver vserver-name suexec user command [ args ... ]" >&2
529                 exit 1
530         elif [ -z "$4" ] ; then
531                 echo "Missing command and arguments!" >&2
532                 echo "vserver vserver-name suexec user command [ args ... ]" >&2
533                 exit 1
534         else
535                 readlastconf $1
536                 . $__CONFDIR/$1.conf
537                 cd $__DEFAULT_VSERVERDIR/$1
538                 mountproc $__DEFAULT_VSERVERDIR/$1
539                 PS1="[\u@vserver:$1 \W]"
540                 export PS1
541                 VSERVER=$1
542                 USERID=$3
543                 shift; shift; shift
544                 CAPS=
545                 for f in $S_CAPS dummy
546                 do
547                         case $f in
548                         dummy)
549                                 ;;
550                         !CAP_SYS_CHROOT)
551                                 CHROOTOPT=--nochroot
552                                 ;;
553                         *)
554                                 CAPS="$CAPS --cap $f"
555                                 ;;
556                         esac
557                 done
558                 FLAGS=
559                 for f in $S_FLAGS dummy
560                 do
561                         case $f in
562                         minit)
563                                 FLAGS="$FLAGS --flag fakeinit"
564                                 ;;
565
566                         dummy)
567                                 ;;
568                         *)
569                                 FLAGS="$FLAGS --flag $f"
570                                 ;;
571                         esac
572                 done
573                 setdefulimit
574                 if [ "$ULIMIT" != "" ] ; then
575                         ulimit $ULIMIT
576                 fi
577                 if $0 $VSERVER running >/dev/null
578                 then
579                         . $__PKGSTATEDIR/$VSERVER.ctx
580                         cd $__DEFAULT_VSERVERDIR/$VSERVER
581                         export PATH=$DEFAULTPATH
582                         exec $_CHBIND_COMPAT $SILENT $IPOPT --bcast $IPROOTBCAST \
583                                 $_CHCONTEXT_COMPAT $SILENT $FLAGS $CAPS --secure --ctx $S_CONTEXT \
584                                 $_CAPCHROOT --suid $USERID . "$@"
585                 else
586                         test -x $__CONFDIR/$1.sh && $__CONFDIR/$1.sh pre-start $1
587                         CTXOPT=
588                         HOSTOPT=
589                         DOMAINOPT=
590                         if [ "$S_CONTEXT" != "" ] ; then
591                                 CTXOPT="--ctx $S_CONTEXT"
592                         fi
593                         if [ "$S_HOSTNAME" != "" ] ; then
594                                 HOSTOPT="--hostname $S_HOSTNAME"
595                                 export HOSTNAME=$S_HOSTNAME
596                         fi
597                         if [ "$S_DOMAINNAME" != "" ] ; then
598                                 DOMAINOPT="--domainname $S_DOMAINNAME"
599                         fi
600                         mkdir -p $__PKGSTATEDIR
601                         cd $__DEFAULT_VSERVERDIR/$VSERVER
602                         export PATH=$DEFAULTPATH
603                         exec $_CHBIND_COMPAT $SILENT $IPOPT --bcast $IPROOTBCAST \
604                                 $_CHCONTEXT_COMPAT $SILENT $FLAGS $CAPS --secure $CTXOPT $HOSTOPT $DOMAINOPT \
605                                 $_SAVE_S_CONTEXT $__PKGSTATEDIR/$VSERVER.ctx \
606                                 $_CAPCHROOT --suid $USERID $CHROOTOPT . "$@"
607                 fi
608         fi
609 elif [ "$2" = "exec" ] ; then
610         VSERV=$1
611         shift; shift
612         exec $0 $SILENT $VSERV suexec root "$@"
613 elif [ "$2" = "enter" ] ; then
614         testperm $1
615         exec $0 $SILENT $1 exec /bin/bash -login
616 elif [ "$2" = "service" ] ; then
617         VSERVER=$1
618         shift
619         shift
620         exec $0 $SILENT $VSERVER exec /sbin/service "$@"
621 elif [ "$2" = "chkconfig" ] ; then
622         VSERVER=$1
623         shift
624         shift
625         if [ "$1" = "--level" ] ; then
626                 shift
627                 LEVELS=$1
628                 shift
629         fi
630         if [ $# != 2 -a ! -x $__DEFAULT_VSERVERDIR/$VSERVER/sbin/chkconfig ] ; then
631                 echo Invalid argument, expected vserver name chkconfig [ --level nnn ] service on\|off
632         elif [ -x $__DEFAULT_VSERVERDIR/$VSERVER/sbin/chkconfig ] ; then
633                 exec $0 --silent $VSERVER exec /sbin/chkconfig "$@"
634         elif [ -x $__DEFAULT_VSERVERDIR/$VSERVER/usr/sbin/update-rc.d ] ; then
635                 if [ "$2" = "on" -o "$2" = "start" ] ; then
636                         $0 --silent $VSERVER exec /usr/sbin/update-rc.d -f $1 remove >/dev/null
637                         exec $0 --silent $VSERVER exec /usr/sbin/update-rc.d $1 start 80 2 3 4 5 . stop 20 0 1 6 . >/dev/null
638                 elif [ "$2" = "off" -o "$2" = "stop" ] ; then
639                         $0 --silent $VSERVER exec /usr/sbin/update-rc.d -f $1 remove >/dev/null
640                         exec $0 --silent $VSERVER exec /usr/sbin/update-rc.d $1 stop 20 0 1 2 3 4 5 6 . >/dev/null
641                 else
642                         echo vserver chkconfig: Expecting on or off
643                 fi
644         else
645                 echo chkconfig functionality is not available on this
646                 echo vserver distribution.
647                 echo Looked for /sbin/chkconfig and /usr/sbin/update-rc.d
648         fi
649 else
650         echo Command unknown $2
651         echo
652         usage
653 fi
654