]>
Commit | Line | Data |
---|---|---|
ab19dac7 | 1 | #!/bin/bash |
60045090 DB |
2 | # |
3 | # stap-server script for managing the systemtap compile server | |
ab19dac7 | 4 | # |
5ac7fee9 | 5 | # Copyright (C) 2008-2011 Red Hat Inc. |
ab19dac7 DB |
6 | # |
7 | # This file is part of systemtap, and is free software. You can | |
8 | # redistribute it and/or modify it under the terms of the GNU General | |
9 | # Public License (GPL); either version 2, or (at your option) any | |
10 | # later version. | |
60045090 DB |
11 | # |
12 | # This script provides management of systemtap compile servers as a service. | |
13 | # See stap-server(8) for more information. | |
ab19dac7 | 14 | |
5ac7fee9 DB |
15 | if [ -f /etc/rc.d/init.d/functions ]; then |
16 | # Red Hat init functions | |
17 | . /etc/rc.d/init.d/functions | |
18 | else | |
19 | # Default init functions | |
20 | success () { | |
21 | echo -n "OK" | |
22 | } | |
23 | failure () { | |
24 | echo -n "FAILED" | |
25 | } | |
26 | fi | |
0e47827d | 27 | |
60045090 | 28 | # Systemtap function library |
961588fd | 29 | . ${PKGLIBEXECDIR}stap-env |
98f552c2 | 30 | |
60045090 DB |
31 | prog=stap-server |
32 | ||
33 | # Commands | |
34 | STAP_START_SERVER=${stap_pkglibexecdir}stap-start-server | |
35 | STAP_STOP_SERVER=${stap_pkglibexecdir}stap-stop-server | |
36 | UNAME=/bin/uname | |
37 | ||
38 | # Default Global Configuration | |
39 | CONFIG_FILE=$stap_sysconfdir/sysconfig/stap-server | |
40 | CONFIG_PATH=$stap_sysconfdir/stap-server/conf.d | |
41 | STAT_PATH=$stap_localstatedir/run/stap-server | |
2648a9b4 | 42 | LOG_FILE=$stap_localstatedir/log/stap-server/log |
60045090 DB |
43 | |
44 | # Default option settings | |
45 | # Optional global config file | |
46 | OPT_CONFIG_FILE= | |
71a522b5 | 47 | OPT_OTHER= |
60045090 DB |
48 | |
49 | echo_usage () { | |
50 | echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|status} [options]" | |
51 | echo $"Options:" | |
52 | echo $" -c configfile : specify additional global configuration file." | |
53 | echo $" -a arch : specify the target architecture." | |
54 | echo $" -r release : specify the kernel release." | |
55 | echo $" -I path : augment the search path for tapsets." | |
56 | echo $" -R path : specify the location of the systemtap runtime." | |
57 | echo $" -B options : specify 'make' options for building systemtap modules." | |
58 | echo $" -u username : specify the user who will run the server(s)." | |
59 | echo $" -i : specify a server for each installed kernel release." | |
60 | echo $" -n nickname : specify a server configuration by nickname." | |
61 | echo $" -p pid : specify a server or server configuration by process id." | |
71a522b5 | 62 | echo $" -k : keep server temporary files." |
60045090 DB |
63 | echo $"" |
64 | echo $"All options, may be specified more than once." | |
65 | echo $"" | |
66 | echo $"If -a is not specified, the default architecture is that of the host" | |
67 | echo $"platform." | |
68 | echo $"" | |
69 | echo $"If -r is not specified, the default kernel release is that currently" | |
70 | echo $"running on the host platform." | |
71 | echo $"" | |
72 | echo $"If -u is not specified, the default user is 'stap-server'" | |
73 | echo $"" | |
74 | echo $"Each -I and -B option specifies an additional path or option" | |
75 | echo $"respectively. For other options, each new instance overrides the" | |
76 | echo $"previous setting." | |
77 | echo $"" | |
78 | echo $"The -i option is a shortcut which specifies one server for each kernel" | |
79 | echo $"release installed in /lib/modules/. Previous -I, -R, -B and -u" | |
80 | echo $"options will be applied to each server, however previous -a options" | |
81 | echo $"are ignored and the default architecture is used." | |
82 | echo $"" | |
83 | echo $"The -n option allows the specification of a server configuration by" | |
84 | echo $"nickname. When -n is specified, a currently running server with the" | |
85 | echo $"given nickname will be searched for. If no currently running server" | |
86 | echo $"with the given nickname is found, a server configuration with the" | |
71a522b5 DB |
87 | echo $"given nickname will be searched for in" |
88 | echo $"$stap_sysconfdir/stap-server/conf.d/*.conf." | |
60045090 DB |
89 | echo $"If a server configuration for the given nickname is found, the -a, -r," |
90 | echo $"-I, -R, -B and -u options for that server will be used as if they were" | |
91 | echo $"specified on the command line. If no configuration with the given" | |
92 | echo $"nickname is found, and the action is 'start' (or an action behaving" | |
93 | echo $"like 'start' (see below), the server will be started with the given" | |
94 | echo $"nickname. If no configuration with the given nickname is found, and" | |
95 | echo $"the action is not 'start' (or an action behaving" "like 'start'," | |
96 | echo $"it is an error. If a nickname is not specified for a server, its" | |
97 | echo $"nickname will be its process id." | |
98 | echo $"" | |
99 | echo $"The -p option allows the specification of a server configuration by" | |
100 | echo $"process id. When -p is specified, a currently running server with the" | |
101 | echo $"given process id will be searched for. If no such server is found," | |
102 | echo $"it is an error. If a server with the given pid is found, the -a, -r," | |
103 | echo $"-I, -R, -B and -u options for that server will be used as if they were" | |
104 | echo $"specified on the command line." | |
105 | echo $"" | |
71a522b5 DB |
106 | echo $"The -k option tells the server to keep the temporary directories it creates" |
107 | echo $"during each transaction with a client." | |
108 | echo $"" | |
60045090 DB |
109 | echo $"The specified action is performed for the server(s) specified on the" |
110 | echo $"command line. If no servers are specified on the command line, the" | |
111 | echo $"behavior is as follows:" | |
112 | echo $"" | |
113 | echo $" start: Start the servers configured in $stap_sysconfdir/stap-server/conf.d/*.conf." | |
114 | echo $" If none are configured, start a server for the kernel release" | |
115 | echo $" and architecture of the host platform." | |
116 | echo $"" | |
117 | echo $" stop: Stop all currently running servers." | |
118 | echo $"" | |
119 | echo $" restart: Restart all currently running servers. If no servers are running," | |
120 | echo $" behave as if 'start' was specified." | |
121 | echo $"" | |
122 | echo $" condrestart: Restart all currently running servers. If no servers are running," | |
123 | echo $" do nothing." | |
124 | echo $"" | |
125 | echo $" try-restart: Same as condrestart." | |
126 | echo $"" | |
127 | echo $" force-reload: Stop all currently running servers and behave as if 'start'" | |
128 | echo $" was specified." | |
129 | echo $"" | |
130 | echo $" status: Report the status of all current running servers." | |
131 | echo $"" | |
132 | } | |
ab19dac7 | 133 | |
60045090 DB |
134 | #----------------------------------------------------------------- |
135 | # Helper functions | |
136 | #----------------------------------------------------------------- | |
137 | log () { # message | |
138 | echo `LC_ALL=en date +"%b %e %T"`": $1" >> "$LOG_FILE" | |
139 | } | |
140 | clog () { # message [-n] | |
141 | echo $2 "$1" | |
142 | log "$1" | |
143 | } | |
144 | slog () { # message | |
145 | logger "$1" # if syslogd is running, this message will be sent to syslog. | |
146 | log "$1" | |
147 | } | |
148 | logex () { # command | |
c807ba1b | 149 | eval log \"Exec: "$@"\" |
60045090 DB |
150 | "$@" >> "$LOG_FILE" 2>&1 |
151 | return $? | |
152 | } | |
153 | do_failure () { # message | |
154 | slog "Error: $1" | |
155 | failure "$1" | |
156 | } | |
157 | do_success () { # message | |
158 | log "Pass: $1" | |
159 | success "$1" | |
160 | } | |
66e1a139 | 161 | |
60045090 DB |
162 | #------------------------------------------------------------------ |
163 | # Parameter parsing and setup options | |
164 | #------------------------------------------------------------------ | |
165 | parse_args () { # arguments | |
166 | local rc=0 | |
167 | while [ -n "$1" ]; do | |
168 | case "$1" in | |
71a522b5 DB |
169 | -k | -P) |
170 | OPT_OTHER="$OPT_OTHER $1" | |
171 | shift 1 | |
172 | ;; | |
60045090 | 173 | -a) |
c807ba1b | 174 | SERVER_CMDS+=("ARCH=\"`quote_for_cmd "$2"`\"") |
60045090 DB |
175 | shift 1 |
176 | ;; | |
177 | -B) | |
c807ba1b | 178 | SERVER_CMDS+=("BUILD+=(\"`quote_for_cmd "$2"`\")") |
60045090 DB |
179 | shift 1 |
180 | ;; | |
181 | -c) | |
c807ba1b | 182 | OPT_CONFIG_FILE="$2" |
60045090 DB |
183 | shift 1 |
184 | ;; | |
185 | -i) | |
186 | process_i | |
187 | ;; | |
188 | -I) | |
c807ba1b | 189 | SERVER_CMDS+=("INCLUDE+=(\"`quote_for_cmd "$2"`\")") |
60045090 DB |
190 | shift 1 |
191 | ;; | |
192 | -n) | |
c807ba1b | 193 | process_n "$2" |
60045090 DB |
194 | shift 1 |
195 | ;; | |
196 | -p) | |
c807ba1b | 197 | process_p "$2" |
60045090 DB |
198 | test $? = 0 || rc=1 |
199 | shift 1 | |
200 | ;; | |
201 | -r) | |
c807ba1b | 202 | process_r "$2" |
60045090 DB |
203 | test $? = 0 || rc=1 |
204 | shift 1 | |
205 | ;; | |
206 | -R) | |
c807ba1b | 207 | SERVER_CMDS+=("RUNTIME=\"`quote_for_cmd "$2"`\"") |
60045090 DB |
208 | shift 1 |
209 | ;; | |
210 | -u) | |
c807ba1b | 211 | SERVER_CMDS+=("USER=\"`quote_for_cmd "$2"`\"") |
60045090 DB |
212 | shift 1 |
213 | ;; | |
214 | --) | |
215 | ;; | |
216 | *) | |
217 | rc=1 | |
218 | ;; | |
219 | esac | |
220 | shift 1 | |
221 | done | |
222 | ||
223 | # Add an EXEC command to the end if any server options were specified | |
c807ba1b | 224 | test -n "$SERVER_CMDS" && SERVER_CMDS+=("EXEC") |
60045090 DB |
225 | |
226 | test $rc != 0 && echo_usage | |
227 | return $rc | |
228 | } | |
66e1a139 | 229 | |
60045090 DB |
230 | # Process the -i flag. |
231 | process_i () { | |
232 | cd /lib/modules | |
233 | local release | |
234 | for release in `ls`; do | |
c807ba1b | 235 | test -n "$SERVER_CMDS" && SERVER_CMDS+=("EXEC") |
60045090 DB |
236 | process_r $release |
237 | done | |
66e1a139 | 238 | |
60045090 | 239 | return 0 |
ab19dac7 DB |
240 | } |
241 | ||
60045090 DB |
242 | # Process the -n flag. |
243 | process_n () { | |
244 | local target_NICKNAME="$1" | |
245 | ||
246 | # Is there a running server with this nickname? | |
247 | local pid=`get_server_pid_by_nickname "$target_NICKNAME"` | |
248 | if [ -n "$pid" ]; then | |
249 | # Read the configuration and add it to the configuration commands. | |
c807ba1b DB |
250 | interpret_server_status "$STAT_PATH/$pid.stat" || continue |
251 | add_server_commands | |
60045090 DB |
252 | return |
253 | fi | |
254 | ||
255 | # Is there a server configuration with this nickname? | |
256 | for f in "$CONFIG_PATH"/*.conf; do | |
257 | if [ -f "$f" ]; then | |
c807ba1b | 258 | interpret_server_config "$f" || continue |
60045090 | 259 | test "X$NICKNAME" = "X$target_NICKNAME" || continue |
c807ba1b | 260 | add_server_commands |
60045090 DB |
261 | return |
262 | fi | |
263 | done | |
ab19dac7 | 264 | |
60045090 DB |
265 | # No server configuration could be found for this nickname. Add a |
266 | # NICKNAME_NOT_FOUND=... command to the configuration commands. | |
c807ba1b | 267 | SERVER_CMDS+=("NICKNAME_NOT_FOUND=\"`quote_for_cmd "$target_NICKNAME"`\"") |
60045090 DB |
268 | } |
269 | ||
270 | # Process the -p flag. | |
271 | process_p () { | |
272 | local pid="$1" | |
9e494cbb | 273 | |
60045090 | 274 | # Are we managing a server with the given pid? |
c807ba1b | 275 | test ! -f "$STAT_PATH/$pid.stat" && echo "No stap-server running as pid $pid" && \ |
60045090 | 276 | exit 1 |
9e494cbb | 277 | |
c807ba1b DB |
278 | # Add the configuration of the server running as $pid to SERVER_CMDS |
279 | interpret_server_status "$STAT_PATH/$pid.stat" || exit 1 | |
280 | add_server_commands | |
60045090 | 281 | return 0 |
66e1a139 | 282 | } |
ab19dac7 | 283 | |
60045090 DB |
284 | # Process the -r flag. |
285 | process_r () { | |
c807ba1b | 286 | local first_char="${1:1:1}" |
60045090 DB |
287 | |
288 | if test "$first_char" = "/"; then # fully specified path | |
c807ba1b | 289 | local kernel_build_tree="$1" |
60045090 DB |
290 | local version_file_name="$kernel_build_tree/include/config/kernel.release" |
291 | # The file include/config/kernel.release within the kernel | |
292 | # build tree is used to pull out the version information | |
293 | local kernel_release=`cat $version_file_name 2>/dev/null` | |
294 | if test "X$kernel_release" = "X"; then | |
295 | echo "Missing $version_file_name" | |
296 | return 1 | |
297 | fi | |
4f747a64 | 298 | SERVER_CMDS+=("RELEASE=\"`quote_for_cmd "$1"`\"") # pass the path as-is |
60045090 | 299 | return 0 |
66e1a139 | 300 | fi |
ab19dac7 | 301 | |
60045090 | 302 | # kernel release specified directly |
c807ba1b | 303 | SERVER_CMDS+=("RELEASE=\"`quote_for_cmd "$1"`\"") |
60045090 | 304 | return 0 |
ab19dac7 DB |
305 | } |
306 | ||
60045090 DB |
307 | load_config () { |
308 | # Include configs | |
309 | if [ -f "$CONFIG_FILE" ]; then | |
c807ba1b | 310 | interpret_config_file "$CONFIG_FILE" |
60045090 DB |
311 | fi |
312 | if [ -f "$OPT_CONFIG_FILE" ]; then | |
c807ba1b | 313 | interpret_config_file "$OPT_CONFIG_FILE" |
60045090 DB |
314 | fi |
315 | } | |
d5658775 | 316 | |
60045090 DB |
317 | # Default to the currently running kernel release |
318 | get_release () { | |
319 | $UNAME -r | |
320 | } | |
d5658775 | 321 | |
60045090 DB |
322 | # Default to the currently running kernel release |
323 | get_arch () { | |
324 | stap_get_arch | |
ab19dac7 DB |
325 | } |
326 | ||
c807ba1b DB |
327 | add_server_commands () { |
328 | # Add commands based on the current state to SERVER_CMDS | |
329 | SERVER_CMDS+=("ARCH=\"`quote_for_cmd "$ARCH"`\"") | |
330 | SERVER_CMDS+=("RELEASE=\"`quote_for_cmd "$RELEASE"`\"") | |
331 | SERVER_CMDS+=("RUNTIME=\"`quote_for_cmd "$RUNTIME"`\"") | |
332 | SERVER_CMDS+=("INCLUDE=()") | |
333 | for i in "${INCLUDE[@]}"; do | |
334 | SERVER_CMDS+=("INCLUDE+=(\"`quote_for_cmd "$i"`\")") | |
60045090 | 335 | done |
c807ba1b DB |
336 | SERVER_CMDS+=("BUILD=()") |
337 | for b in "${BUILD[@]}"; do | |
338 | SERVER_CMDS+=("BUILD+=(\"`quote_for_cmd "$b"`\")") | |
60045090 | 339 | done |
c807ba1b DB |
340 | SERVER_CMDS+=("USER=\"`quote_for_cmd "$USER"`\"") |
341 | SERVER_CMDS+=("NICKNAME=\"`quote_for_cmd "$NICKNAME"`\"") | |
60045090 | 342 | } |
8afee8bb | 343 | |
60045090 | 344 | echo_server_options () { |
c807ba1b DB |
345 | # Echo the current state. |
346 | echo -n "-a \"`quote_for_cmd "$ARCH"`\"" | |
347 | echo -n " -r \"`quote_for_cmd "$RELEASE"`\"" | |
348 | test -n "$RUNTIME" && echo -n " -R \"`quote_for_cmd "$RUNTIME"`\"" | |
349 | for i in "${INCLUDE[@]}"; do | |
350 | echo -n " -I \"`quote_for_cmd "$i"`\"" | |
60045090 | 351 | done |
c807ba1b DB |
352 | for b in "${BUILD[@]}"; do |
353 | echo -n " -B \"`quote_for_cmd "$b"`\"" | |
ab19dac7 | 354 | done |
56b3f5cf | 355 | echo -n " -u \"`quote_for_cmd "$USER"`\"" |
d0d71073 | 356 | test -n "$NICKNAME" && echo -n " -n \"`quote_for_cmd "$NICKNAME"`\"" |
60045090 | 357 | echo |
ab19dac7 DB |
358 | } |
359 | ||
60045090 DB |
360 | prepare_stat_dir () { |
361 | if [ ! -d "$STAT_PATH" ]; then | |
362 | logex mkdir -p "$STAT_PATH" | |
363 | [ $? -ne 0 ] && return 1 | |
364 | fi | |
365 | return 0 | |
ab19dac7 DB |
366 | } |
367 | ||
60045090 DB |
368 | prepare_log_dir () { |
369 | local log_path=`dirname "$LOG_FILE"` | |
370 | if [ ! -d "$log_path" ]; then | |
371 | mkdir -p "$log_path" | |
372 | [ $? -ne 0 ] && return 1 | |
373 | fi | |
374 | return 0 | |
ab19dac7 DB |
375 | } |
376 | ||
60045090 DB |
377 | init_server_opts () { |
378 | ARCH=`get_arch` | |
379 | RELEASE=`get_release` | |
c807ba1b DB |
380 | unset BUILD |
381 | unset INCLUDE | |
60045090 DB |
382 | NICKNAME= |
383 | NICKNAME_NOT_FOUND= | |
384 | RUNTIME= | |
385 | USER=$STAP_USER | |
56b3f5cf | 386 | test -z "$USER" && USER=`id -un` |
ab19dac7 DB |
387 | } |
388 | ||
c807ba1b DB |
389 | # Double quotes, backslashes within generated command |
390 | # arguments must be quoted. | |
391 | quote_for_cmd () { | |
392 | echo "$1" | \ | |
393 | sed -e 's/\\/\\\\/g' \ | |
394 | -e 's/"/\\"/g' | |
395 | } | |
396 | ||
397 | # Interpret the contents of a global config file. | |
398 | interpret_config_file () { | |
399 | local config_file="$1" | |
400 | ||
401 | # Save the results locally first, in case there is an error. | |
402 | local local_CONFIG_PATH= | |
403 | local local_STAT_PATH= | |
404 | local local_LOG_FILE= | |
405 | local local_STAP_USER= | |
406 | ||
407 | local input | |
408 | while read -r -u3 input | |
409 | do | |
410 | case "$input" in | |
411 | CONFIG_PATH=*) | |
412 | local_CONFIG_PATH="${input:12}" | |
413 | ;; | |
414 | STAT_PATH=*) | |
415 | local_STAT_PATH="${input:10}" | |
416 | ;; | |
417 | LOG_FILE=*) | |
418 | local_LOG_FILE="${input:9}" | |
419 | ;; | |
420 | STAP_USER=*) | |
421 | local_STAP_USER="${input:10}" | |
422 | ;; | |
423 | \#*) | |
424 | ;; # Comment, do nothing | |
425 | "") | |
426 | ;; # Empty line, do nothing | |
427 | *) | |
428 | echo $"Invalid input, \"$input\", in $config_file" >&2 | |
429 | exit 1 | |
430 | ;; | |
431 | esac | |
432 | done 3< "$config_file" | |
433 | ||
434 | # Now set the results globally | |
435 | test -n "$local_CONFIG_PATH" && CONFIG_PATH="$local_CONFIG_PATH" | |
436 | test -n "$local_STAT_PATH" && STAT_PATH="$local_STAT_PATH" | |
437 | test -n "$local_LOG_FILE" && LOG_FILE="$local_LOG_FILE" | |
438 | test -n "$local_STAP_USER" && STAP_USER="$local_STAP_USER" | |
439 | } | |
440 | ||
441 | # Interpret the contents of a server config file. | |
442 | interpret_server_config () { | |
443 | local config_file="$1" | |
444 | ||
445 | # Save the results locally first, in case there is an error. | |
446 | local local_ARCH= | |
447 | local local_RELEASE= | |
448 | local local_BUILD=() | |
449 | local local_INCLUDE=() | |
450 | local local_RUNTIME= | |
451 | local local_USER= | |
452 | local local_NICKNAME= | |
453 | ||
454 | local input | |
455 | while read -r -u3 input | |
456 | do | |
457 | case "$input" in | |
458 | ARCH=*) | |
459 | local_ARCH="${input:5}" | |
460 | ;; | |
461 | RELEASE=*) | |
462 | local_RELEASE="${input:8}" | |
463 | ;; | |
464 | BUILD=*) | |
465 | if [ -z "${input:6}" -o "${input:6}" = "()" ]; then | |
466 | local_BUILD=() | |
467 | else | |
468 | local_BUILD=("${input:6}") | |
469 | fi | |
470 | ;; | |
471 | BUILD+=*) | |
472 | test -z "${input:7}" -o "${input:7}" = "()" || \ | |
473 | local_BUILD+=("${input:7}") | |
474 | ;; | |
475 | INCLUDE=*) | |
476 | if [ -z "${input:8}" -o "${input:8}" = "()" ]; then | |
477 | local_INCLUDE=() | |
478 | else | |
479 | local_INCLUDE=("${input:8}") | |
480 | fi | |
481 | ;; | |
482 | INCLUDE+=*) | |
483 | test -z "${input:8}" -o "${input:8}" = "()" || \ | |
484 | local_INCLUDE+=("${input:9}") | |
485 | ;; | |
486 | RUNTIME=*) | |
487 | local_RUNTIME="${input:8}" | |
488 | ;; | |
489 | USER=*) | |
490 | local_USER="${input:5}" | |
491 | ;; | |
492 | NICKNAME=*) | |
493 | local_NICKNAME="${input:9}" | |
494 | ;; | |
495 | \#*) | |
496 | ;; # Comment, do nothing | |
497 | "") | |
498 | ;; # Empty line, do nothing | |
499 | *) | |
500 | echo $"Invalid input, \"$input\", in $config_file" >&2 | |
501 | exit 1 | |
502 | ;; | |
503 | esac | |
504 | done 3< "$config_file" | |
505 | ||
506 | # Now set the results globally. All variables are expected to be set, even | |
507 | # if to nothing. | |
508 | ARCH="$local_ARCH" | |
509 | RELEASE="$local_RELEASE" | |
510 | BUILD=("${local_BUILD[@]}") | |
511 | INCLUDE=("${local_INCLUDE[@]}") | |
512 | RUNTIME="$local_RUNTIME" | |
513 | USER="$local_USER" | |
514 | NICKNAME="$local_NICKNAME" | |
515 | } | |
516 | ||
517 | # Interpret the contents of a server status file. | |
518 | interpret_server_status () { | |
519 | # The contents of the server status files are currently the same as | |
520 | # that of server config files. | |
521 | interpret_server_config "$1" | |
522 | } | |
523 | ||
524 | # Load the default server config and add the results to SERVER_CMDS. | |
525 | load_server_config () { | |
526 | for f in "$CONFIG_PATH"/*.conf; do | |
527 | if [ -f "$f" ]; then | |
528 | # Obtain a configuration from each config file. | |
529 | # Ensure that we get the correct defaults for items not specified. | |
530 | local ARCH= | |
531 | local BUILD=() | |
532 | local INCLUDE=() | |
533 | local RUNTIME= | |
534 | local USER= | |
535 | local RELEASE= | |
536 | interpret_server_config "$f" || continue | |
537 | # Other options default to empty. These ones don't. | |
538 | [ -z "$ARCH" ] && ARCH=`get_arch` | |
539 | [ -z "$RELEASE" ] && RELEASE=`get_release` | |
540 | [ -z "$USER" ] && USER=$STAP_USER | |
56b3f5cf | 541 | [ -z "$USER" ] && USER=`id -un` |
c807ba1b DB |
542 | add_server_commands |
543 | SERVER_CMDS+=("EXEC") | |
544 | fi | |
545 | done | |
546 | } | |
547 | ||
60045090 DB |
548 | server_still_running () { # PID |
549 | (ps -e | grep stap-serverd | grep -q $1) && return 0 # Still running | |
550 | ||
c807ba1b | 551 | rm -f "$STAT_PATH/$1.stat" |
60045090 DB |
552 | return 1 # Not running |
553 | } | |
554 | ||
555 | get_server_pid_by_config () { | |
556 | # Need to save the config, since the process of checking the running | |
557 | # servers alters it. | |
558 | local target_ARCH="$ARCH" | |
559 | local target_RELEASE="$RELEASE" | |
60045090 | 560 | local target_RUNTIME="$RUNTIME" |
c807ba1b DB |
561 | local target_INCLUDE=("${INCLUDE[@]}") |
562 | local target_BUILD=("${BUILD[@]}") | |
60045090 DB |
563 | local target_USER="$USER" |
564 | local target_NICKNAME="$NICKNAME" | |
565 | ||
566 | # Check the status file for each running server to see if it matches | |
567 | # the one currently configured. We're checking for a given configuration, | |
568 | # so don't compare the nickname. | |
c807ba1b DB |
569 | for f in "$STAT_PATH"/*.stat; do |
570 | test ! -e "$f" && continue | |
571 | interpret_server_status "$f" || continue | |
60045090 DB |
572 | test "X$ARCH" = "X$target_ARCH" || continue |
573 | test "X$RELEASE" = "X$target_RELEASE" || continue | |
574 | test "X$INCLUDE" = "X$target_INCLUDE" || continue | |
575 | test "X$RUNTIME" = "X$target_RUNTIME" || continue | |
576 | test "X$BUILD" = "X$target_BUILD" || continue | |
577 | test "X$USER" = "X$target_USER" || continue | |
c807ba1b | 578 | echo `basename "$f" | sed 's/.stat//'` # Server has a pid |
60045090 DB |
579 | return |
580 | done | |
581 | ||
582 | ARCH="$target_ARCH" | |
583 | RELEASE="$target_RELEASE" | |
60045090 | 584 | RUNTIME="$target_RUNTIME" |
c807ba1b DB |
585 | INCLUDE=("${target_INCLUDE[@]}") |
586 | BUILD=("${target_BUILD[@]}") | |
60045090 DB |
587 | USER="$target_USER" |
588 | NICKNAME="$target_NICKNAME" | |
589 | } | |
590 | ||
591 | get_server_pid_by_nickname () { | |
592 | # No need to save the current configuration. This function is not called | |
593 | # in a context requiring it. | |
594 | local target_NICKNAME="$1" | |
595 | ||
596 | # Check the status file for each running server to see if the nickname | |
597 | # matches the one we want. | |
c807ba1b DB |
598 | for f in "$STAT_PATH"/*.stat; do |
599 | test ! -e "$f" && continue | |
600 | interpret_server_status "$f" || continue | |
60045090 | 601 | test "X$NICKNAME" = "X$target_NICKNAME" || continue |
c807ba1b | 602 | echo `basename "$f" | sed 's/\.stat//'` # Server with nickname was found |
60045090 DB |
603 | return |
604 | done | |
605 | } | |
606 | ||
607 | managed_servers () { | |
c807ba1b | 608 | if [ ! -d "$STAT_PATH" ]; then |
60045090 DB |
609 | echo "" |
610 | return 1 | |
611 | fi | |
c807ba1b DB |
612 | cd "$STAT_PATH" |
613 | local list=`ls | sed 's/\.stat//'` | |
60045090 DB |
614 | if [ -z "$list" ]; then |
615 | echo "" | |
616 | return 1 | |
617 | fi | |
618 | ||
619 | echo "$list" | |
620 | } | |
621 | ||
622 | eval_server_command () { | |
623 | local cmd="$1" | |
c807ba1b | 624 | eval $cmd |
60045090 | 625 | } |
0e47827d | 626 | |
60045090 | 627 | start_server () { |
d0d71073 | 628 | clog $"Starting $prog `echo_server_options`" |
b9c1510e | 629 | |
60045090 DB |
630 | # Is there already a server running for the requested kernel release |
631 | # and arch? | |
632 | local server_pid=`get_server_pid_by_config` | |
633 | if test -n "$server_pid"; then | |
634 | if server_still_running $server_pid; then | |
635 | do_success $"$prog start `echo_server_options`" | |
636 | return 0 # Success | |
b9c1510e | 637 | fi |
ab19dac7 DB |
638 | fi |
639 | ||
60045090 | 640 | # Construct the server start command. |
71a522b5 | 641 | local server_cmd="$STAP_START_SERVER -r \"`quote_for_cmd "$RELEASE"`\" -a \"`quote_for_cmd "$ARCH"`\" $OPT_OTHER" |
c807ba1b DB |
642 | for b in "${BUILD[@]}"; do |
643 | server_cmd="$server_cmd -B \"`quote_for_cmd "$b"`\"" | |
60045090 | 644 | done |
c807ba1b DB |
645 | for i in "${INCLUDE[@]}"; do |
646 | server_cmd="$server_cmd -I \"`quote_for_cmd "$i"`\"" | |
60045090 | 647 | done |
c807ba1b DB |
648 | test -n "$RUNTIME" && server_cmd="$server_cmd -R \"`quote_for_cmd "$RUNTIME"`\"" |
649 | server_cmd="$server_cmd --log=\"`quote_for_cmd "$LOG_FILE"`\"" | |
60045090 DB |
650 | |
651 | # Start the server here. | |
652 | local pid | |
56b3f5cf | 653 | if [ "$USER" != "`id -un`" ]; then |
60045090 DB |
654 | pid=`runuser -s /bin/bash - $USER -c "$server_cmd"` |
655 | else | |
656 | pid=`eval $server_cmd` | |
657 | fi | |
658 | if [ $? != 0 -o -z "$pid" ]; then | |
659 | if [ -n "$pid" ]; then | |
c807ba1b | 660 | rm -f "$STAT_PATH/$pid.stat" |
60045090 DB |
661 | fi |
662 | do_failure $"$prog start `echo_server_options`" | |
663 | return 1 # Failure | |
ab19dac7 | 664 | fi |
b7afc05d | 665 | |
60045090 DB |
666 | # Nickname defaults to the pid. |
667 | test -z "$NICKNAME" && NICKNAME="$pid" | |
ab19dac7 | 668 | |
60045090 | 669 | # Write the configuration to the status file. |
c807ba1b DB |
670 | local server_status_file="$STAT_PATH/$pid.stat" |
671 | echo "ARCH=$ARCH" > "$server_status_file" | |
672 | echo "USER=$USER" >> "$server_status_file" | |
673 | for b in "${BUILD[@]}"; do | |
674 | echo "BUILD+=$b" >> "$server_status_file" | |
675 | done | |
676 | for i in "${INCLUDE[@]}"; do | |
677 | echo "INCLUDE+=$i" >> "$server_status_file" | |
678 | done | |
679 | echo "NICKNAME=$NICKNAME" >> "$server_status_file" | |
680 | echo "RUNTIME=$RUNTIME" >> "$server_status_file" | |
681 | echo "RELEASE=$RELEASE" >> "$server_status_file" | |
b5935516 | 682 | |
60045090 | 683 | do_success $"$prog start `echo_server_options`" |
ab19dac7 DB |
684 | } |
685 | ||
60045090 DB |
686 | start () { # server-cmds |
687 | prepare_stat_dir | |
688 | if [ $? -ne 0 ]; then | |
689 | do_failure $"Failed to make stat directory ($STAT_PATH)" | |
690 | return 1 | |
691 | fi | |
692 | ||
693 | # Start the specified servers | |
c807ba1b DB |
694 | local server_cmds=("$@") |
695 | ||
60045090 DB |
696 | # If none specified, start the configured servers |
697 | if [ -z "$server_cmds" ]; then | |
c807ba1b | 698 | unset SERVER_CMDS |
60045090 | 699 | load_server_config |
c807ba1b | 700 | server_cmds=("${SERVER_CMDS[@]}") |
60045090 | 701 | # If none configured, start the default servers |
c807ba1b | 702 | test -z "$server_cmds" && server_cmds=("EXEC") |
60045090 DB |
703 | fi |
704 | ||
705 | # Start each requested server in turn | |
706 | local rc=0 | |
707 | local first=1 | |
708 | init_server_opts | |
709 | local cmd | |
710 | local prevCmd | |
c807ba1b DB |
711 | for cmd in "${server_cmds[@]}"; do |
712 | prevCmd="$cmd" | |
60045090 DB |
713 | # Evaluate commands until the EXEC command is found. |
714 | if test "$cmd" != "EXEC"; then | |
c807ba1b | 715 | eval_server_command "$cmd" |
60045090 DB |
716 | # A specified nickname only sticks if it is the final command. |
717 | # Otherwise, we have a configuration based on a nicknamed | |
718 | # configuration. | |
719 | echo "$cmd" | grep -q "^NICKNAME=" || NICKNAME="" | |
720 | continue | |
721 | fi | |
722 | # If a nickname was specified, but the corresponding config was not found, | |
723 | # then it is the nickname for this new configuration. | |
724 | if test -n "$NICKNAME_NOT_FOUND"; then | |
725 | NICKNAME="$NICKNAME_NOT_FOUND" | |
726 | NICKNAME_NOT_FOUND= | |
727 | fi | |
728 | ||
729 | # Start the configured server | |
730 | test $first = 0 && echo | |
731 | first=0 | |
732 | start_server || rc=1 | |
733 | ||
734 | # Don't use the same nickname for the next server. | |
735 | NICKNAME= | |
736 | done | |
737 | ||
738 | return $rc | |
ab19dac7 DB |
739 | } |
740 | ||
60045090 DB |
741 | stop () { # server-cmds |
742 | local first=1 | |
743 | local server_list= | |
c807ba1b | 744 | local server_cmds=("$@") |
60045090 DB |
745 | if [ -n "$server_cmds" ]; then |
746 | # Get the pids of all the requested servers. | |
747 | init_server_opts | |
748 | local cmd | |
749 | local prevCmd | |
c807ba1b DB |
750 | for cmd in "${server_cmds[@]}"; do |
751 | prevCmd="$cmd" | |
60045090 DB |
752 | # Evaluate commands until the EXEC command is found. |
753 | if test "$cmd" != "EXEC"; then | |
c807ba1b | 754 | eval_server_command "$cmd" |
60045090 DB |
755 | # A specified nickname only sticks if it is the final command. |
756 | # Otherwise, we have a configuration based on a nicknamed | |
757 | # configuration. | |
758 | echo "$cmd" | grep -q "^NICKNAME=" || NICKNAME="" | |
759 | continue | |
760 | fi | |
761 | # If a nickname was specified, but the corresponding config was not | |
762 | # found, it is an error. | |
763 | if test -n "$NICKNAME_NOT_FOUND"; then | |
d0d71073 | 764 | clog "No configuration found for the nickname '$NICKNAME_NOT_FOUND'" |
60045090 DB |
765 | NICKNAME="$NICKNAME_NOT_FOUND" |
766 | do_failure $"$prog stop `echo_server_options`" | |
767 | NICKNAME_NOT_FOUND= | |
768 | rc=1 | |
769 | continue | |
770 | fi | |
771 | ||
772 | # Get the pid for this server, if it's running | |
773 | local server_pid=`get_server_pid_by_config` | |
774 | if test -n "$server_pid"; then | |
775 | server_list="$server_list $server_pid" | |
776 | continue | |
777 | fi | |
778 | ||
779 | # This server is not running, but give a success stop status anyway. | |
780 | test $first = 0 && echo | |
781 | first=0 | |
d0d71073 | 782 | clog $"Stopping $prog `echo_server_options`" |
60045090 DB |
783 | do_success $"$prog stop `echo_server_options`" |
784 | done | |
785 | else | |
786 | server_list=`managed_servers` | |
787 | if [ -z "$server_list" ]; then | |
788 | clog $"Stopping $prog: " -n | |
789 | do_success $"$prog: No managed servers to stop" | |
790 | return 0 | |
791 | fi | |
792 | fi | |
793 | ||
794 | # Stop each server in turn | |
795 | local rc=0 | |
796 | local pid | |
797 | for pid in $server_list; do | |
c807ba1b DB |
798 | if ! interpret_server_status "$STAT_PATH/$pid.stat"; then |
799 | rc=1 | |
800 | continue | |
801 | fi | |
60045090 DB |
802 | |
803 | test $first = 0 && echo | |
804 | first=0 | |
d0d71073 | 805 | clog $"Stopping $prog `echo_server_options`" |
60045090 DB |
806 | |
807 | local this_rc=0 | |
808 | if server_still_running $pid; then | |
56b3f5cf | 809 | if [ "$USER" != "`id -un`" ]; then |
60045090 DB |
810 | runuser -s /bin/bash - $USER -c "$STAP_STOP_SERVER $pid" |
811 | else | |
812 | eval $STAP_STOP_SERVER $pid | |
813 | fi | |
814 | if [ $? != 0 ]; then | |
815 | do_failure $"$prog stop `echo_server_options`" | |
816 | this_rc=1 | |
817 | rc=1 | |
818 | fi | |
819 | fi | |
820 | if [ $this_rc = 0 ]; then | |
c807ba1b | 821 | rm -f "$STAT_PATH/$pid.stat" |
60045090 DB |
822 | do_success $"$prog stop `echo_server_options`" |
823 | fi | |
824 | done | |
825 | ||
826 | return $rc | |
ab19dac7 DB |
827 | } |
828 | ||
60045090 DB |
829 | status () { # server-list |
830 | local rc=0 | |
831 | ||
832 | # Report status for the specified servers or all running servers, if none | |
833 | # specified. | |
834 | local server_list= | |
c807ba1b | 835 | local server_cmds=("$@") |
60045090 DB |
836 | if [ -n "$server_cmds" ]; then |
837 | # Get the pids of all the requested servers. | |
838 | init_server_opts | |
839 | local cmd | |
840 | local prevCmd | |
c807ba1b DB |
841 | for cmd in "${server_cmds[@]}"; do |
842 | prevCmd="$cmd" | |
60045090 DB |
843 | # Evaluate commands until the EXEC command is found. |
844 | if test "$cmd" != "EXEC"; then | |
c807ba1b | 845 | eval_server_command "$cmd" |
60045090 DB |
846 | # A specified nickname only sticks if it is the final command. |
847 | # Otherwise, we have a configuration based on a nicknamed | |
848 | # configuration. | |
849 | echo "$cmd" | grep -q "^NICKNAME=" || NICKNAME="" | |
850 | continue | |
851 | fi | |
852 | # If a nickname was specified, but the corresponding config was not | |
853 | # found, say so. | |
854 | if test -n "$NICKNAME_NOT_FOUND"; then | |
855 | echo "No configuration found for the nickname '$NICKNAME_NOT_FOUND'" | |
856 | NICKNAME_NOT_FOUND= | |
857 | rc=3 | |
858 | continue | |
859 | fi | |
860 | ||
861 | # Get the pid for this server, if it's running | |
862 | local server_pid=`get_server_pid_by_config` | |
863 | if test -n "$server_pid"; then | |
864 | server_list="$server_list $server_pid" | |
865 | continue | |
866 | fi | |
867 | # This server is not running | |
c807ba1b | 868 | echo "stap-server `echo_server_options` is not running" |
60045090 DB |
869 | rc=3 |
870 | done | |
871 | else | |
872 | server_list=`managed_servers` | |
873 | if [ -z "$server_list" ]; then | |
874 | echo "No managed stap-server is running" | |
875 | return 3 | |
876 | fi | |
877 | fi | |
878 | ||
879 | # Get status of each server in turn | |
880 | local pid | |
881 | for pid in $server_list; do | |
c807ba1b DB |
882 | if ! interpret_server_status "$STAT_PATH/$pid.stat"; then |
883 | rc=1 | |
884 | continue | |
885 | fi | |
60045090 DB |
886 | if ! server_still_running $pid; then |
887 | echo "stap-server `echo_server_options` started as PID $pid is no longer running" | |
888 | rc=1 | |
889 | continue | |
890 | fi | |
891 | echo "stap-server `echo_server_options` running as PID $pid" | |
892 | done | |
893 | ||
894 | return $rc | |
ab19dac7 DB |
895 | } |
896 | ||
60045090 DB |
897 | # Restart or start if not running |
898 | function restart () { # server-cmds | |
899 | # Restart the specified servers or all servers, if none specified. | |
c807ba1b DB |
900 | local rc=0 |
901 | local server_cmds=("$@") | |
60045090 DB |
902 | if [ -z "$server_cmds" ]; then |
903 | local server_list=`managed_servers` | |
904 | local pid | |
905 | for pid in $server_list; do | |
c807ba1b DB |
906 | if ! interpret_server_status "$STAT_PATH/$pid.stat"; then |
907 | rc=1 | |
908 | continue | |
909 | fi | |
910 | unset SERVER_CMDS | |
911 | add_server_commands | |
912 | server_cmds+=("${SERVER_CMDS[@]}") | |
913 | server_cmds+=("EXEC") | |
60045090 DB |
914 | done |
915 | fi | |
916 | ||
917 | # Stop the specified servers, or all if none specified | |
c807ba1b | 918 | stop "${server_cmds[@]}" || rc=1 |
60045090 DB |
919 | echo |
920 | ||
921 | # Restart the same servers. If none were specified then | |
922 | # start the configured or default server(s)). | |
c807ba1b | 923 | start "${server_cmds[@]}" |
60045090 DB |
924 | local this_rc=$? |
925 | [ $this_rc != 0 ] && rc=$this_rc | |
926 | ||
927 | return $rc | |
0e47827d DB |
928 | } |
929 | ||
60045090 DB |
930 | # Restart only if running |
931 | function condrestart () { # server-list | |
932 | # Restart the specified servers or all servers, if none specified, | |
933 | # but only if they are already running. | |
c807ba1b DB |
934 | local rc=0 |
935 | local server_cmds=("$@") | |
60045090 DB |
936 | if [ -z "$server_cmds" ]; then |
937 | local server_list=`managed_servers` | |
938 | local pid | |
939 | for pid in $server_list; do | |
c807ba1b DB |
940 | if ! interpret_server_status "$STAT_PATH/$pid.stat"; then |
941 | rc=1 | |
942 | continue | |
943 | fi | |
944 | unset SERVER_CMDS | |
945 | add_server_commands | |
946 | server_cmds+=("${SERVER_CMDS[@]}") | |
947 | server_cmds+=("EXEC") | |
60045090 DB |
948 | done |
949 | # No server specified or running? | |
950 | if [ -z "$server_cmds" ]; then | |
951 | clog "No managed stap-server is running" -n | |
952 | do_success "No managed stap-server is running" | |
953 | return 0 | |
954 | fi | |
955 | fi | |
956 | ||
957 | # For each server in the list, stop it if it is running | |
60045090 | 958 | local first=1 |
c807ba1b | 959 | local this_server_cmds |
60045090 | 960 | local cmd |
c807ba1b | 961 | for cmd in "${server_cmds[@]}"; do |
60045090 | 962 | # Execute and collect commands until the EXEC command is found. |
c807ba1b | 963 | this_server_cmds+=("$cmd") |
60045090 | 964 | if test "$cmd" != "EXEC"; then |
c807ba1b | 965 | eval_server_command "$cmd" |
60045090 DB |
966 | continue |
967 | fi | |
968 | ||
969 | test $first = 0 && echo | |
970 | first=0 | |
971 | ||
972 | # Now see if this server is running | |
c807ba1b | 973 | if ! status "${this_server_cmds[@]}" >/dev/null 2>&1; then |
d0d71073 | 974 | clog $"$prog `echo_server_options` is not running" |
60045090 | 975 | do_success "$prog `echo_server_options` is not running" |
c807ba1b | 976 | unset this_server_cmds |
60045090 DB |
977 | continue |
978 | fi | |
979 | ||
c807ba1b | 980 | start_cmds+=("${this_server_cmds[@]}") |
60045090 | 981 | |
c807ba1b | 982 | stop "${this_server_cmds[@]}" |
60045090 DB |
983 | this_rc=$? |
984 | [ $this_rc != 0 ] && rc=$this_rc | |
985 | ||
c807ba1b | 986 | unset this_server_cmds |
60045090 DB |
987 | done |
988 | ||
989 | # Now restart the servers that were running | |
c807ba1b | 990 | if [ -n "$start_cmds" ]; then |
60045090 | 991 | echo |
c807ba1b | 992 | start "${start_cmds[@]}" |
60045090 DB |
993 | local this_rc=$? |
994 | [ $this_rc != 0 ] && rc=$this_rc | |
995 | fi | |
996 | ||
997 | return $rc | |
998 | } | |
ab19dac7 | 999 | |
60045090 DB |
1000 | #------------------------------------------------------------------ |
1001 | # Mainline script | |
1002 | #------------------------------------------------------------------ | |
1003 | CMD=$1 | |
1004 | shift 1 | |
1005 | ||
1006 | prepare_log_dir | |
1007 | if [ $? -ne 0 ]; then | |
1008 | echo $"Failed to make log directory (`dirname $LOG_FILE`)" >&2 | |
1009 | exit 1 | |
1010 | fi | |
1011 | ||
71a522b5 | 1012 | OPTS=`getopt -s bash -u -o 'a:B:c:iI:n:p:kPr:R:u:' -- "$@"` |
60045090 DB |
1013 | if [ $? -ne 0 ]; then |
1014 | echo "Error: Argument parse error: $@" >&2 | |
1015 | echo_usage | |
1016 | exit 2 | |
1017 | fi | |
1018 | ||
1019 | # Initialize server specs | |
c807ba1b | 1020 | parse_args "$@" || exit 2 |
60045090 DB |
1021 | load_config |
1022 | ||
1023 | RETVAL=0 | |
1024 | ||
1025 | case $CMD in | |
c807ba1b DB |
1026 | start) # Start specified servers. If none specified, start configured servers |
1027 | start "${SERVER_CMDS[@]}" | |
1028 | RETVAL=$? | |
1029 | ;; | |
1030 | stop) # Stop specified servers | |
1031 | stop "${SERVER_CMDS[@]}" | |
1032 | RETVAL=$? | |
1033 | ;; | |
1034 | restart) # Restart specified servers | |
1035 | restart "${SERVER_CMDS[@]}" | |
1036 | RETVAL=$? | |
1037 | ;; | |
1038 | condrestart|try-restart) # Restart specified servers if they are running | |
1039 | condrestart "${SERVER_CMDS[@]}" | |
1040 | RETVAL=$? | |
1041 | ;; | |
1042 | status) # Give status on specified servers | |
1043 | status "${SERVER_CMDS[@]}" | |
1044 | exit $? | |
1045 | ;; | |
1046 | reload) # Reloading config without stop/restart is not supported | |
1047 | RETVAL=3 | |
1048 | ;; | |
1049 | force-reload) # Reload config with stop/start | |
1050 | # stop all running servers | |
1051 | stop | |
1052 | echo | |
1053 | # Restart specified servers | |
1054 | # If none specified, restart configured servers | |
1055 | start "${SERVER_CMDS[@]}" | |
1056 | RETVAL=$? | |
1057 | ;; | |
60045090 | 1058 | usage|*) |
c807ba1b DB |
1059 | echo_usage |
1060 | RETVAL=0 | |
1061 | ;; | |
60045090 DB |
1062 | esac |
1063 | ||
1064 | echo | |
1065 | exit $RETVAL |