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