diff options
author | Rob Harrop <rob@rabbitmq.com> | 2011-08-22 11:58:39 +0100 |
---|---|---|
committer | Rob Harrop <rob@rabbitmq.com> | 2011-08-22 11:58:39 +0100 |
commit | 2b0a450fc734d0c80381b1affe8897a5036ea464 (patch) | |
tree | df7308e73273ee2e56d97bad1a0d7ccee6c591f9 | |
parent | 04a22b6eba57696c4e5abd5048ee698682ae926e (diff) | |
parent | 1e91230c84a3048111ea64e5d393ef8544480361 (diff) | |
download | rabbitmq-server-2b0a450fc734d0c80381b1affe8897a5036ea464.tar.gz |
Merge with default
-rw-r--r-- | packaging/RPMS/Fedora/rabbitmq-server.spec | 2 | ||||
-rw-r--r-- | packaging/common/rabbitmq-server.init | 9 | ||||
-rwxr-xr-x | packaging/common/rabbitmq-server.ocf | 21 | ||||
-rw-r--r-- | packaging/debs/Debian/debian/dirs | 1 | ||||
-rw-r--r-- | packaging/debs/Debian/debian/postinst | 1 | ||||
-rwxr-xr-x | scripts/rabbitmq-server | 4 | ||||
-rw-r--r-- | src/rabbit_control.erl | 79 |
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; |