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