]> git.pld-linux.org Git - packages/vzctl.git/blob - vz-pld.in
Merge branch 'master' of ssh://git.pld-linux.org/packages/vzctl
[packages/vzctl.git] / vz-pld.in
1 #!/bin/sh
2 #  Copyright (C) 2000-2009, Parallels, Inc. All rights reserved.
3 #
4 #  This program is free software; you can redistribute it and/or modify
5 #  it under the terms of the GNU General Public License as published by
6 #  the Free Software Foundation; either version 2 of the License, or
7 #  (at your option) any later version.
8 #
9 #  This program is distributed in the hope that it will be useful,
10 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 #  GNU General Public License for more details.
13 #
14 #  You should have received a copy of the GNU General Public License
15 #  along with this program; if not, write to the Free Software
16 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 #
18 #
19 # OpenVZ startup script, used for redhat and debian related distributions.
20
21 ###
22 # chkconfig: 2345 96 88
23 # description: OpenVZ startup script.
24 ###
25
26 ### BEGIN INIT INFO
27 # Provides: vz
28 # Required-start: $network $remote_fs $syslog
29 # Required-stop:  $network $remote_fs $syslog
30 # Should-Start:  sshd vzeventd
31 # Should-Stop:  sshd vzeventd
32 # Default-Start: 2 3 4 5
33 # Default-Stop: 0 1 6
34 # Short-Description: OpenVZ startup script
35 # Description: OpenVZ startup script.
36 ### END INIT INFO
37
38
39 # This line is needed to cheat /etc/init.d/rc who expects action word
40
41 . /etc/rc.d/init.d/functions
42 . @SCRIPTDIR@/initd-functions
43
44 VZQUOTA=@SBINDIR@/vzquota
45 CONFIG_DIR=@PKGCONFDIR@/conf
46 LOCKFILE=/var/lock/subsys/vz_lock
47 SUBSYS_VZ=/var/lock/subsys/vz
48 VESTAT=/proc/vz/vestat
49 VZDEV=venet0
50 PRELOAD_MODULES=
51 MODULES=
52 MODULES_OTHER=
53 NET_MODULES=
54 IPT_MODULES=
55
56 if [ "${MODULES_DISABLED}" != "yes" ]; then
57         PRELOAD_MODULES="af_packet"
58         MODULES="vzmon vzdquota vzdev"
59         CPT_MODULES="vzcpt vzrst"
60         MODULES_OTHER="vzcompat ${CPT_MODULES}"
61         VNET_MODULES="vznetdev vznet"
62         VETH_MODULES="vzethdev"
63         NET_MODULES="${VNET_MODULES} ${VETH_MODULES}"
64         if [ "${VZWDOG}" = "yes" ]; then
65                 MODULES="${MODULES} vzwdog"
66         fi
67         IPT_MODULES="ip_tables ${IPTABLES} xt_tcpudp"
68         if [ "${IPV6}" = "yes" ]; then
69                 IPT_MODULES="${IPT_MODULES} ${IP6TABLES}"
70         fi
71         VZFS_MODULES="simfs"
72 fi
73
74
75 VEINFO=""
76 RETVAL=0
77 # Number of the containers to stop in parallel.
78 # In case of empty value the number of CTs is calculated as 'num_cpu * 4'
79 PARALLEL=
80 cd /
81
82 check_kernel()
83 {
84         if ! test -d /proc/vz ; then
85                 fail
86                 print_warning "Running kernel is not OpenVZ kernel."
87                 exit 1
88         fi
89 }
90
91 get_kernel_version()
92 {
93         [ ! -z "$KERNEL_MAJOR" ] && return
94
95         local ver=$(uname -r)
96         local kernel=$(echo $ver | sed s/[-+].*//)
97         KERNEL_MAJOR=$(echo $kernel | awk -F . '{print $1}')
98         KERNEL_MINOR=$(echo $kernel | awk -F . '{print $2}')
99         KERNEL_PATCHLEVEL=$(echo $kernel | awk -F . '{print $3}')
100 }
101
102 check_kernel_config()
103 {
104         test -r /proc/config.gz || return 0
105
106         local conf opt err=0
107         local opt_must="SIM_FS VE VE_CALLS VZ_GENCALLS"
108         get_kernel_version
109         # For kernels >= 2.6.9 VZ_DEV must be set.
110         test "${KERNEL_MINOR}" -ge 6 &&
111                 test "${KERNEL_PATCHLEVEL}" -gt 9 &&
112                         opt_must="${opt_must} VZ_DEV"
113 #       local opt_rec="SCHED_VCPU FAIRSCHED VZ_QUOTA VZ_QUOTA_UGID VE_NETDEV VE_ETHDEV
114 #                       VE_IPTABLES VZ_CHECKPOINT VZ_WDOG"
115
116         conf="`zcat /proc/config.gz 2>/dev/null | grep -E -v '^#|^$'`"
117
118         for opt in $opt_must; do
119                 if ! echo "$conf" 2>/dev/null | grep -q "$opt="; then
120                         show "ERROR: Missing kernel config option: CONFIG_$opt"
121                         err=1
122                 fi
123         done
124         if [ $err != 0 ]; then
125                 fail
126                 print_warning "Please recompile your kernel."
127                 exit 1
128         fi
129 }
130
131 get_parallel()
132 {
133         [ -n "${PARALLEL}" ] && return
134         PARALLEL=`awk '
135 BEGIN { num=0; }
136 $1 == "processor" { num++; }
137 END { print num * 4; }' /proc/cpuinfo`
138 }
139
140 get_veinfo()
141 {
142         if [ -f /proc/vz/veinfo ]; then
143                 VEINFO=/proc/vz/veinfo
144         elif [ -f /proc/veinfo ]; then
145                 VEINFO=/proc/veinfo
146         elif [ ! -f $VESTAT ]; then
147                 return 1
148         fi
149         return 0
150 }
151
152 is_running()
153 {
154         get_veinfo || return 1
155         [ -f $SUBSYS_VZ ] || return 1
156 }
157
158 status()
159 {
160         check_kernel
161
162         if is_running; then
163                 nls "OpenVZ is running..."
164                 return 0
165         else
166                 nls "OpenVZ is stopped."
167                 return 3
168         fi
169 }
170
171 start_net()
172 {
173         local mod
174
175         # load all kernel modules needed for containers networking
176         for mod in ${NET_MODULES}; do
177                 modprobe ${mod} 2>/dev/null
178         done
179
180         if ip addr list | grep -q "venet0:.*UP" 2>/dev/null; then
181                 return 0
182         fi
183
184         get_veinfo
185         if [ -z "$VEINFO" ]; then
186                 return 0
187         fi
188         show "Bringing up interface $VZDEV"
189         busy
190         ok
191         ip link set $VZDEV up
192
193         ip addr add 0.0.0.0/0 dev $VZDEV
194         if [ "${IPV6}" = "yes" ]; then
195                 ip -6 addr add fe80::1/128 dev $VZDEV
196         fi
197         sysctl -q -w net.ipv4.conf.$VZDEV.send_redirects=0
198         if [ "$(sysctl -n -e net.ipv4.ip_forward)" != "1" ]; then
199                 print_warning "Warning ! IP forwarding is not enabled !"
200         fi
201 }
202
203 stop_net()
204 {
205         local mod
206
207         if ip addr list | grep -q "venet0:.*UP" 2>/dev/null; then
208                 show "Bringing down interface $VZDEV"
209                 ip link set $VZDEV down
210                 print_result
211         fi
212         for mod in ${NET_MODULES}; do
213                 /sbin/modprobe -r ${mod} > /dev/null 2>&1
214         done
215 }
216
217 setup_ve0()
218 {
219         if test -z "${VE0CPUUNITS}"; then
220                 echo "Warning: VE0CPUUNITS is not set in ${VZCONF}; using value of 1000"
221                 VE0CPUUNITS=1000
222         fi
223         msg=`${VZCTL} set 0 --cpuunits ${VE0CPUUNITS} 2>&1`
224         if [ $? -ne 0 ]; then
225                 fail
226                 print_warning "vzctl set 0 --cpuunits ${VE0CPUUNITS} failed: $msg"
227         fi
228
229         if ! test -f "${CONFIG_DIR}/0.conf"; then
230                 return
231         fi
232         if ! grep -q '^ONBOOT=yes\|^ONBOOT=\"yes\"' ${CONFIG_DIR}/0.conf;
233         then
234                 return
235         fi
236         show "Configure node UB resources: "
237         msg=`$VZCTL set 0 --reset_ub 2>&1`
238         print_result "$msg"
239 }
240
241 start_ves()
242 {
243         local veid
244         local velist
245         local msg
246         local need_restart
247
248         need_restart=""
249         velist=$(vzlist -aH -octid,onboot -s-bootorder |
250                 awk '$2 == "yes" {print $1}')
251         sysctl -q -w net.ipv4.route.src_check=0
252         for veid in $velist; do
253                 [ "${veid}" = "0" ] && continue
254                 show "Starting CT ${veid}"
255                 if [ "x${VZFASTBOOT}" = "xyes" -a "x${DISK_QUOTA}" = "xyes" ];
256                 then
257                         $VZQUOTA stat ${veid} >/dev/null 2>&1
258                         if [ $? -eq 6 ]; then
259                                 if $VZQUOTA show ${veid} 2>&1 | grep "vzquota : (warning) Quota is running" >/dev/null 2>&1; then
260                                         $VZQUOTA on ${veid} --nocheck >/dev/null 2>&1
261                                         need_restart="${need_restart} ${veid}"
262                                 fi
263                         fi
264                 fi
265                 msg=`$VZCTL start ${veid} 2>&1`
266                 print_result "$msg"
267         done 
268         for veid in ${need_restart}; do
269                 msg_stopping "CT ${veid}: "
270                 busy
271                 ok
272                 $VZCTL stop ${veid} 2>&1 >/dev/null 2>&1
273                 print_result
274                 msg_starting "CT ${veid}: "
275                 busy
276                 ok
277                 msg=`$VZCTL start ${veid} 2>&1`
278                 print_result 
279         done
280 }
281
282 stop_ves()
283 {
284         local veid
285         local velist
286         local msg
287         local m
288         local mounts
289         local fail
290         local iter
291         local quota
292         local pids
293
294         if get_veinfo; then
295                 get_parallel
296                 for i in 0 1 2; do
297                         iter=0;
298                         pids=
299                         velist=`awk '$1 != "VEID" && $1 != "Version:" {print $1}' ${VESTAT}`
300                         for veid in $velist; do
301                                 msg_stopping "CT $veid"
302                                 busy
303                                 echo
304                                 # Set fairsched parameters to maximum so
305                                 # CT will stop fast
306                                 $VZCTL set $veid --cpuunits 2000 --cpulimit 0 >/dev/null 2>&1
307                                 $VZCTL --skiplock stop $veid >/dev/null 2>&1 &
308                                 pids="$pids $!"
309                                 iter=$(($iter+1))
310                                 if [ ${iter} -gt ${PARALLEL} ]; then
311                                         for pid in ${pids}; do
312                                                 wait ${pid}
313                                         done
314                                         pids=
315                                         iter=0
316                                 fi
317                         done
318                         for pid in $pids; do
319                                 wait $pid
320                         done
321                 done
322         fi
323         iter=0
324         fail=1
325         while test $iter -lt 5 -a $fail -ne 0; do
326                 fail=0
327                 mounts=`awk '{if ($3=="simfs") print $2}' /proc/mounts`
328                 for m in $mounts; do
329                         show "Unmounting CT area "
330                         echo -n $m
331                         msg=`umount $m 2>&1`
332                         if [ $? -eq 0 ]; then
333                                 ok
334                         else
335                                 fail
336                                 print_warning "$msg"
337                                 fail=$((fail+1))
338                                 fuser -k -m ${m} > /dev/null 2>&1
339                         fi
340                 done
341                 iter=$(($iter+1))
342         done
343         # turn quota off
344         quota=`awk -F: '/^[0-9]+:/{print $1}' /proc/vz/vzquota 2>/dev/null`
345         for m in ${quota}; do
346                 show "Turn quota off for CT "
347                 echo -n $m
348                 msg=`vzquota off ${m} 2>&1`
349                 print_result "$msg"
350         done
351 }
352
353 lockfile()
354 {
355         local TEMPFILE="${1}.$$"
356         local LOCKFILE="${1}"
357
358         trap -- "rm -f ${LOCKFILE} ${TEMPFILE}" EXIT
359
360         echo $$ > ${TEMPFILE} 2> /dev/null || {
361                 echo "Can't write to ${TEMPFILE}"
362         }
363         ln ${TEMPFILE} ${LOCKFILE} >/dev/null 2>&1 && {
364                 rm -f ${TEMPFILE};
365                 return 0;
366         }
367         kill -0 `cat $LOCKFILE` >/dev/null 2>&1 && {
368                 return 1;
369         }
370         ln ${TEMPFILE} ${LOCKFILE} >/dev/null 2>&1 && {
371                 rm -f ${TEMPFILE};
372                 return 0;
373         }
374         rm -f ${LOCKFILE}
375         echo $$ > ${LOCKFILE}
376         return 0
377 }
378
379 start()
380 {
381         local veid
382         local velist
383         local msg
384         local mod
385
386         check_kernel
387         check_kernel_config
388
389         if ! lockfile $LOCKFILE; then
390                 show "OpenVZ is locked"
391                 fail
392                 return 1
393         fi
394         if [ -f ${SUBSYS_VZ} ]; then
395                 nls "OpenVZ already running"
396                 return 1
397         fi
398         msg_starting "OpenVZ"
399         if [ "$?" = "0" ]; then
400                 ok
401         else
402                 fail
403         fi
404         load_modules "${IPT_MODULES}"
405         for mod in $PRELOAD_MODULES; do
406                 /sbin/modprobe -r $mod >/dev/null 2>&1
407                 /sbin/modprobe $mod >/dev/null 2>&1
408         done
409         for mod in $MODULES; do
410                 /sbin/modprobe $mod >/dev/null 2>&1
411                 RETVAL=$?
412                 if [ $RETVAL -ne 0 ]; then
413                         fail
414                         print_warning "failed to load module ${mod}"
415                         return $RETVAL
416                 fi
417         done
418         load_modules "${MODULES_OTHER} ${VZFS_MODULES}"
419         show "loading OpenVZ modules"
420         ok
421
422         if [ ! -e /dev/vzctl ]; then
423                 # On most modern distros udev will create a device for you,
424                 # while on the old distros /dev/vzctl comes with vzctl rpm.
425                 # So the below mknod call is probably not needed at all.
426                 /bin/mknod -m 600 /dev/vzctl c 126 0 > /dev/null 2>&1
427                 RETVAL=$?
428                 if [ $RETVAL -ne 0 ]; then
429                         fail
430                         print_warning "creating /dev/vzctl"
431                         return $RETVAL
432                 fi
433         fi
434
435         start_net
436         setup_ve0
437         start_ves
438
439         rm -f $LOCKFILE
440         touch $SUBSYS_VZ
441 }
442
443 stop()
444 {
445         local mod
446
447         # Avoid stop action inside a CT, check we are in CT0
448         if ! egrep -q '^[[:space:]]*0:[[:space:]]' \
449                         /proc/user_beancounters; then
450                 print_failure "Looks like we are inside a container!"
451                 RETVAL=1
452                 return 1
453         fi
454
455         if ! lockfile $LOCKFILE; then
456                 show "OpenVZ is locked"
457                 fail
458                 RETVAL=1
459                 return 1
460         fi
461
462         stop_ves
463         stop_net
464         msg_stopping "OpenVZ"
465         for mod in ${MODULES_OTHER} ${MODULES} ${PRELOAD_MODULES} ${IPT_MODULES} ${VZFS_MODULES}; do
466                 /sbin/modprobe -r ${mod} > /dev/null 2>&1
467         done
468         rm -f $LOCKFILE
469         rm -f $SUBSYS_VZ
470         print_result
471 }
472
473 load_modules()
474 {
475         local modules=$1
476         local mod
477
478         for mod in ${modules}; do
479                 if /sbin/lsmod | grep -qw ${mod}; then
480                         continue
481                 fi
482                 /sbin/modprobe ${mod} >/dev/null 2>&1
483         done
484 }
485
486 # See how we were called.
487 case "$1" in
488   start)
489         start
490         ;;
491   stop)
492         stop
493         ;;
494   restart|force-reload)
495         stop
496         start
497         ;;
498   status)
499         status
500         RETVAL=$?
501         ;;
502   *)
503         echo "Usage: $0 {start|stop|status|restart|force-reload}"
504         exit 1
505 esac
506
507 exit $RETVAL
This page took 0.618849 seconds and 4 git commands to generate.