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