summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Harrop <rob@rabbitmq.com>2011-08-22 11:58:39 +0100
committerRob Harrop <rob@rabbitmq.com>2011-08-22 11:58:39 +0100
commit2b0a450fc734d0c80381b1affe8897a5036ea464 (patch)
treedf7308e73273ee2e56d97bad1a0d7ccee6c591f9
parent04a22b6eba57696c4e5abd5048ee698682ae926e (diff)
parent1e91230c84a3048111ea64e5d393ef8544480361 (diff)
downloadrabbitmq-server-2b0a450fc734d0c80381b1affe8897a5036ea464.tar.gz
Merge with default
-rw-r--r--packaging/RPMS/Fedora/rabbitmq-server.spec2
-rw-r--r--packaging/common/rabbitmq-server.init9
-rwxr-xr-xpackaging/common/rabbitmq-server.ocf21
-rw-r--r--packaging/debs/Debian/debian/dirs1
-rw-r--r--packaging/debs/Debian/debian/postinst1
-rwxr-xr-xscripts/rabbitmq-server4
-rw-r--r--src/rabbit_control.erl79
7 files changed, 94 insertions, 23 deletions
diff --git a/packaging/RPMS/Fedora/rabbitmq-server.spec b/packaging/RPMS/Fedora/rabbitmq-server.spec
index 11f5f01c..bdd6c4a1 100644
--- a/packaging/RPMS/Fedora/rabbitmq-server.spec
+++ b/packaging/RPMS/Fedora/rabbitmq-server.spec
@@ -50,6 +50,7 @@ make install TARGET_DIR=%{_maindir} \
mkdir -p %{buildroot}%{_localstatedir}/lib/rabbitmq/mnesia
mkdir -p %{buildroot}%{_localstatedir}/log/rabbitmq
+mkdir -p %{buildroot}%{_localstatedir}/run/rabbitmq
#Copy all necessary lib files etc.
install -p -D -m 0755 %{S:1} %{buildroot}%{_initrddir}/rabbitmq-server
@@ -111,6 +112,7 @@ done
%defattr(-,root,root,-)
%attr(0750, rabbitmq, rabbitmq) %dir %{_localstatedir}/lib/rabbitmq
%attr(0750, rabbitmq, rabbitmq) %dir %{_localstatedir}/log/rabbitmq
+%attr(0750, rabbitmq, rabbitmq) %dir %{_localstatedir}/run/rabbitmq
%dir %{_sysconfdir}/rabbitmq
%{_initrddir}/rabbitmq-server
%config(noreplace) %{_sysconfdir}/logrotate.d/rabbitmq-server
diff --git a/packaging/common/rabbitmq-server.init b/packaging/common/rabbitmq-server.init
index d8a7a94d..e2815f04 100644
--- a/packaging/common/rabbitmq-server.init
+++ b/packaging/common/rabbitmq-server.init
@@ -24,6 +24,7 @@ DESC=rabbitmq-server
USER=rabbitmq
ROTATE_SUFFIX=
INIT_LOG_DIR=/var/log/rabbitmq
+PID_FILE=/var/run/rabbitmq/pid
LOCK_FILE= # This is filled in when building packages
@@ -40,9 +41,9 @@ start_rabbitmq () {
else
RETVAL=0
set +e
- setsid sh -c "$DAEMON > ${INIT_LOG_DIR}/startup_log \
- 2> ${INIT_LOG_DIR}/startup_err" &
- $CONTROL wait >/dev/null 2>&1
+ setsid sh -c "RABBITMQ_PID_FILE=$PID_FILE $DAEMON > \
+ ${INIT_LOG_DIR}/startup_log 2> ${INIT_LOG_DIR}/startup_err" &
+ $CONTROL wait $PID_FILE >/dev/null 2>&1
RETVAL=$?
set -e
case "$RETVAL" in
@@ -53,6 +54,7 @@ start_rabbitmq () {
fi
;;
*)
+ rm -f $PID_FILE
echo FAILED - check ${INIT_LOG_DIR}/startup_\{log, _err\}
RETVAL=1
;;
@@ -68,6 +70,7 @@ stop_rabbitmq () {
RETVAL=$?
set -e
if [ $RETVAL = 0 ] ; then
+ rm -f $PID_FILE
if [ -n "$LOCK_FILE" ] ; then
rm -f $LOCK_FILE
fi
diff --git a/packaging/common/rabbitmq-server.ocf b/packaging/common/rabbitmq-server.ocf
index d58c48ed..51e16517 100755
--- a/packaging/common/rabbitmq-server.ocf
+++ b/packaging/common/rabbitmq-server.ocf
@@ -29,6 +29,7 @@
## OCF_RESKEY_log_base
## OCF_RESKEY_mnesia_base
## OCF_RESKEY_server_start_args
+## OCF_RESKEY_pid_file
#######################################################################
# Initialization:
@@ -42,10 +43,12 @@ OCF_RESKEY_server_default="/usr/sbin/rabbitmq-server"
OCF_RESKEY_ctl_default="/usr/sbin/rabbitmqctl"
OCF_RESKEY_nodename_default="rabbit@localhost"
OCF_RESKEY_log_base_default="/var/log/rabbitmq"
+OCF_RESKEY_pid_file_default="/var/lib/rabbitmq/pid"
: ${OCF_RESKEY_server=${OCF_RESKEY_server_default}}
: ${OCF_RESKEY_ctl=${OCF_RESKEY_ctl_default}}
: ${OCF_RESKEY_nodename=${OCF_RESKEY_nodename_default}}
: ${OCF_RESKEY_log_base=${OCF_RESKEY_log_base_default}}
+: ${OCF_RESKEY_pid_file=${OCF_RESKEY_pid_file_default}}
meta_data() {
cat <<END
@@ -133,6 +136,14 @@ Additional arguments provided to the server on startup
<content type="string" default="" />
</parameter>
+<parameter name="pid_file" unique="0" required="0">
+<longdesc lang="en">
+Location of the file in which the pid will be stored
+</longdesc>
+<shortdesc lang="en">Pid file path</shortdesc>
+<content type="string" default="${OCF_RESKEY_pid_file_default}" />
+</parameter>
+
</parameters>
<actions>
@@ -164,6 +175,7 @@ RABBITMQ_CONFIG_FILE=$OCF_RESKEY_config_file
RABBITMQ_LOG_BASE=$OCF_RESKEY_log_base
RABBITMQ_MNESIA_BASE=$OCF_RESKEY_mnesia_base
RABBITMQ_SERVER_START_ARGS=$OCF_RESKEY_server_start_args
+RABBITMQ_PID_FILE=$OCF_RESKEY_pid_file
[ ! -z $RABBITMQ_NODENAME ] && NODENAME_ARG="-n $RABBITMQ_NODENAME"
[ ! -z $RABBITMQ_NODENAME ] && export RABBITMQ_NODENAME
@@ -174,6 +186,7 @@ export_vars() {
[ ! -z $RABBITMQ_LOG_BASE ] && export RABBITMQ_LOG_BASE
[ ! -z $RABBITMQ_MNESIA_BASE ] && export RABBITMQ_MNESIA_BASE
[ ! -z $RABBITMQ_SERVER_START_ARGS ] && export RABBITMQ_SERVER_START_ARGS
+ [ ! -z $RABBITMQ_PID_FILE ] && export RABBITMQ_PID_FILE
}
rabbit_validate_partial() {
@@ -214,13 +227,13 @@ rabbit_status() {
}
rabbit_wait() {
- rabbitmqctl_action "wait"
+ rabbitmqctl_action "wait" $1
}
rabbitmqctl_action() {
local rc
local action
- action=$1
+ action=$@
$RABBITMQ_CTL $NODENAME_ARG $action > /dev/null 2> /dev/null
rc=$?
case "$rc" in
@@ -252,9 +265,10 @@ rabbit_start() {
# Wait for the server to come up.
# Let the CRM/LRM time us out if required
- rabbit_wait
+ rabbit_wait $RABBITMQ_PID_FILE
rc=$?
if [ "$rc" != $OCF_SUCCESS ]; then
+ rm -f $RABBITMQ_PID_FILE
ocf_log info "rabbitmq-server start failed: $rc"
exit $OCF_ERR_GENERIC
fi
@@ -285,6 +299,7 @@ rabbit_stop() {
rabbit_status
rc=$?
if [ "$rc" = $OCF_NOT_RUNNING ]; then
+ rm -f $RABBITMQ_PID_FILE
stop_wait=0
break
elif [ "$rc" != $OCF_SUCCESS ]; then
diff --git a/packaging/debs/Debian/debian/dirs b/packaging/debs/Debian/debian/dirs
index 625b7d41..5cf167d5 100644
--- a/packaging/debs/Debian/debian/dirs
+++ b/packaging/debs/Debian/debian/dirs
@@ -4,6 +4,7 @@ usr/sbin
usr/share/man
var/lib/rabbitmq/mnesia
var/log/rabbitmq
+var/run/rabbitmq
etc/logrotate.d
etc/rabbitmq
diff --git a/packaging/debs/Debian/debian/postinst b/packaging/debs/Debian/debian/postinst
index b11340ef..ca531f14 100644
--- a/packaging/debs/Debian/debian/postinst
+++ b/packaging/debs/Debian/debian/postinst
@@ -32,6 +32,7 @@ fi
chown -R rabbitmq:rabbitmq /var/lib/rabbitmq
chown -R rabbitmq:rabbitmq /var/log/rabbitmq
+chown -R rabbitmq:rabbitmq /var/run/rabbitmq
case "$1" in
configure)
diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server
index 2f80eb96..35b41d59 100755
--- a/scripts/rabbitmq-server
+++ b/scripts/rabbitmq-server
@@ -47,6 +47,7 @@ fi
[ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${MNESIA_DIR}
[ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME}
+[ "x" = "x$RABBITMQ_PID_FILE" ] && RABBITMQ_PID_FILE=${RABBITMQ_MNESIA_DIR}/pid
[ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${PLUGINS_EXPAND_DIR}
[ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME}-plugins-expand
@@ -67,6 +68,9 @@ fi
RABBITMQ_START_RABBIT=
[ "x" = "x$RABBITMQ_ALLOW_INPUT" ] && RABBITMQ_START_RABBIT='-noinput'
+mkdir -p $(dirname ${RABBITMQ_PID_FILE})
+echo $$ > ${RABBITMQ_PID_FILE}
+
RABBITMQ_EBIN_ROOT="${RABBITMQ_HOME}/ebin"
if [ "x" = "x$RABBITMQ_NODE_ONLY" ]; then
if erl \
diff --git a/src/rabbit_control.erl b/src/rabbit_control.erl
index e8afed0c..b9e550c9 100644
--- a/src/rabbit_control.erl
+++ b/src/rabbit_control.erl
@@ -20,7 +20,6 @@
-export([start/0, stop/0, action/5, diagnostics/1, log_action/3]).
-define(RPC_TIMEOUT, infinity).
--define(WAIT_FOR_VM_ATTEMPTS, 5).
-define(QUIET_OPT, "-q").
-define(NODE_OPT, "-n").
@@ -193,9 +192,9 @@ action(force_cluster, Node, ClusterNodeSs, _Opts, Inform) ->
[Node, ClusterNodes]),
rpc_call(Node, rabbit_mnesia, force_cluster, [ClusterNodes]);
-action(wait, Node, [], _Opts, Inform) ->
+action(wait, Node, [PidFile], _Opts, Inform) ->
Inform("Waiting for ~p", [Node]),
- wait_for_application(Node, ?WAIT_FOR_VM_ATTEMPTS);
+ wait_for_application(Node, PidFile, Inform);
action(status, Node, [], _Opts, Inform) ->
Inform("Status of node ~p", [Node]),
@@ -356,23 +355,69 @@ action(report, Node, _Args, _Opts, Inform) ->
%%----------------------------------------------------------------------------
-wait_for_application(Node, Attempts) ->
+wait_for_application(Node, PidFile, Inform) ->
+ Pid = wait_and_read_pid_file(PidFile),
+ Inform("pid is ~s", [Pid]),
+ wait_for_application(Node, Pid).
+
+wait_for_application(Node, Pid) ->
+ case process_up(Pid) of
+ true -> case node_up(Node) of
+ true -> ok;
+ false -> timer:sleep(1000),
+ wait_for_application(Node, Pid)
+ end;
+ false -> {error, process_not_running}
+ end.
+
+wait_and_read_pid_file(PidFile) ->
+ case file:read_file(PidFile) of
+ {ok, Bin} -> string:strip(binary_to_list(Bin), right, $\n);
+ {error, enoent} -> timer:sleep(500),
+ wait_and_read_pid_file(PidFile);
+ {error, _} = E -> exit({error, {could_not_read_pid, E}})
+ end.
+
+node_up(Node) ->
case rpc_call(Node, application, which_applications, [infinity]) of
- {badrpc, _} = E -> case Attempts of
- 0 -> E;
- _ -> wait_for_application0(Node, Attempts - 1)
- end;
- Apps -> case proplists:is_defined(rabbit, Apps) of
- %% We've seen the node up; if it goes down
- %% die immediately.
- true -> ok;
- false -> wait_for_application0(Node, 0)
- end
+ {badrpc, _} -> false;
+ Apps -> proplists:is_defined(rabbit, Apps)
end.
-wait_for_application0(Node, Attempts) ->
- timer:sleep(1000),
- wait_for_application(Node, Attempts).
+% Test using some OS clunkiness since we shouldn't trust
+% rpc:call(os, getpid, []) at this point
+process_up(Pid) ->
+ with_os([{unix, fun () ->
+ system("ps -p " ++ Pid
+ ++ " >/dev/null 2>&1") =:= 0
+ end},
+ {win32, fun () ->
+ Res = os:cmd("tasklist /nh /fi \"pid eq " ++
+ Pid ++ "\" 2>&1"),
+ case re:run(Res, "erl\\.exe", [{capture, none}]) of
+ match -> true;
+ _ -> false
+ end
+ end}]).
+
+with_os(Handlers) ->
+ {OsFamily, _} = os:type(),
+ case proplists:get_value(OsFamily, Handlers) of
+ undefined -> throw({unsupported_os, OsFamily});
+ Handler -> Handler()
+ end.
+
+% Like system(3)
+system(Cmd) ->
+ ShCmd = "sh -c '" ++ escape_quotes(Cmd) ++ "'",
+ Port = erlang:open_port({spawn, ShCmd}, [exit_status,nouse_stdio]),
+ receive {Port, {exit_status, Status}} -> Status end.
+
+% Escape the quotes in a shell command so that it can be used in "sh -c 'cmd'"
+escape_quotes(Cmd) ->
+ lists:flatten(lists:map(fun ($') -> "'\\''"; (Ch) -> Ch end, Cmd)).
+
+%%----------------------------------------------------------------------------
default_if_empty(List, Default) when is_list(List) ->
if List == [] -> Default;