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