summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2014-07-10 14:51:35 +0100
committerSimon MacMullen <simon@rabbitmq.com>2014-07-10 14:51:35 +0100
commitff0492352a1ac43178eea6c171bd441cea1dbb7b (patch)
tree52caa517e38f945d8b7c6e12cda10122c6201863
parent5ed104cd9b45562258c2176bff570dd932b51b81 (diff)
parent9cbde47bcd42a4d33ef571bf459202bae41f0d2e (diff)
downloadrabbitmq-server-ff0492352a1ac43178eea6c171bd441cea1dbb7b.tar.gz
Merge bug26192
-rw-r--r--docs/rabbitmqctl.1.xml14
-rwxr-xr-xscripts/rabbitmqctl5
-rwxr-xr-xscripts/rabbitmqctl.bat5
-rw-r--r--src/rabbit_control_main.erl25
-rw-r--r--src/rabbit_table.erl7
5 files changed, 46 insertions, 10 deletions
diff --git a/docs/rabbitmqctl.1.xml b/docs/rabbitmqctl.1.xml
index 43d1e55a..328926df 100644
--- a/docs/rabbitmqctl.1.xml
+++ b/docs/rabbitmqctl.1.xml
@@ -406,11 +406,15 @@
online, except when using the <command>--offline</command> flag.
</para>
<para>
- When using the <command>--offline</command> flag the node you
- connect to will become the canonical source for cluster metadata
- (e.g. which queues exist), even if it was not before. Therefore
- you should use this command on the latest node to shut down if
- at all possible.
+ When using the <command>--offline</command> flag
+ rabbitmqctl will not attempt to connect to a node as
+ normal; instead it will temporarily become the node in
+ order to make the change. This is useful if the node
+ cannot be started normally. In this case the node will
+ become the canonical source for cluster metadata
+ (e.g. which queues exist), even if it was not
+ before. Therefore you should use this command on the
+ latest node to shut down if at all possible.
</para>
<para role="example-prefix">For example:</para>
<screen role="example">rabbitmqctl -n hare@mcnulty forget_cluster_node rabbit@stringer</screen>
diff --git a/scripts/rabbitmqctl b/scripts/rabbitmqctl
index 495b06b3..cbdf3f45 100755
--- a/scripts/rabbitmqctl
+++ b/scripts/rabbitmqctl
@@ -19,6 +19,10 @@
# Non-empty defaults should be set in rabbitmq-env
. `dirname $0`/rabbitmq-env
+# rabbitmqctl starts distribution itself, so we need to make sure epmd
+# is running.
+${ERL_DIR}erl -sname rabbitmqctl-prelaunch-$$ -eval 'erlang:halt().'
+
# We specify Mnesia dir and sasl error logger since some actions
# (e.g. forget_cluster_node --offline) require us to impersonate the
# real node.
@@ -27,7 +31,6 @@ exec ${ERL_DIR}erl \
-noinput \
-hidden \
${RABBITMQ_CTL_ERL_ARGS} \
- -sname rabbitmqctl$$ \
-boot "${CLEAN_BOOT_FILE}" \
-sasl errlog_type error \
-mnesia dir "\"${RABBITMQ_MNESIA_DIR}\"" \
diff --git a/scripts/rabbitmqctl.bat b/scripts/rabbitmqctl.bat
index 22eabf94..9266a480 100755
--- a/scripts/rabbitmqctl.bat
+++ b/scripts/rabbitmqctl.bat
@@ -55,6 +55,10 @@ if not exist "!ERLANG_HOME!\bin\erl.exe" (
exit /B
)
+rem rabbitmqctl starts distribution itself, so we need to make sure epmd
+rem is running.
+"!ERLANG_HOME!\bin\erl.exe" -sname rabbitmqctl-prelaunch-!RANDOM!!TIME:~9! -eval "erlang:halt()."
+
"!ERLANG_HOME!\bin\erl.exe" ^
-pa "!TDP0!..\ebin" ^
-noinput ^
@@ -62,7 +66,6 @@ if not exist "!ERLANG_HOME!\bin\erl.exe" (
!RABBITMQ_CTL_ERL_ARGS! ^
-sasl errlog_type error ^
-mnesia dir \""!RABBITMQ_MNESIA_DIR:\=/!"\" ^
--sname rabbitmqctl!RANDOM!!TIME:~9! ^
-s rabbit_control_main ^
-nodename !RABBITMQ_NODENAME! ^
-extra !STAR!
diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl
index 35f3c7dd..b8b6afad 100644
--- a/src/rabbit_control_main.erl
+++ b/src/rabbit_control_main.erl
@@ -132,6 +132,7 @@
%%----------------------------------------------------------------------------
start() ->
+ start_distribution(),
{ok, [[NodeStr|_]|_]} = init:get_argument(nodename),
{Command, Opts, Args} =
case parse_arguments(init:get_plain_arguments(), NodeStr) of
@@ -303,8 +304,12 @@ action(forget_cluster_node, Node, [ClusterNodeS], Opts, Inform) ->
ClusterNode = list_to_atom(ClusterNodeS),
RemoveWhenOffline = proplists:get_bool(?OFFLINE_OPT, Opts),
Inform("Removing node ~p from cluster", [ClusterNode]),
- rpc_call(Node, rabbit_mnesia, forget_cluster_node,
- [ClusterNode, RemoveWhenOffline]);
+ case RemoveWhenOffline of
+ true -> become(Node),
+ rabbit_mnesia:forget_cluster_node(ClusterNode, true);
+ false -> rpc_call(Node, rabbit_mnesia, forget_cluster_node,
+ [ClusterNode, false])
+ end;
action(force_boot, Node, [], _Opts, Inform) ->
Inform("Forcing boot for Mnesia dir ~s", [mnesia:system_info(directory)]),
@@ -658,6 +663,22 @@ exit_loop(Port) ->
{Port, _} -> exit_loop(Port)
end.
+start_distribution() ->
+ CtlNodeName = rabbit_misc:format("rabbitmqctl-~s", [os:getpid()]),
+ {ok, _} = net_kernel:start([list_to_atom(CtlNodeName), shortnames]).
+
+become(BecomeNode) ->
+ case net_adm:ping(BecomeNode) of
+ pong -> exit({node_running, BecomeNode});
+ pang -> io:format(" * Impersonating node: ~s...", [BecomeNode]),
+ error_logger:tty(false),
+ ok = net_kernel:stop(),
+ {ok, _} = net_kernel:start([BecomeNode, shortnames]),
+ io:format(" done~n", []),
+ Dir = mnesia:system_info(directory),
+ io:format(" * Mnesia directory : ~s~n", [Dir])
+ end.
+
%%----------------------------------------------------------------------------
default_if_empty(List, Default) when is_list(List) ->
diff --git a/src/rabbit_table.erl b/src/rabbit_table.erl
index 47c77cd0..fe2c3b58 100644
--- a/src/rabbit_table.erl
+++ b/src/rabbit_table.erl
@@ -70,7 +70,12 @@ wait_for_replicated() ->
not lists:member({local_content, true}, TabDef)]).
wait(TableNames) ->
- {ok, Timeout} = application:get_env(rabbit, mnesia_table_loading_timeout),
+ %% We might be in ctl here for offline ops, in which case we can't
+ %% get_env() for the rabbit app.
+ Timeout = case application:get_env(rabbit, mnesia_table_loading_timeout) of
+ {ok, T} -> T;
+ undefined -> 30000
+ end,
case mnesia:wait_for_tables(TableNames, Timeout) of
ok ->
ok;