#!/bin/sh # vim:sw=4:et: ## This Source Code Form is subject to the terms of the Mozilla Public ## License, v. 2.0. If a copy of the MPL was not distributed with this ## file, You can obtain one at https://mozilla.org/MPL/2.0/. ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. ## set -e # Get default settings with user overrides for (RABBITMQ_) # Non-empty defaults should be set in rabbitmq-env SCRIPTS_DIR=$(dirname "$0") . "$SCRIPTS_DIR/rabbitmq-env" [ "$NOTIFY_SOCKET" ] && RUNNING_UNDER_SYSTEMD=true RABBITMQ_DEFAULT_ALLOC_ARGS="+MBas ageffcbf +MHas ageffcbf +MBlmbcs 512 +MHlmbcs 512 +MMmcs 30" # Bump ETS table limit to 50000 if [ "x" = "x$ERL_MAX_ETS_TABLES" ]; then ERL_MAX_ETS_TABLES=50000 fi check_start_params() { check_not_empty RABBITMQ_BOOT_MODULE check_not_empty SASL_BOOT_FILE } check_not_empty() { local name="${1:?}" local value eval value=\$$name if [ -z "$value" ]; then echo "Error: ENV variable should be defined: $1. Please check rabbitmq-env, rabbitmq-defaults, and ${RABBITMQ_CONF_ENV_FILE} script files" exit 78 fi } start_rabbitmq_server() { set -e _rmq_env_set_erl_libs RABBITMQ_START_RABBIT= [ "x" = "x$RABBITMQ_ALLOW_INPUT" ] && RABBITMQ_START_RABBIT=" -noinput" if test -z "$RABBITMQ_NODE_ONLY"; then if test "$USE_RABBIT_BOOT_SCRIPT"; then # TODO: This is experimental and undocumented at this point. # It is here just to do simple checks while playing with how # RabbitMQ is started. "$SCRIPTS_DIR/rabbitmq-rel" gen-boot SASL_BOOT_FILE=rabbit test -f "$SASL_BOOT_FILE.boot" RABBITMQ_START_RABBIT="$RABBITMQ_START_RABBIT -init_debug" else RABBITMQ_START_RABBIT="$RABBITMQ_START_RABBIT -s $RABBITMQ_BOOT_MODULE boot" fi fi # We need to turn off path expansion because some of the vars, # notably RABBITMQ_SERVER_ERL_ARGS, contain terms that look like # globs and there is no other way of preventing their expansion. set -f export ERL_MAX_ETS_TABLES \ SYS_PREFIX check_start_params exec erl \ -pa "$RABBITMQ_SERVER_CODE_PATH" \ ${RABBITMQ_START_RABBIT} \ -boot "${SASL_BOOT_FILE}" \ +W w \ ${RABBITMQ_DEFAULT_ALLOC_ARGS} \ ${RABBITMQ_SERVER_ERL_ARGS} \ ${RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS} \ ${RABBITMQ_SERVER_START_ARGS} \ -lager crash_log false \ -lager handlers '[]' \ "$@" } stop_rabbitmq_server() { if test "$rabbitmq_server_pid"; then kill -TERM "$rabbitmq_server_pid" wait "$rabbitmq_server_pid" || true fi } if [ "$RABBITMQ_ALLOW_INPUT" -o "$RUNNING_UNDER_SYSTEMD" -o "$detached" ]; then # Run erlang VM directly, completely replacing current shell # process - so the pid file written in the code above will be # valid (unless detached, which is also handled in the code # above). # # And also this is the correct mode to run the broker under # systemd - there is no need in a proxy process that converts # signals to graceful shutdown command, the unit file should already # contain instructions for graceful shutdown. Also by removing # this additional process we could simply use value returned by # `os:getpid/0` for a systemd ready notification. start_rabbitmq_server "$@" else # When RabbitMQ runs in the foreground but the Erlang shell is # disabled, we setup signal handlers to stop RabbitMQ properly. This # is at least useful in the case of Docker. # The Erlang VM should ignore SIGINT. RABBITMQ_SERVER_START_ARGS="${RABBITMQ_SERVER_START_ARGS} ${RABBITMQ_IGNORE_SIGINT_FLAG}" # Signal handlers. They all stop RabbitMQ properly, using # rabbitmqctl stop. This script will exit with different exit codes: # SIGHUP, SIGTSTP + SIGCONT # Ignored until we implement a useful behavior. # SIGTERM # Exits 0 since this is considered a normal process termination. # SIGINT # Exits 128 + $signal_number where $signal_number is 2 for SIGINT (see # https://pubs.opengroup.org/onlinepubs/009695399/utilities/kill.html). # This is considered an abnormal process termination. Normally, we # don't need to specify this exit code because the shell propagates it. # Unfortunately, the signal handler doesn't work as expected in Dash, # thus we need to explicitly restate the exit code. # # The behaviors below should remain consistent with the # equivalent signal handlers in the Erlang code # (see apps/rabbitmq_prelaunch/src/rabbit_prelaunch_sighandler.erl). trap '' HUP TSTP CONT trap "stop_rabbitmq_server; exit 0" TERM trap "stop_rabbitmq_server; exit 130" INT start_rabbitmq_server "$@" & export rabbitmq_server_pid=$! # Block until RabbitMQ exits or a signal is caught. # Waits for last command (which is start_rabbitmq_server) # # The "|| true" is here to work around an issue with Dash. Normally # in a Bourne shell, if `wait` is interrupted by a signal, the # signal handlers defined above are executed and the script # terminates with the exit code of `wait` (unless the signal handler # overrides that). # In the case of Dash, it looks like `set -e` (set at the beginning # of this script) gets precedence over signal handling. Therefore, # when `wait` is interrupted, its exit code is non-zero and because # of `set -e`, the script terminates immediately without running the # signal handler. To work around this issue, we use "|| true" to # force that statement to succeed and the signal handler to properly # execute. Because the statement below has an exit code of 0, the # signal handler has to restate the expected exit code. wait "$rabbitmq_server_pid" || true fi