1#!/bin/sh 2 3### BEGIN INIT INFO 4# Provides: stud 5# Required-Start: $local_fs $remote_fs 6# Required-Stop: $local_fs $remote_fs 7# Should-Start: $syslog 8# Should-Stop: $syslog 9# Default-Start: 2 3 4 5 10# Default-Stop: 0 1 6 11# Short-Description: Start or stop stud (SSL offloader) 12### END INIT INFO 13 14####################################################### 15# GLOBALS # 16####################################################### 17 18# instance configuration directory 19CONFIG_DIR="/etc/stud" 20 21# Runtime directory data 22RUNTIME_DIR="/var/run/stud" 23 24####################################################### 25 26####################################################### 27 28stud_single_instance_config_reset() { 29####################################################### 30# stud instance configuration # 31####################################################### 32 33# stud listening address 34FRONTEND_ADDRESS="*,8443" 35 36# upstream service address 37BACKEND_ADDRESS="127.0.0.1,80" 38 39# x509 certificate file 40CERT_FILE="" 41 42# TLS only service? Don't set this to 1 if you're 43# offloading HTTPS. 44TLS_ONLY="0" 45 46# cipher suite (run openssl ciphers for full list) 47CIPHER_SUITE="HIGH" 48 49# OpenSSL engine 50ENGINE="" 51 52# Number of worker processes 53WORKERS="1" 54 55# Listen backlog 56BACKLOG="" 57 58# Chroot directory 59CHROOT_DIR="" 60 61# drop privileges and run as specified 62# user if set 63SETUID_USER="" 64 65# use shared cache with specified number of sessions 66# WARNING: stud must be compiled with USE_SHARED_CACHE=1 67SHARED_CACHE_SESSIONS="0" 68 69# Accept cache updates on specified address 70# 71# syntax: HOST,PORT 72# 73# WARNING: stud must be compiled with USE_SHARED_CACHE=1 74# SHARED_CACHE_SESSIONS must be >= 1 75CACHE_UPDATE_ACCEPT="" 76 77# Send cache updates to specified list space separated peers 78# 79# syntax: HOST1,PORT HOST2,PORT 80# 81# WARNING: stud must be compiled with USE_SHARED_CACHE=1 82# and CACHE_UPDATE_ACCEPT must be defined 83CACHE_UPDATE_SEND="" 84 85# Force network interface and ttl to receive and send multicast 86# cache updates 87# 88# syntax: IFACE[,TTL] 89# 90# WARNING: stud must be compiled with USE_SHARED_CACHE=1 91# and CACHE_UPDATE_ACCEPT must be defined 92CACHE_UPDATE_IFACE="" 93 94# default tcp keepalive on client socket in seconds 95CLIENT_TCP_KEEPALIVE_SEC="" 96 97# log to syslog? 98SYSLOG="1" 99 100# Write 1 octet with the IP family followed by the IP 101# address in 4 (IPv4) or 16 (IPv6) octets little-endian 102# to backend before the actual data 103WRITE_IP="0" 104 105# Enable writing HAProxy protocol line to the backend before 106# actual data, see 107# http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt 108# for additional info 109WRITE_PROXY="0" 110 111# Enable reading HAProxy protocol line before actual data. 112# This address will be sent to the backend if one of 113# WRITE_IP or WRITE_PROXY is specified. 114READ_PROXY="0" 115 116# Alternative OpenSSL library dir 117# Use this if you'd like to run stud with different 118# version of OpenSSL library 119OPENSSL_LIB_DIR="" 120 121# Semicolon separated list of process affinities; requires 122# taskset(8) utility. 123# 124# SYNTAX: 125# "<process_number>:<affinity>;<process_number2>:<affinity2>;..." 126# 127# <process_number>: stud worker process number, starting with 1 128# <affinity>: process affinity, see taskset(8) for details 129# 130# EXAMPLES: 131# 132# "1:0" => bind first process to CPU0 133# 134# "1:0;2:3-4;3:5;4:7" => bind first worker process to CPU0, 135# second worker process to CPU3 and CPU4, 136# third worker process to CPU5 and fourth 137# worker process to CPU7 138PROCESS_AFFINITY="" 139 140# Process priority (integer between -19 to 19) 141# lower value means higher priority 142# 143PROCESS_PRIORITY="" 144 145# ulimit -n value before starting single stud instance 146# 147# Comment out or set to 0 to disable ulimit -n 148# setup. 149# 150ULIMIT_N="" 151 152# Additional stud command line options 153# 154# NOTE: set this only if you really know what your're 155# doing 156# 157# ADDITIONAL_STUD_OPT="" 158 159# EOF 160} 161 162PATH="${PATH}:." 163INSTANCE_NAME="" 164STUD=`which stud 2>/dev/null` 165 166die() { 167 msg_log "FATAL: $@" 168 echo "FATAL: $@" 1>&2 169 exit 1 170} 171 172msg_log() { 173 ident="stud" 174 test ! -z "${INSTANCE_NAME}" && ident="${ident}/${INSTANCE_NAME}" 175 logger -i -t "${ident}" "$@" >/dev/null 2>&1 176} 177 178msg_err() { 179 msg_log "ERROR: $@" 180} 181 182 183_real_single_instance_start() { 184 # check stud binary 185 if [ -z "${STUD}" ] || [ ! -f "${STUD}" ] || [ ! -x "${STUD}" ]; then 186 die "Invalid stud binary: '${STUD}'" 187 fi 188 189 # generate stud command line options 190 opts="-f ${FRONTEND_ADDRESS}" 191 opts="${opts} -b ${BACKEND_ADDRESS}" 192 193 if [ "${TLS_ONLY}" = "1" ]; then 194 opts="${opts} --tls" 195 else 196 opts="${opts} --ssl" 197 fi 198 199 test ! -z "${CIPHER_SUITE}" && opts="${opts} -c ${CIPHER_SUITE}" 200 test ! -z "${ENGINE}" && opts="${opts} -e ${ENGINE}" 201 202 if [ ! -z "${WORKERS}" ] && [ ${WORKERS} -gt 0 ]; then 203 opts="${opts} -n ${WORKERS}" 204 fi 205 206 if [ ! -z "${BACKLOG}" ] && [ ${BACKLOG} -gt 0 ]; then 207 opts="${opts} -B ${BACKLOG}" 208 fi 209 210 if [ ! -z "${CLIENT_TCP_KEEPALIVE_SEC}" ] && [ ${CLIENT_TCP_KEEPALIVE_SEC} -gt 0 ]; then 211 opts="${opts} -k ${CLIENT_TCP_KEEPALIVE_SEC}" 212 fi 213 214 # shared cache sessions... 215 if [ ! -z "${SHARED_CACHE_SESSIONS}" ] && [ ${SHARED_CACHE_SESSIONS} -gt 0 ]; then 216 opts="${opts} -C ${SHARED_CACHE_SESSIONS}" 217 218 # shared cache stuff 219 if [ ! -z "${CACHE_UPDATE_ACCEPT}" ]; then 220 opts="${opts} -U ${CACHE_UPDATE_ACCEPT}" 221 222 c_u=0 223 for h in ${CACHE_UPDATE_SEND}; do 224 test ! -z "${h}" || continue 225 opts="${opts} -P ${h}" 226 c_u=$((c_u + 1)) 227 done 228 if [ ${c_u} -lt 1 ]; then 229 die "Cache updates are enabled but CACHE_UPDATE_SEND option seems to be empty." 230 fi 231 232 if [ ! -z "${CACHE_UPDATE_IFACE}" ]; then 233 opts="${opts} -M ${CACHE_UPDATE_IFACE}" 234 fi 235 fi 236 237 fi 238 239 # chroot? 240 test ! -z "${CHROOT_DIR}" && opts="${opts} -r ${CHROOT_DIR}" 241 test ! -z "${SETUID_USER}" && opts="${opts} -u ${SETUID_USER}" 242 243 opts="${opts} -q" 244 test "${SYSLOG}" = "1" && opts="${opts} -s" 245 246 test "${WRITE_IP}" = "1" && opts="${opts} --write-ip" 247 test "${WRITE_PROXY}" = "1" && opts="${opts} --write-proxy" 248 test "${READ_PROXY}" = "1" && opts="${opts} --read-proxy" 249 250 if [ ! -z "${CERT_FILE}" ] && [ -f "${CERT_FILE}" ] && [ -r "${CERT_FILE}" ]; then 251 opts="${opts} ${CERT_FILE}" 252 else 253 die "Invalid or unreadable certificate file '${CERT_FILE}'." 254 fi 255 256 # additional command line options?! 257 if [ ! -z "${ADDITIONAL_STUD_OPT}" ]; then 258 opts="${opts} ${ADDITIONAL_STUD_OPT}" 259 fi 260 261 # priority?! 262 prefix="" 263 if [ ! -z "${PROCESS_PRIORITY}" ]; then 264 prefix="nice -n ${PROCESS_PRIORITY}" 265 fi 266 267 # we want to start stud in a daemon mode... 268 opts="${opts} --daemon" 269 270 # set ulimits! 271 ulimit_set || die "Unable to set stud runtime limits." 272 273 # disable linker stuff 274 unset LD_LIBRARY_PATH 275 276 # set new lib path if requested 277 if [ ! -z "${OPENSSL_LIB_DIR}" -a -d "${OPENSSL_LIB_DIR}" ]; then 278 LD_LIBRARY_PATH="${OPENSSL_LIB_DIR}" 279 export LD_LIBRARY_PATH 280 fi 281 282 # start stud! 283 msg_log "Starting instance '${INSTANCE_NAME}': ${STUD} ${opts}" 284 out=`${prefix} ${STUD} ${opts} 2>&1` 285 286 # remove lib path 287 unset LD_LIBRARY_PATH 288 289 # check invocation 290 stud_pid=`echo "${out}" | tail -n 1 | cut -d " " -f5 | tr -d '.'` 291 if [ -z "${stud_pid}" ]; then 292 die "Empty stud pid. This is extremely weird." 293 fi 294 295 # wait a little bit, check if pid is still alive 296 sleep 0.2 >/dev/null 2>&1 297 if ! kill -0 "${stud_pid}" >/dev/null 2>&1; then 298 die "Stud started successfully as pid ${stud_pid} but died shortly after startup."; 299 fi 300 301 # write pid file! 302 pid_file_write "${INSTANCE_NAME}" "${stud_pid}" || msg_warn "${Error}" 303 304 # set affinity! 305 stud_affinity_set "${stud_pid}" || die "${Error}" 306} 307 308stud_single_instance_start() { 309 name="${1}" 310 if [ -z "${name}" ]; then 311 Error="Unable to stop undefined stud instance." 312 return 1 313 fi 314 315 # check if it is running 316 if stud_single_instance_status "${name}"; then 317 Error="Instance ${name} is already running as pid ${Error}." 318 return 1 319 fi 320 321 # do the real stuff... 322 Error="" 323 out=`_real_single_instance_start 2>&1` 324 rv=$? 325 if [ "${rv}" != "0" ]; then 326 Error="${out}" 327 rv=1 328 fi 329 330 # this is it! :) 331 return $rv 332} 333 334stud_single_instance_stop() { 335 name="${1}" 336 if [ -z "${name}" ]; then 337 Error="Unable to stop undefined stud instance." 338 return 1 339 fi 340 341 # check if it is running 342 stud_single_instance_status "${name}" || return 1 343 344 # time to stop instance 345 pid="${Error}" 346 msg_log "Stopping stud instance '${name}', pid ${pid}." 347 348 ok=0 349 if ! kill "${pid}" >/dev/null 2>&1; then 350 Error="Unable to stop instance: unable to kill pid ${pid}." 351 return 1 352 fi 353 354 # wait for termination 355 i=0 356 while [ ${i} -lt 9 ]; do 357 i=$((i + 1)) 358 # are you dead yet? 359 if ! kill -0 "${pid}" >/dev/null 2>&1; then 360 ok=1 361 break 362 fi 363 sleep 0.1 >/dev/null 2>&1 364 done 365 366 # not ok?! try to with headshot... 367 if [ "${ok}" != "1" ]; then 368 msg_log "Gentle stop of instance ${name} failed, trying to stop it with SIGKILL." 369 if ! kill -9 "${pid}"; then 370 Error="Unable to stop instance ${name}: kill(1) failed." 371 return 1 372 fi 373 fi 374 375 return 0 376} 377 378stud_single_instance_restart() { 379 name="${1}" 380 if [ -z "${name}" ]; then 381 Error="Unable to stop undefined stud instance." 382 return 1 383 fi 384 385 # maybe we need to stop it first... 386 if stud_single_instance_status "${name}"; then 387 stud_single_instance_stop "${name}" || return 1 388 fi 389 390 # start it back... 391 Error="" 392 stud_single_instance_start "${name}" 393} 394 395stud_single_instance_status() { 396 Error="" 397 if [ -z "${1}" ]; then 398 Error="Invalid instance name." 399 return 1 400 fi 401 402 # get pid file... 403 pid=`pid_file_read "${1}"` 404 405 # check it... 406 if [ -z "${pid}" ] || ! kill -0 "${pid}" >/dev/null 2>&1; then 407 Error="Instance '${1}' is stopped." 408 return 1 409 fi 410 411 # set pid to Error 412 Error="${pid}" 413 return 0 414} 415 416# reads pid file of specific instance 417pid_file_read() { 418 test -z "${1}" && return 1 419 file="${RUNTIME_DIR}/${1}.pid" 420 test -f "${file}" -a -r "${file}" || return 1 421 head -n 1 "${file}" 422} 423 424# writes pid file for specific instance 425pid_file_write() { 426 test -z "${1}" && return 1 427 test -z "${2}" && return 1 428 429 # check runtime directory 430 if [ ! -e "${RUNTIME_DIR}" ] || [ ! -d "${RUNTIME_DIR}" ] || [ ! -w "${RUNTIME_DIR}" ]; then 431 # try to create directory 432 mkdir -p "${RUNTIME_DIR}" || die "Unable to create missing runtime directory '${RUNTIME_DIR}'" 433 fi 434 435 file="${RUNTIME_DIR}/${1}.pid" 436 echo "${2}" > "${file}" 437} 438 439# lists running instances 440running_instance_list() { 441 list="" 442 for file in ${RUNTIME_DIR}/*.pid; do 443 test -f "${file}" || continue 444 445 fileb=`basename "${file}"` 446 name=`echo "${fileb}" | cut -d. -f1` 447 if [ -z "${name}" ]; then 448 msg_log "Removing bogus pid file '${file}'." 449 rm -f "${file}" >/dev/null 2>&1 450 continue 451 fi 452 pid=`pid_file_read "${name}"` 453 if [ -z "${pid}" ]; then 454 msg_log "Removing bogus pid file '${file}': instance '${name}' doesn't contain pid." 455 rm -f "${file}" >/dev/null 2>&1 456 continue 457 fi 458 459 # is this pid alive? 460 if ! kill -0 "${pid}" >/dev/null 2>&1 ; then 461 msg_log "Removing bogus pid file '${file}': instance '${name}' [pid ${pid}] is stopped." 462 rm -f "${file}" >/dev/null 2>&1 463 continue 464 fi 465 466 list="${list} ${name}" 467 done 468 echo ${list} 469} 470 471stud_instances_start() { 472 list="$@" 473 if [ -z "${list}" ]; then 474 list=`stud_config_instances_list` 475 fi 476 if [ -z "${list}" ]; then 477 die "No stud instances configured in directory '${CONFIG_DIR}'." 478 fi 479 480 echo "Starting stud instances:" 481 num_ok=0 482 num_failed=0 483 for instance in ${list}; do 484 echo -n " ${instance}: " 485 # load configuration 486 if ! stud_single_instance_config_load "${instance}"; then 487 echo "failed: ${Error}" 488 return 1 489 # start instance 490 elif stud_single_instance_start "${instance}"; then 491 echo "done." 492 msg_log "Instance ${name} successfully started." 493 num_ok=$((num_ok + 1)) 494 else 495 echo "failed: ${Error}" 496 msg_err "Error starting instance ${name}: ${Error}" 497 num_failed=$((num_failed + 1)) 498 fi 499 done 500 501 if [ "${num_failed}" != "0" ]; then 502 return 1 503 else 504 return 0 505 fi 506} 507 508stud_instances_stop() { 509 list="$@" 510 if [ -z "${list}" ]; then 511 list=`running_instance_list` 512 fi 513 if [ -z "${list}" ]; then 514 die "No stud instances are running." 515 fi 516 517 echo "Stopping stud instances:" 518 num_ok=0 519 num_failed=0 520 for instance in ${list}; do 521 echo -n " ${instance}: " 522 if stud_single_instance_stop "${instance}"; then 523 echo "done." 524 num_ok=$((num_ok + 1)) 525 msg_log "Instance ${instance} successfully stopped." 526 else 527 echo "failed: ${Error}" 528 msg_err "Error stopping instance ${instance}: ${Error}" 529 num_failed=$((num_failed + 1)) 530 fi 531 done 532 533 if [ "${num_failed}" != "0" ]; then 534 return 1 535 else 536 return 0 537 fi 538} 539 540stud_instances_restart() { 541 list="$@" 542 if [ -z "${list}" ]; then 543 list=`(running_instance_list ; stud_config_instances_list) | tr ' ' '\n' | sort -u | xargs echo` 544 fi 545 546 echo "Restarting stud instances: " 547 num_ok=0 548 num_failed=0 549 for instance in ${list}; do 550 echo -n " ${instance}: "; 551 552 # load configuration 553 if ! stud_single_instance_config_load "${instance}"; then 554 echo "failed: ${Error}" 555 return 1 556 # restart instance 557 elif stud_single_instance_restart "${instance}"; then 558 echo "done." 559 num_ok=$((num_ok + 1)) 560 msg_log "Instance ${instance} successfully restarted." 561 else 562 echo "failed: ${Error}" 563 msg_err "Error restarting instance ${instance}: ${Error}" 564 num_failed=$((num_failed + 1)) 565 fi 566 done 567 568 if [ "${num_failed}" != "0" ]; then 569 return 1 570 else 571 return 0 572 fi 573} 574 575stud_instances_status() { 576 list_config=`stud_config_instances_list` 577 list_running=`running_instance_list` 578 579 list_all=`echo ${list_config} ${list_running} | tr ' ' '\n' | sort -u | xargs echo` 580 581 i=0; 582 583 echo "Stud instance status: " 584 585 if [ -z "${list_all}" ]; then 586 die "No instances are configured and/or running." 587 fi 588 589 for instance in ${list_all}; do 590 echo -n " ${instance}: " 591 if stud_single_instance_status "${instance}"; then 592 echo "running as pid $Error" 593 i=$((i + 1)) 594 else 595 echo "stopped" 596 fi 597 done 598 599 if [ ${i} -gt 0 ]; then 600 return 0 601 else 602 return 1 603 fi 604} 605 606stud_config_instances_list() { 607 list="" 608 for file in ${CONFIG_DIR}/*.conf; do 609 test -f "${file}" -a -r "${file}" || continue 610 fileb=`basename "${file}"` 611 name=`echo "${fileb}" | cut -d. -f1` 612 test ! -z "${name}" || continue 613 list="${list} ${name}" 614 done 615 616 echo ${list} 617} 618 619stud_single_instance_config_print() { 620 head -n 151 "$0" | tail -n 123 621} 622 623stud_single_instance_config_load() { 624 file="${CONFIG_DIR}/${1}.conf" 625 INSTANCE_NAME="" 626 627 # reset configuration 628 stud_single_instance_config_reset 629 Error='' 630 631 if [ -f "${file}" -a -r "${file}" ]; then 632 . "${file}" >/dev/null || Error="Unable to load instance configuration file '${file}'." 633 else 634 Error="Invalid or unreadable instance configuration file '${file}'." 635 return 1 636 fi 637 638 # set instance name... 639 INSTANCE_NAME="${1}" 640 641 return 0 642} 643 644stud_instance_worker_pids() { 645 test -z "${1}" && return 1 646 ps -ef | grep " ${1} " | grep -v ' 1 ' | grep -v ' grep ' | awk '{print $2}' | xargs echo 647} 648 649# prints worker pid for n-th worker 650# arguments: 651# $1: list of worker pids (string) 652# $2: worker number 653stud_instance_worker_pid_by_num() { 654 i=0 655 local IFS=" " 656 for e in ${1}; do 657 i=$((i + 1)) 658 if [ "${i}" = "${2}" ]; then 659 echo "$e" 660 return 0 661 fi 662 done 663 return 1 664} 665 666stud_affinity_set() { 667 # nothing to set? 668 test -z "$PROCESS_AFFINITY" && return 0 669 670 Error="" 671 672# "1:0;2:3-4;3:5;4:7" => bind first haproxy process to CPU0, 673# second haproxy process to CPU3 and CPU4, 674# third haproxy process to CPU5 and fourth 675# process to CPU7 676 677 678 worker_pids=`stud_instance_worker_pids "${1}"` 679 680 local IFS=";" 681 item="" 682 for item in $PROCESS_AFFINITY; do 683 num=`echo "${item}" | cut -f1 -d:` 684 affinity=`echo "${item}" | cut -f2 -d:` 685 686 # validate process number 687 test -z "$num" && continue 688 test ${num} -ge 1 2>&1 || continue 689 690 # validate affinity 691 test -z "${affinity}" && continue 692 # WORKS: OpenSUSE 693 # DOESNT WORK: Debian/Ubuntu!!! 694 #echo "${affinity}" | grep -qPi '[^a-f0-9\-\,x]' && continue 695 696 # is this raw affinity mask? 697 raw_affinity=0 698 echo "${affinity}" | grep -qE '^0x' && raw_affinity=1 699 700 # get pid for process id $num 701 pid=`stud_instance_worker_pid_by_num "${worker_pids}" "$num"` 702 test -z "$pid" && continue 703 704 #echo "item: $item; process num: $num; pid: $pid; affinity: $affinity; raw: $raw_affinity" 705 706 opt="-p" 707 test "${raw_affinity}" = "0" && opt="${opt} -c" 708 opt="${opt} ${affinity}" 709 opt="${opt} ${pid}" 710 # echo "WILL RUN: 'taskset $opt'" 711 msg_log "Setting stud worker number ${num} (pid ${pid}) affinity using command: taskset ${opt}" 712 eval taskset ${opt} >/dev/null 2>&1 || msg_log "Error setting process affinity." 713 done 714} 715 716ulimit_n_set() { 717 if [ -z "$ULIMIT_N" ] || [ "$ULIMIT_N" = "0" ]; then 718 return 0 719 fi 720 721 # try to set maximum possible limit... 722 i="$ULIMIT_N" 723 num=0 724 while [ $i -gt 0 ]; do 725 num=$((num + 1)) 726 if ulimit -n "$i" > /dev/null 2>&1; then 727 percentage=$((i*100 / ${ULIMIT_N})) 728 if [ $percentage -lt 75 ]; then 729 Error="Filedescriptor limit set to only $i (${percentage}% of desired value of $ULIMIT_N); check your system settings." 730 return 1 731 fi 732 msg_log "Filedescriptor limit successfully set to $i (${percentage}% of desired value of $ULIMIT_N) after ${num} iteration(s)." 733 return 0 734 break 735 else 736 i=$((i - 100)) 737 fi 738 done 739 740 Error="Filedescriptor limit of $ULIMIT_N could not be set." 741 msg_log "$Error" 742 return 1 743} 744 745ulimit_set() { 746 # set fd limit 747 ulimit_n_set || return 1 748 749 # set core file limit 750 ulimit -c unlimited >/dev/null 2>&1 751 752 return 0 753} 754 755printhelp() { 756 cat <<EOF 757Usage: ${MYNAME} {start|stop|restart|status|sample_instance_config} [name, name2, ...] 758 759This is stud SSL offloader multi-instance init script. 760 761OPTIONS: 762 -C --config-dir Instance configuration directory (Default: "${CONFIG_DIR}") 763 764 This directory is searched for files matching *.conf 765 glob pattern; each file represents single stud instance 766 configuration file. 767 768 -R --runtime-dir Runtime (pid file) directory (Default: "${RUNTIME_DIR}") 769 770 --sample-config Prints out default single instance configuration 771 772 -V --version Prints script version 773 -h --help This help message 774EOF 775} 776 777# parse command line... 778TEMP=`getopt -o C:R:Vh --long config-dir:,runtime-dir:,sample-config,version,help -n "$MYNAME" -- "$@"` 779test "$?" != "0" && die "Invalid command line arguments. Run $MYNAME --help for instructions." 780eval set -- "$TEMP" 781while true; do 782 case $1 in 783 -C|--config-dir) 784 CONFIG_DIR="${2}" 785 shift 2 786 ;; 787 -R|--runtime-dir) 788 RUNTIME_DIR="${2}" 789 shift 2 790 ;; 791 --sample-config) 792 stud_single_instance_config_print 793 exit 0 794 ;; 795 -V|--version) 796 echo "$MYNAME $VERSION" 797 exit 0 798 ;; 799 -h|--help) 800 printhelp 801 exit 0 802 ;; 803 --) 804 shift 805 break 806 ;; 807 *) 808 die "Invalid command line arguments. Run $MYNAME --help for instructions." 809 ;; 810 esac 811done 812 813# weed out real action and do something 814case $1 in 815 start) 816 shift 817 stud_instances_start "$@" 818 ;; 819 820 stop) 821 shift 822 stud_instances_stop "$@" 823 ;; 824 825 force-reload|restart) 826 shift 827 stud_instances_restart "$@" 828 ;; 829 830 status) 831 stud_instances_status 832 exit $? 833 ;; 834 835 sample_instance_config|instance_config) 836 stud_single_instance_config_print 837 exit 0 838 ;; 839 840 *) 841 printhelp 842 exit 1 843 ;; 844esac 845 846# EOF 847