]>
Commit | Line | Data |
---|---|---|
43bb5f82 BP |
1 | # This is a shell function library sourced by some Open vSwitch scripts. |
2 | # It is not intended to be invoked on its own. | |
3 | ||
e0edde6f | 4 | # Copyright (C) 2009, 2010, 2011, 2012 Nicira, Inc. |
43bb5f82 BP |
5 | # |
6 | # Licensed under the Apache License, Version 2.0 (the "License"); | |
7 | # you may not use this file except in compliance with the License. | |
8 | # You may obtain a copy of the License at: | |
9 | # | |
10 | # http://www.apache.org/licenses/LICENSE-2.0 | |
11 | # | |
12 | # Unless required by applicable law or agreed to in writing, software | |
13 | # distributed under the License is distributed on an "AS IS" BASIS, | |
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
15 | # See the License for the specific language governing permissions and | |
16 | # limitations under the License. | |
17 | ||
18 | ## ----------------- ## | |
19 | ## configure options ## | |
20 | ## ----------------- ## | |
21 | ||
22 | # All of these should be substituted by the Makefile at build time. | |
23 | logdir=${OVS_LOGDIR-'@LOGDIR@'} # /var/log/openvswitch | |
24 | rundir=${OVS_RUNDIR-'@RUNDIR@'} # /var/run/openvswitch | |
25 | sysconfdir=${OVS_SYSCONFDIR-'@sysconfdir@'} # /etc | |
26 | etcdir=$sysconfdir/openvswitch # /etc/openvswitch | |
27 | datadir=${OVS_PKGDATADIR-'@pkgdatadir@'} # /usr/share/openvswitch | |
28 | bindir=${OVS_BINDIR-'@bindir@'} # /usr/bin | |
29 | sbindir=${OVS_SBINDIR-'@sbindir@'} # /usr/sbin | |
30 | ||
c3bf5498 BP |
31 | # /etc/openvswitch or /var/lib/openvswitch |
32 | if test X"$OVS_DBDIR" != X; then | |
33 | dbdir=$OVS_DBDIR | |
34 | elif test X"$OVS_SYSCONFDIR" != X; then | |
35 | dbdir=$OVS_SYSCONFDIR/openvswitch | |
36 | else | |
37 | dbdir='@DBDIR@' | |
38 | fi | |
39 | ||
19cbf2b8 GS |
40 | ovs_ctl_log () { |
41 | echo "$@" >> "${logdir}/ovs-ctl.log" | |
42 | } | |
43 | ||
46528f78 | 44 | ovs_ctl () { |
ed87900d GS |
45 | case "$@" in |
46 | *"=strace"*) | |
47 | # In case of running the daemon with strace, piping the o/p causes | |
48 | # the script to block (strace probably does not close the inherited | |
49 | # pipe). So, do not log the o/p to ovs-ctl.log. | |
50 | "${datadir}/scripts/ovs-ctl" "$@" | |
51 | ;; | |
3b8ba174 GS |
52 | "status") |
53 | # In case of the command 'status', we should return the exit status | |
54 | # of ovs-ctl. It is also useful to document the o/p in ovs-ctl.log. | |
55 | display=`"${datadir}/scripts/ovs-ctl" "$@" 2>&1` | |
56 | rc=$? | |
691e4755 FL |
57 | if test -w "${logdir}/ovs-ctl.log"; then |
58 | echo "${display}" | tee -a "${logdir}/ovs-ctl.log" | |
59 | else | |
60 | echo "${display}" | |
61 | fi | |
3b8ba174 GS |
62 | return ${rc} |
63 | ;; | |
ed87900d GS |
64 | *) |
65 | echo "`date -u`:$@" >> "${logdir}/ovs-ctl.log" | |
a34779bc | 66 | "${datadir}/scripts/ovs-ctl" "$@" 2>&1 | tee -a "${logdir}/ovs-ctl.log" |
ed87900d GS |
67 | ;; |
68 | esac | |
46528f78 GS |
69 | } |
70 | ||
43bb5f82 | 71 | VERSION='@VERSION@' |
43bb5f82 | 72 | |
5824c938 BP |
73 | DAEMON_CWD=/ |
74 | ||
43bb5f82 BP |
75 | LC_ALL=C; export LC_ALL |
76 | ||
77 | ## ------------- ## | |
78 | ## LSB functions ## | |
79 | ## ------------- ## | |
80 | ||
81 | # Use the system's own implementations if it has any. | |
82 | if test -e /etc/init.d/functions; then | |
83 | . /etc/init.d/functions | |
84 | elif test -e /etc/rc.d/init.d/functions; then | |
85 | . /etc/rc.d/init.d/functions | |
86 | elif test -e /lib/lsb/init-functions; then | |
87 | . /lib/lsb/init-functions | |
88 | fi | |
89 | ||
90 | # Implement missing functions (e.g. OpenSUSE lacks 'action'). | |
91 | if type log_success_msg >/dev/null 2>&1; then :; else | |
92 | log_success_msg () { | |
93 | printf '%s.\n' "$*" | |
94 | } | |
95 | fi | |
96 | if type log_failure_msg >/dev/null 2>&1; then :; else | |
97 | log_failure_msg () { | |
98 | printf '%s ... failed!\n' "$*" | |
99 | } | |
100 | fi | |
101 | if type log_warning_msg >/dev/null 2>&1; then :; else | |
102 | log_warning_msg () { | |
103 | printf '%s ... (warning).\n' "$*" | |
104 | } | |
105 | fi | |
106 | if type action >/dev/null 2>&1; then :; else | |
107 | action () { | |
108 | STRING=$1 | |
109 | shift | |
110 | "$@" | |
111 | rc=$? | |
112 | if test $rc = 0; then | |
113 | log_success_msg "$STRING" | |
114 | else | |
115 | log_failure_msg "$STRING" | |
116 | fi | |
117 | return $rc | |
118 | } | |
119 | fi | |
120 | ||
121 | ## ------- ## | |
122 | ## Daemons ## | |
123 | ## ------- ## | |
124 | ||
3028ce25 BP |
125 | pid_exists () { |
126 | # This is better than "kill -0" because it doesn't require permission to | |
127 | # send a signal (so daemon_status in particular works as non-root). | |
128 | test -d /proc/"$1" | |
129 | } | |
130 | ||
1f3f3f0a CL |
131 | pid_comm_check () { |
132 | [ "$1" = "`cat /proc/$2/comm`" ] | |
133 | } | |
134 | ||
43bb5f82 BP |
135 | start_daemon () { |
136 | priority=$1 | |
d0c06099 BP |
137 | wrapper=$2 |
138 | shift; shift | |
43bb5f82 | 139 | daemon=$1 |
e78eed56 | 140 | strace="" |
43bb5f82 BP |
141 | |
142 | # drop core files in a sensible place | |
143 | test -d "$DAEMON_CWD" || install -d -m 755 -o root -g root "$DAEMON_CWD" | |
144 | set "$@" --no-chdir | |
145 | cd "$DAEMON_CWD" | |
146 | ||
147 | # log file | |
148 | test -d "$logdir" || install -d -m 755 -o root -g root "$logdir" | |
149 | set "$@" --log-file="$logdir/$daemon.log" | |
150 | ||
151 | # pidfile and monitoring | |
152 | test -d "$rundir" || install -d -m 755 -o root -g root "$rundir" | |
153 | set "$@" --pidfile="$rundir/$daemon.pid" | |
154 | set "$@" --detach --monitor | |
155 | ||
d0c06099 BP |
156 | # wrapper |
157 | case $wrapper in | |
158 | valgrind) | |
159 | if (valgrind --version) > /dev/null 2>&1; then | |
287e3bc0 | 160 | set valgrind -q --leak-check=full --time-stamp=yes \ |
d0c06099 BP |
161 | --log-file="$logdir/$daemon.valgrind.log.%p" "$@" |
162 | else | |
163 | log_failure_msg "valgrind not installed, running $daemon without it" | |
164 | fi | |
165 | ;; | |
166 | strace) | |
167 | if (strace -V) > /dev/null 2>&1; then | |
e78eed56 EJ |
168 | strace="strace -tt -T -s 256 -ff" |
169 | if (strace -DV) > /dev/null 2>&1; then | |
170 | # Has the -D option. | |
171 | set $strace -D -o "$logdir/$daemon.strace.log" "$@" | |
172 | strace="" | |
173 | fi | |
d0c06099 BP |
174 | else |
175 | log_failure_msg "strace not installed, running $daemon without it" | |
176 | fi | |
177 | ;; | |
37368939 BP |
178 | glibc) |
179 | set env MALLOC_CHECK_=2 MALLOC_PERTURB_=165 "$@" | |
180 | ;; | |
d0c06099 BP |
181 | '') |
182 | ;; | |
183 | *) | |
184 | log_failure_msg "unknown wrapper $wrapper, running $daemon without it" | |
185 | ;; | |
186 | esac | |
187 | ||
43bb5f82 BP |
188 | # priority |
189 | if test X"$priority" != X; then | |
190 | set nice -n "$priority" "$@" | |
191 | fi | |
192 | ||
193 | action "Starting $daemon" "$@" | |
e78eed56 EJ |
194 | |
195 | if test X"$strace" != X; then | |
196 | # Strace doesn't have the -D option so we attach after the fact. | |
197 | setsid $strace -o "$logdir/$daemon.strace.log" \ | |
198 | -p `cat $rundir/$daemon.pid` > /dev/null 2>&1 & | |
199 | fi | |
43bb5f82 BP |
200 | } |
201 | ||
43bb5f82 BP |
202 | stop_daemon () { |
203 | if test -e "$rundir/$1.pid"; then | |
204 | if pid=`cat "$rundir/$1.pid"`; then | |
89bc5283 GS |
205 | for action in TERM .1 .25 .65 1 1 1 1 KILL 1 1 1 2 10 15 30 FAIL; do |
206 | if pid_exists "$pid" >/dev/null 2>&1; then :; else | |
207 | return 0 | |
208 | fi | |
43bb5f82 BP |
209 | case $action in |
210 | TERM) | |
211 | action "Killing $1 ($pid)" kill $pid | |
212 | ;; | |
213 | KILL) | |
214 | action "Killing $1 ($pid) with SIGKILL" kill -9 $pid | |
215 | ;; | |
216 | FAIL) | |
217 | log_failure_msg "Killing $1 ($pid) failed" | |
218 | return 1 | |
219 | ;; | |
220 | *) | |
89bc5283 | 221 | sleep $action |
43bb5f82 BP |
222 | ;; |
223 | esac | |
224 | done | |
225 | fi | |
226 | fi | |
227 | log_success_msg "$1 is not running" | |
228 | } | |
229 | ||
230 | daemon_status () { | |
231 | pidfile=$rundir/$1.pid | |
232 | if test -e "$pidfile"; then | |
233 | if pid=`cat "$pidfile"`; then | |
3028ce25 | 234 | if pid_exists "$pid"; then |
43bb5f82 BP |
235 | echo "$1 is running with pid $pid" |
236 | return 0 | |
237 | else | |
238 | echo "Pidfile for $1 ($pidfile) is stale" | |
239 | fi | |
240 | else | |
241 | echo "Pidfile for $1 ($pidfile) exists but cannot be read" | |
242 | fi | |
243 | else | |
244 | echo "$1 is not running" | |
245 | fi | |
246 | return 1 | |
247 | } | |
248 | ||
249 | daemon_is_running () { | |
250 | pidfile=$rundir/$1.pid | |
1f3f3f0a | 251 | test -e "$pidfile" && pid=`cat "$pidfile"` && pid_exists "$pid" && pid_comm_check $1 $pid |
43bb5f82 | 252 | } >/dev/null 2>&1 |
7a62e5cc | 253 | |
a1d5e459 GS |
254 | # Prints commands needed to move the ip address from interface $1 to interface |
255 | # $2 | |
256 | move_ip_address () { | |
257 | if [ -z "$1" ] || [ -z "$2" ]; then | |
258 | return | |
259 | fi | |
7a62e5cc | 260 | dev="$1" |
a1d5e459 | 261 | dst="$2" |
7a62e5cc GS |
262 | |
263 | # IP addresses (including IPv6). | |
264 | echo "ip addr flush dev $dev 2>/dev/null" # Suppresses "Nothing to flush". | |
265 | ip addr show dev $dev | while read addr; do | |
266 | set -- $addr | |
267 | ||
268 | # Check and trim family. | |
269 | family=$1 | |
270 | shift | |
271 | case $family in | |
272 | inet | inet6) ;; | |
273 | *) continue ;; | |
274 | esac | |
275 | ||
276 | # Trim device off the end--"ip" insists on having "dev" precede it. | |
277 | addrcmd= | |
278 | while test $# != 0; do | |
279 | case $1 in | |
280 | dynamic) | |
281 | # Omit kernel-maintained route. | |
282 | continue 2 | |
283 | ;; | |
284 | scope) | |
285 | if test "$2" = link -a "$family" != inet6; then | |
286 | # Omit route derived from IP address, e.g. | |
287 | # 172.16.0.0/16 derived from 172.16.12.34, | |
288 | # but preserve IPv6 link-local address. | |
289 | continue 2 | |
290 | fi | |
291 | ;; | |
292 | "$dev"|"$dev:"*) | |
293 | # Address label string | |
a1d5e459 GS |
294 | label=`echo $1 | sed "s/$dev/$dst/"` |
295 | addrcmd="$addrcmd label $label" | |
7a62e5cc GS |
296 | shift |
297 | continue | |
298 | ;; | |
299 | esac | |
300 | addrcmd="$addrcmd $1" | |
301 | shift | |
302 | done | |
303 | if test "$1" != "$dev"; then | |
304 | addrcmd="$addrcmd $1" | |
305 | fi | |
306 | ||
a1d5e459 | 307 | echo ip -f $family addr add $addrcmd dev $dst |
7a62e5cc GS |
308 | done |
309 | } | |
310 | ||
a1d5e459 GS |
311 | # Prints commands needed to move the ip route of interface $1 to interface $2 |
312 | move_ip_routes () { | |
313 | if [ -z "$1" ] || [ -z "$2" ]; then | |
314 | return | |
315 | fi | |
7a62e5cc | 316 | dev="$1" |
a1d5e459 | 317 | dst="$2" |
7a62e5cc GS |
318 | echo "ip route flush dev $dev proto boot 2>/dev/null" # Suppresses "Nothing to flush". |
319 | ip route show dev $dev | while read route; do | |
320 | # "proto kernel" routes are installed by the kernel automatically. | |
321 | case $route in | |
322 | *" proto kernel "*) continue ;; | |
323 | esac | |
324 | ||
a1d5e459 | 325 | echo "ip route add $route dev $dst" |
7a62e5cc GS |
326 | done |
327 | } |