summaryrefslogtreecommitdiff
path: root/scripts/rabbitmq-server
blob: 82058dcb269b1116317e60c151bbec2e006316ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/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_)<var_name>
# 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